从
Understanding the Linux Kernel 3rd edition
页面错误处理程序do\u Page\u Fault()执行以下操作
声明:
if ((fixup = search_exception_tables(regs->eip))) {
regs->eip = fixup->fixup;
return 1;
}
异常发生时
寄存器(指令指针)在异常表中,
do\u page\u fault()将保存的值替换为在中找到的地址
search\u exception\u tables()返回的条目。然后是页面错误
处理程序终止,中断的程序继续执行
修正码。
很好的理解,除了一个重要的事实-内存操作可以
缓存
,这意味着在发生页错误异常时,指令指针包含与异常无关的另一条指令的地址,即导致CPU先前执行的异常的指令,但被缓存到此时为止(参考
here
最后一段)。
缓存
编辑#1:
我相信同样的指南在第2.4.7章中也有提示-
也许这意味着地址转换和签入总是完成的
(或在此期间)到缓存(至少在x86体系结构中,本指南基于此),这可以通过在MMU电路中完成地址签入来解释我的问题
? 不幸的是,我在指南和网上搜索中都找不到任何明确的“是”。
编辑#2:
我找到了另一个来源
SuperUser
这加强了我在第1版中的推测:
仍然需要检查权限才能访问
因此,似乎(没有任何正式来源的确认)在内存访问时,地址在缓存之前或期间进入MMU电路进行转换,这意味着地址检查是在指令执行时完成的,而此时可能会引发页面错误。因此,主存访问的缓存延迟与页错误定时无关,当页错误发生时,指令指针寄存器中确实包含试图访问无效地址的错误指令。我将继续寻找一个来源,以证实这一点,或者另一个来源,矛盾,并提供了一个适当的解决方案。