I'm writing a pagefault handler, and I'm wondering what happens if the ISR changes the value of cr2
right before the ISR returns.
For example, if some code does this:
mov rax,QWORD PTR [rip 0x23]
mov rbx,QWORD PTR [rax 0x28432]
movabs rax,0xdeadbeefdeadbeef
mov rcx,QWORD PTR [rax]
Let's say [rax 0x28432]
has the Present
bit in the PTE
set to 0
. Let's also assume that the 0xdeadbeefdeadbeef
points to valid, but paged-out memory.
Assuming the code is the ISR (This is pseudocode):
PPTE pte = GetPteFromVA(__readcr2() & ~0xFFF);
/* Bring page into memory */
pte->Present = 1;
__writecr2(newValue);
__asm
{
add rsp, 8
iretq
}
What will happen back in the code? Will the instruction that loads rbx
with a value use the updated cr2
value in its computation? What will happen when trying to load rcx
with the value that rax
is pointing to? Is cr2
only used for notifying the kernel of a faulting address? Or will something break?
CodePudding user response:
After the page fault handler returns, the faulting instruction is reexecuted. Assuming the fault handler preserves all register values, as it must, when the instruction is reexecuted it will attempt to access the same address again. CR2 isn't used.
A page fault on a subsequent instruction can happen only after the first page fault is resolved and the memory access is completed. Assuming you change 0xdeadbeefdeadbeef to a canonical address, you'll get a second page fault on the load of rcx, completely unrelated to the page fault on the load of rbx.