x86page-fault

When is EIP register equal to CR2 in 80X86?


If CPU fetchs a instruction, is it possible that EIP == CR2 ?

I just wonder it, but after many searches it seems that nobody cares about it .


Solution

  • A page fault sets CR2 to the page-fault linear address, but it keeps its value until the next page fault.

    After a page fault has been resolved and the page-fault handler returns to user-space, it will re-run the faulting instruction. The normal way for that to happen is via an iret which sets CS:EIP to the exception-return address,.

    If the page fault was on code-fetch, and you have a flat memory model (CS base = 0 so EIP = the linear address), then CR2 = address of the faulting instruction, which is also the exception-return address pushed by the #PF exception.

    A confounding factor is that during execution of an instruction, EIP is the address of the end of the current instruction. (Relative jumps and [rip + rel32] addressing modes are relative to the end of instructions.) But if you think of a logical state between instructions, like after iret sets a new CS:EIP but before fetch+decode of an instruction there changes EIP again, you could have EIP = CR2 during normal operation, without having to do mov cr2, eax which could of course trivially create any condition you want.

    Of course this is just the logical model of execution, running one instruction at a time, in program order. Maybe a non-pipelined CPU like 386 could actually have physical states like that, but modern superscalar out-of-order exec CPUs only maintain the illusion of running as if they'd done that.


    Say you had a memory layout like

      0x401234   jmp foo
      ...
      0x402000   foo:  nop         # in an page that's not mapped yet
    

    A possible sequence of execution could be: