Маскировка прерываний при возвращении в режим ядра
Я работаю над MIT JOS (лаборатория для класса операционной системы 6.828).
В этой простой ОС прерывания отключены в режиме ядра (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));
Я в замешательстве... есть ли другой способ сделать это?
1 ответ
Да, вы можете изменить соответствующую запись в IDT, чтобы сделать ее шлюзом прерывания вместо шлюза-ловушки, которым он является сейчас. Затем, всякий раз, когда прерывание инициируется, ЦП автоматически очищает EFLAGS.IF при переходе к обработчику, и флаг восстанавливается при возврате из обработчика с использованием IRETD.
Я предполагаю, что CLI мало поможет, потому что, хотя он отключает прерывания, он все еще допускает вложенные прерывания и потенциально может привести к переполнению стека. Этого небольшого окна одной инструкции (CLI), где прерывания все еще включены, достаточно для вмешательства прерывания с более высоким приоритетом, что, насколько я понимаю, нежелательно в текущей реализации системы или в задаче, которую вы дали.