【问题标题】:Write to CR2 during PageFault ISR在 PageFault ISR 期间写入 CR2
【发布时间】:2022-01-21 20:04:44
【问题描述】:

我正在编写一个页面错误处理程序,我想知道如果 ISR 在 ISR 返回之前更改 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 是否仅用于通知内核错误地址?还是会坏掉?

【问题讨论】:

  • 0xdeadbeefdeadbeef 当然是一个非规范地址,所以它会导致#GP,但这只会在第一个页面错误解决并且加载到rbx完成之后才会发生。假设您将 0xdeadbeefdeadbeef 更改为规范地址,您将在 rcx 加载时获得第二个页面错误,与 rbx 加载时的页面错误完全无关。

标签: assembly memory-management x86 kernel x86-64


【解决方案1】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-10-01
    • 2012-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-03
    • 1970-01-01
    • 2013-10-29
    相关资源
    最近更新 更多