Обработчик ошибок страницы __do_page_fault
включает в себя этот фрагмент кода:
if (!(error_code & X86_PF_USER) &&
!search_exception_tables(regs->ip)) {
bad_area_nosemaphore(regs, error_code, address, NULL);
return;
}
Это условие !(error_code & X86_PF_USER)
выполняется, когда системный вызов происходит из режима ядра, а не из режима пользователя.Это условие !search_exception_tables(regs->ip)
истинно, когда сбой страницы не произошел из-за выполнения одной из инструкций, использующих линейную функцию, переданную системному вызову.Обратите внимание, что regs->ip
содержит указатель команды, вызвавшей ошибку страницы.Если оба эти условия выполняются, это означает, что в какой-либо функции ядра имеется ошибка или имеется какая-то аппаратная ошибка (второй случай).
regs
содержит снимок всех архитектурных регистров ввремя ошибки страницы.На x86 это включает в себя регистр сегмента CS.RPL в этом регистре можно использовать для определения того, произошел ли системный вызов из пользовательского режима или режима ядра.
search_exception_tables
выполняет двоичный поиск по отсортированным массивам адресов команд, которые создаются во время компиляции при компиляцииядро.Это в основном инструкции для доступа к адресу, переданному системному вызову.
Для двух других перечисленных вами случаев условие !(error_code & X86_PF_USER)
будет ложным.