从了解Linux内核第3版,第10.4.4节:
Page Fault处理程序do_page_fault()执行以下语句:
if ((fixup = search_exception_tables(regs->eip))) {
regs->eip = fixup->fixup;
return 1;
}
regs-> eip字段包含发生异常时保存在内核模式堆栈上的eip寄存器的值。如果寄存器中的值(指令指针)在异常表中,则do_page_fault()将使用search_exception_tables()返回的条目中找到的地址替换保存的值。然后页面错误处理程序终止,并且中断的程序在执行修正代码时恢复。
很好理解,除了一个关键的事实 - 内存操作可以被缓存,这意味着在页面错误异常时,指令指针包含与异常无关的另一条指令的地址,作为导致执行异常的指令早于CPU,但直到现在才被缓存。
Linux内核如何执行上面的代码而没有副作用?如何确定在页面错误异常时,指令指针寄存器包含访问非法地址的存储器操作指令的地址(可以缓存并稍后执行)?
发布于 2018-09-11 16:11:24
Linux内核如何执行上面的代码而没有副作用?如何确定在页面错误异常时,指令指针寄存器包含访问非法地址的存储器操作指令的地址(可以缓存并稍后执行)?
页面错误(即虚拟内存位置当前未映射到物理内存)只能在MMU将虚拟内存地址转换为物理内存地址时发生。 必须翻译虚拟内存地址的实例(同时方便地忽略IOMMU的工作方式):
如果在这些情况下对虚拟内存位置的引用导致页面错误,则IP寄存器将有效并指示引发页面错误的指令的地址(或自寄存器通常自动增量以来的下一条指令)。
如果存在处理器缓存并且它采用了回写策略,那么就没有冲突,因为您声称。 处理器缓存使用物理内存地址,而不是虚拟内存地址。 由处理器高速缓存执行的存储器操作不能生成页面错误。
https://stackoverflow.com/questions/-100006116
复制相似问题