中断上下文中的页面错误

时间:2011-01-31 07:16:02

标签: linux operating-system linux-kernel

中断处理程序/原子上下文中是否会发生页面错误?

5 个答案:

答案 0 :(得分:7)

它可以,但这将是一场灾难。 : - )

答案 1 :(得分:1)

处理程序或关键区域的代码可以跨越两个页面之间的边界。如果第二页不可用,则需要页面错误才能将其带入。

答案 2 :(得分:1)

(这是一个古老的问题。现有答案包含正确的事实,但非常薄。我会尝试以更实质的方式回答。)

此问题的答案取决于代码是在内核(管理员模式)还是在用户模式下。原因是这些区域的内存访问规则通常不同。下面是一个简短的事件序列来说明问题(假设内核内存可以被分页):

  1. 当用户程序正在执行时,会发生中断(例如按键/磁盘事件)。
  2. CPU转换为管理员模式并开始在内核中执行处理程序。
  3. 中断处理程序开始保存CPU状态(以便稍后可以正确恢复用户进程),但这样做会触及之前已被分页的部分存储。
  4. 这会触发页面错误异常。
  5. 为了处理页面错误异常,内核现在必须保存经历页面未命中的代码的CPU状态。
  6. 如果它有一个永远不会被分页的预先分配的内存池,它实际上可以做到这一点,但是这样的池将不可避免地受到限制。
  7. 所以你看,最安全(也是最简单)的解决方案是让内核确保内核拥有的内存根本不可分页。因此,内核中不应发生页面错误。它们可以发生,但正如@adobriyan指出的那样,这通常表示比在某些内存中简单的页面需求更大的错误。 (我相信在Linux中就是这种情况。请检查您的特定操作系统,以确定内核内存是否不可分页。操作系统架构确实不同。)

    总而言之,内核内存通常不是可分页的,并且由于中断通常在内核中处理,因此在处理中断时通常不应发生页面错误。较高优先级的中断仍然可以中断较低的中断。只是他们所有的资源都保存在物理内存中。

    关于原子背景的问题不太清楚。如果你的意思是硬件支持的原子操作,那么在部分完成操作的过程中不会发生中断。如果你指的是像关键部分那样的东西,那么请记住,关键部分只能模仿原子性。从硬件的角度来看,除了进入和退出代码之外,这些代码没有什么特别之处,它可以使用真正的硬件原子操作。中间的代码是普通代码,可能会被中断。

    我希望这对这个问题提供了有用的回应,因为我也有一段时间对这个问题感到疑惑。

答案 3 :(得分:0)

不确定为什么没有机构使用“Double Fault”这个词:

http://en.wikipedia.org/wiki/Double_fault

但这是英特尔手册中使用的术语:

http://software.intel.com/en-us/articles/introduction-to-pc-architecture/

或在这里:

ftp://download.intel.com/design/processor/manuals/253668.pdf(见第6-38节)。

还有一种称为三重故障的东西,正如名称所示,也可能在CPU尝试服务于双重故障​​错误时发生。

答案 4 :(得分:0)

我认为答案是肯定的。 我刚刚检查了x86_64平台的内核4.15中的页面错误处理程序代码。 采取以下作为提示。 no_context是经典的“内核哎呀”。

no_context(struct pt_regs *regs, unsigned long error_code,
           unsigned long address, int signal, int si_code)
{

        /* Are we prepared to handle this kernel fault? */
        if (fixup_exception(regs, X86_TRAP_PF)) {
                /*
                 * Any interrupt that takes a fault gets the fixup. This makes
                 * the below recursive fault logic only apply to a faults from
                 * task context.
                 */
                if (in_interrupt())
                        return;