Processors
Intel® Pentium® Processor
Invalid Instruction Erratum Overview

Invalid Instruction Errata Home Software Vendor Statements How to Contact Us
Software Backgrounder
Updated Nov. 20 1997

Erratum Technical Description Updated Nov. 20 1997

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: There are two workarounds for this erratum for protected mode operating systems. Both workarounds generate a page fault when the invalid opcode exception occurs. In both cases, the page 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. Use one of the following:

  1. The first part of this workaround sets the first 7 entries (0-6) of the Interrupt Descriptor Table (IDT) in a non-writeable page. When the invalid opcode exception (exception 6) occurs due to the locked CMPXCHG8B instruction with an invalid register destination (and only then), the processor will generate a page fault if it does not have write access to the page containing entry 6 of the IDT. The second part of this workaround modifies the page fault handler to recognize and correctly dispatch the invalid opcode exceptions that are now routed through the page fault handler.

    Part I, IDT page access
    1. Mark the page containing the first seven entries (0-6) of the IDT as read only by setting bit 1 of the page table entry to zero. Also set CR0.WP (bit 16) to 1. Now when the invalid opcode exception occurs on the locked CMPXCHG8B instruction, the processor will trigger a page fault since it does not have write access to the page containing entry 6 of the IDT. This page fault prevents the bus lock condition and gives the OS complete control to process the invalid operand exception 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.
    2. Optional: If updates to entries 7-255 of the IDT occur during the course of normal operation, page faults should be avoided on writes to these IDT entries. These page faults can be avoided by aligning the IDT across a 4KB page boundary such that the first seven entries (0-6) of the IDT are on the first read only page and the remaining entries are on a read/writeable page.
    Part II, Page Fault Handler Modifications
  • Modify the page fault handler to calculate which exception caused the page fault using the fault address in CR2. If the error code on the stack indicates the exception occurred from ring 0 and if the address corresponds to the invalid opcode exception, then pop the error code off the stack and jump to the invalid opcode exception handler. Otherwise continue with the normal page fault handler. 
    OR
    1. This workaround has two parts. First, the Interrupt Descriptor Table (IDT) is aligned such that any invalid opcode exception will cause a page fault (due to the page not being present). 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 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.

    Both workarounds 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

     

    No.

    B1

    B3

    B5

    C2

    mA1

    cB1

    mcB1

    cC0

    mA4

    mcC0

    E0

    xA3

    mxA3

    xB1

    mxB1

    myA0

    ERRATA

    81

    X

    X

    X

    X

    X

    X

    X

    X

    X

    X

    X

    X

    X

    X

    X

    X

    Invalid operand with locked CMPXCHG8B instruction

     

    60 MHz and 66 MHz Pentium® Processors

     

    No.

    B1

    C1

    D1

    ERRATA

    52

    X

    X

    X

    Invalid operand with locked CMPXCHG8B instruction

     

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

     

    No.

    B1

    B2

    C0

    tA0

    aC0

    oxA3

    oxB1

    ERRATA

    70

    X

    X

    X

    X

    X

    X

    X

    Invalid operand with locked CMPXCHG8B instruction

    This applies to:

    Intel® Pentium® Processor
    Intel® Pentium® Processor with MMX™ Technology
    OverDrive® Processors



    Solution ID: CS-013148
    Last Modified: 16-Nov-2009
    Date Created: 12-Jul-2004
    Back to Top