返回内核模式时屏蔽中断
Masking interrupts when going back to kernel mode
我正在研究 MIT's JOS(针对 6.828 操作系统的实验室 class)。
在这个简单的OS中,内核模式下禁用中断(cli
是内核的第一条指令运行)。一旦我们通过相应地设置 eflags 寄存器启动用户进程,就会重新启用中断,并且在返回内核模式时应该以某种方式再次屏蔽。
我的问题是,在发生陷阱并且我回到内核模式后,IF 仍然设置在 eflags 中。我很想使用 cli
作为我的陷阱处理程序的第一条指令来清除它,但以下评论 (trap.c) 明确表示不要这样做:
// Check that interrupts are disabled. If this assertion
// fails, DO NOT be tempted to fix it by inserting a "cli" in
// the interrupt path.
assert(!(read_eflags() & FL_IF));
我很困惑...还有其他方法吗?
是的,您可以更改 IDT 中的相关条目,使其成为 中断门 而不是 陷阱门,它就是现在。然后,每当中断被触发时,CPU 将在跳转到处理程序时自动清除 EFLAGS.IF,并且在使用 IRETD 从处理程序返回时将恢复标志。
我的猜测是 CLI 不会有太大帮助,因为虽然它禁用了中断,但它仍然允许嵌套中断并可能导致堆栈溢出。仍然启用中断的一条指令 (CLI) 的这一小 window 足以让更高优先级的中断进行干预,据我所知,这在系统的当前实现或您正在执行的任务中是不可取的给出。
我正在研究 MIT's JOS(针对 6.828 操作系统的实验室 class)。
在这个简单的OS中,内核模式下禁用中断(cli
是内核的第一条指令运行)。一旦我们通过相应地设置 eflags 寄存器启动用户进程,就会重新启用中断,并且在返回内核模式时应该以某种方式再次屏蔽。
我的问题是,在发生陷阱并且我回到内核模式后,IF 仍然设置在 eflags 中。我很想使用 cli
作为我的陷阱处理程序的第一条指令来清除它,但以下评论 (trap.c) 明确表示不要这样做:
// Check that interrupts are disabled. If this assertion
// fails, DO NOT be tempted to fix it by inserting a "cli" in
// the interrupt path.
assert(!(read_eflags() & FL_IF));
我很困惑...还有其他方法吗?
是的,您可以更改 IDT 中的相关条目,使其成为 中断门 而不是 陷阱门,它就是现在。然后,每当中断被触发时,CPU 将在跳转到处理程序时自动清除 EFLAGS.IF,并且在使用 IRETD 从处理程序返回时将恢复标志。
我的猜测是 CLI 不会有太大帮助,因为虽然它禁用了中断,但它仍然允许嵌套中断并可能导致堆栈溢出。仍然启用中断的一条指令 (CLI) 的这一小 window 足以让更高优先级的中断进行干预,据我所知,这在系统的当前实现或您正在执行的任务中是不可取的给出。