Linux内核代码似乎忽略了缓存?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (1)
  • 关注 (0)
  • 查看 (56)

了解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内核如何执行上面的代码而没有副作用?如何确定在页面错误异常时,指令指针寄存器包含访问非法地址的存储器操作指令的地址(可以缓存并稍后执行)?

提问于
用户回答回答于

Linux内核如何执行上面的代码而没有副作用?如何确定在页面错误异常时,指令指针寄存器包含访问非法地址的存储器操作指令的地址(可以缓存并稍后执行)?

页面错误(即虚拟内存位置当前未映射到物理内存)只能在MMU将虚拟内存地址转换为物理内存地址时发生。 必须翻译虚拟内存地址的实例(同时方便地忽略IOMMU的工作方式):

  • 必须从IP寄存器中包含的地址中获取指令。
  • 该指令包含操作数的地址。
  • 该指令指定一个包含操作数地址的寄存器。

如果在这些情况下对虚拟内存位置的引用导致页面错误,则IP寄存器将有效并指示引发页面错误的指令的地址(或自寄存器通常自动增量以来的下一条指令)。

如果存在处理器缓存并且它采用了回写策略,那么就没有冲突,因为您声称。 处理器缓存使用物理内存地址,而不是虚拟内存地址。 由处理器高速缓存执行的存储器操作不能生成页面错误。

扫码关注云+社区

领取腾讯云代金券