为什么页面错误通常由 OS 而不是硬件来处理?

Why page faults are usually handled by the OS, not hardware?

我发现在TLB丢失的过程中,有些架构使用硬件来处理,有些则使用OS。但是当涉及到页面错误时,他们中的大多数使用 OS 而不是硬件。

我试图找到答案,但没有找到任何文章解释原因。

有人可以帮忙吗? 谢谢

如果硬件可以自行处理,就不会出现故障。

重点是 OS 没有将页面连接到硬件页面 table,例如因为它实际上根本不在内存中,或者因为 OS 需要捕获写入尝试以便 OS 可以实现写时复制。

页面错误分为三类:

  • valid(进程逻辑上有内存映射,但是OS偷懒了或者耍花样):
    • 硬:页面需要从磁盘调入,可以是交换 space 或磁盘文件(例如内存映射文件,如 executable 或共享的页面图书馆)。 通常 OS 会在等待 I/O 时安排另一个任务。
    • soft:不需要磁盘访问,例如分配+清零一个新的物理页面以支持用户-space 刚刚尝试写入的虚拟页面。或多个进程已映射的可写页面的写时复制,但其中一个进程的更改不应该对另一个进程可见(如 mmap(MAP_PRIVATE))。这会将共享页面变成私有脏页。
  • 无效:该页面甚至没有逻辑映射。像 Linux 这样的 POSIX OS 将向违规的 process/thread.
  • 发送 SIGSEGV 信号

硬件不知道哪个是哪个,它只知道页面遍历没有找到该虚拟地址的有效页面-table 条目,所以是时候让 OS 决定下一步做什么。 (即引发 运行 是 OS 的页面错误处理程序的页面错误异常。)valid/invalid 纯粹是 software/OS 概念。

这些示例原因并非详尽无遗。例如OS 可能会删除页面的硬件映射而不实际将其分页,只是为了查看进程是否很快再次接触它。 (在这种情况下,它只是一个便宜的软页面错误。但如果不是,那么它实际上可能会将其分页到磁盘。如果它是干净的,则将其丢弃。)

为了让硬件能够完全处理页面错误,我们需要具有硬件指定布局的数据结构,以某种方式让硬件知道在某些可能的情况下该怎么做。除非你将整个内核构建到 CPU 微代码中,否则不可能让它处理 每个 页面错误,尤其是那些需要读取 OS 的无效页面错误s 进程/任务管理数据结构并向用户传递信号-space。如果有信号处理程序,或者终止进程。

尤其是硬页面错误,多任务处理 OS 会在等待磁盘将页面 DMA 写入内存时让其他进程 运行 在连接之前此进程的页面 tables 并让它重试错误的加载或存储指令。