COMMAND

    CPU [HW stuff]

SYSTEMS AFFECTED

    Cyrix 6x86, 6x86L, and 6x86MX up to Rev. 1.4

PROBLEM

    Following was found by Serguei  Shtyliov and was published in  c't
    13/97.   It's about  an endless  loop, done  with just  a few very
    basic  instructions  that  locks  every  6x86-CPU by IBM Cyrix and
    SGS, inclusive  the M2.   The bug  is called  'Hidden CLI' because
    it seems to show up when the Interrupt-Flag of the CPU is deleted.
    The  CPU  ignores  the   keyboard  interrupt  and  even   maskable
    Interrupts over the ISA-bus (NMI), also a reset via the  keyboard-
    controller - the CPU is in a dead-lock.

    The error will persists even under the following conditions:

	Usage of other registers
	Deactivation of Data bypassing and forwarding
	Deactivation of Write Allocation
	Dependend jumps instead  of JMP ADD,  AND, XOR or  MOV instead
	of STI

    The assembler code is:

	     MOV BX,70h
	     STI
    again:   XCHG AX,[BX]
	     MOV DX,AX
	     JMP again

    C people should use:

    static unsigned char c[4] = {0x36, 0x78, 0x38, 0x36};

    main()
    {
    asm ("movl      $c, %ebx\n\t"
    "again: xchgl   (%ebx), %eax\n\t"
	    "movl   %eax, %edx\n\t"
	    "jmp    again\n\t");
    }

    The program above basically consists of the following loop:

        1. Exchange  the contents  of memory  location pointed  by ebx
           with contents of eax (32 bits): xchg opcode.
        2. Copy the new contents of eax to edx (32 bits): mov opcode.
        3. Unconditionally jump back to step 1: jmp opcode.

    This,  in  itself,  is  an  infinite  loop.  The  only way for the
    processor to get  out of this  loop is by  getting interrupted. So
    far so good, since any multitasking OS and even DOS will interrupt
    the processor.  However, as you  will see for yourself if you  try
    to  run  this  loop  or  a  variant  of it, the processor does not
    respond to any interrupt  once in the loop.   This is the  symptom
    that led the c't magazine crew to call it the hidden CLI bug.

SOLUTION

    This effect is not reproduceable on other 586-processors. Pentium,
    K6, K5 and others are also in the endless loop but still react  to
    the keyboard interrupt (pressing  ctrl-alt-del for example).   The
    error will not show up under the following conditions:

        L1-Cache is deactivated
        Adding NOP or other commands in the loop
        Resolving the dependency of MOV and XCHG
        OUT instead of STI
        ADD, TEST, AND or MOV instead of XCHG

    According to another post on linux-kernel, it is fixed by:

        set6x86 -p 0xc1 -s 0x10

    This means  setting the  NO_LOCK bit  in CCR1.   This will prevent
    the  deadlock  caused  by  the  above  code  sequence.  Page table
    accesses and interrupt acknowledge  cycles will still be  executed
    in locked cycles,  but the xchgl  instruction will *not*  generate
    locked cycles anymore.   Note that Cyrix  has reported having  had
    problems  with  the  DOS4GW  Extensions  when  NO-LOCK  is set (no
    details provided).   The DOS4GW  extensions are  used by  DOOM and
    QUAKE and other DOS packages to enable access to extended  memory.
    However, this incompatibility is irrelevant to the serious problem
    caused by  the Cyrix  Coma bug:  a security  breach in  multiuser,
    multitasking protected-mode  OS's.   According to  Andrew D. Balsa
    you should add the following lines to your rc.cyrix script, in the
    part where it has MAPEN enabled:

        set6x86 -p 0x31 -s 0xF8
        set6x86 -p 0x32 -s 0x7f
        set6x86 -p 0x33 -c 0xFF
        set6x86 -p 0x3c -s 0x87

    Be careful to  copy exactly as  shown, particularly the  -c on the
    third line.  Basically what this script does is setup the 6x86 for
    detection  of  the  xchg  opcode  (0x87).  When  detected  in  the
    instruction stream, the xchg opcode will be serialized,  bypassing
    the pipeline. The performance hit of this solution is almost zero.