在 PageFault ISR 期间写入 CR2

Write to CR2 during PageFault ISR

我正在编写一个页面错误处理程序,我想知道如果 ISR 在 ISR returns.

之前更改 cr2 的值会发生什么

例如,如果某些代码这样做:

mov    rax,QWORD PTR [rip+0x23]
mov    rbx,QWORD PTR [rax+0x28432] 
movabs rax,0xdeadbeefdeadbeef
mov    rcx,QWORD PTR [rax]

假设 [rax+0x28432]PTE 中的 Present 位设置为 0。我们还假设 0xdeadbeefdeadbeef 指向有效但页面调出的内存。

假设代码是ISR(这是伪代码):

PPTE pte = GetPteFromVA(__readcr2() & ~0xFFF);

/* Bring page into memory */

pte->Present = 1;

__writecr2(newValue);
__asm
{
    add rsp, 8
    iretq
}

代码中会发生什么?加载 rbx 值的指令会在其计算中使用更新后的 cr2 值吗?当试图用 rax 指向的值加载 rcx 时会发生什么? cr2 仅用于通知内核错误地址吗?还是会坏掉?

页面错误处理程序returns之后,重新执行错误指令。假设故障处理程序保留了所有寄存器值,因为它必须如此,当指令重新执行时,它将尝试再次访问相同的地址。未使用 CR2。

后续指令的页面错误只有在解决第一个页面错误并完成内存访问后才会发生。假设您将 0xdeadbeefdeadbeef 更改为规范地址,您将在 rcx 加载时遇到第二个页面错误,与 rbx 加载时的页面错误完全无关。