Pentium processor invalid instruction erratum

Aleph One (aleph1@DFW.NET)
Fri, 14 Nov 1997 15:59:06 -0600

http://support.intel.com/support/processors/pentium/ppiie/descrip.htm

Pentium processor invalid instruction erratum

Erratum Technical Description

Problem: The CMPXCHG8B instruction compares an 8 byte value in EDX and
EAX with an 8 byte value in memory (the destination operand). The only
valid destination operands for this instruction are memory operands.
If the destination operand is a register the processor should generate
an invalid opcode exception, execution of the CMPXCHG8B instruction
should be halted and the processor should execute the invalid opcode
exception handler. This erratum occurs if the LOCK prefix is used with
the CMPXCHG8B instruction with an (invalid) register destination
operand. In this case, the processor may not start execution of the
invalid opcode exception handler because the bus is locked. This
results in a system hang.

Implication: If an (invalid) register destination operand is used with
the CMPXCHG8B instruction and the LOCK prefix, the system may hang. No
memory data is corrupted and the user can perform a system reset to
return to normal operation. Note that the specific invalid code
sequence necessary for this erratum to occur is not normally generated
in the course of programming nor is such a sequence generated by
commercially available software.

This erratum only applies to Pentium® processors, Pentium processors
with MMX™ technology, Pentium OverDrive® processors and Pentium
OverDrive processors with MMX technology. Pentium Pro processors,
Pentium II processors and i486™ and earlier processors are not
affected.

Workaround: The recommended workaround for protected mode operating
systems is to always create a page not present fault when an invalid
opcode exception occurs. This page not present fault will be serviced
before the invalid opcode exception and thus prevent the lock
condition from occurring. The implementation details will differ
depending on the operating system.

The workaround has two parts. First, the Interrupt Descriptor Table
(IDT) is aligned such that any invalid opcode exception will cause a
page not present fault. Second, the page fault handler is modified to
recognize and correctly dispatch the invalid opcode exception and
certain other exceptions that are now routed through the page fault
handler.

Part I, IDT Alignment:
1. Align the Interrupt Descriptor Table (IDT) such that it spans a
4KB page boundary by placing the first entry starting 56 bytes
from the end of the first 4KB page. This places the first seven
entries (0-6) on the first 4KB page, and the remaining entries on
the second page.

2. The page containing the first seven entries of the IDT must not
have a mapping in the OS page tables. This will cause any of
exceptions 0-6 to generate a page not present fault. A page not
present fault prevents the bus lock condition and gives the OS
complete control to process these exceptions as appropriate. Note
that exception 6 is the invalid opcode exception, so with this
scheme an OS has complete control of any program executing an
invalid CMPXCHG8B instruction.

Part II, Page Fault Handler Modifications:
1. Recognize accesses to the first page of the IDT by testing the
fault address in CR2. Page not present faults on other addresses
can be processed normally.

2. For page not present faults on the first page of the IDT, the OS
must recognize and dispatch the exception which caused the page
not present fault. Before proceeding, test the fault address in
CR2 to determine if it is in the address range corresponding to
exceptions 0-6.

3. Calculate which exception caused the page not present fault from
the fault address in CR2.

4. Depending on the operating system, certain privilege level checks
may be required, along with adjustments to the interrupt stack.

5. Jump to the normal handler for the appropriate exception.

This workaround should only be implemented on Intel processors that
return Family=5 via the CPUID instruction.

75/90/100/120/133/150/166/200 MHz Pentium Processors and
120/133/150/166/200/233 MHz Pentium Processors with MMX
Technology

60 MHz and 66 MHz Pentium Processors

63/83/120/125/133/150/166 MHz Pentium OverDrive Processors and
125/150/166/180/200 MHz Pentium OverDrive Processors with MMX
Technology