С Общие сведения о ядре Linux, 3-е издание , глава 10.4.4, в котором обсуждается исключение сбоя страницы при доступе ядра к памяти пространства пользователя:
обработчик сбоя страницы do_page_fault () выполняет следующее
заявления:
if ((fixup = search_exception_tables(regs->eip))) {
regs->eip = fixup->fixup;
return 1;
}
Поле regs-> eip содержит значение регистра eip, сохраненного в
стек режима ядра при возникновении исключения . Если значение в
регистр (указатель инструкции) находится в таблице исключений,
do_page_fault () заменяет сохраненное значение адресом, найденным в
запись, возвращаемая функцией search_exception_tables (). Тогда ошибка страницы
обработчик завершается и прерванная программа возобновляется с выполнением
кода исправления.
Понятно, что помимо важного факта операции с памятью могут быть кэшированы , что означает, что в момент исключения ошибки страницы указатель инструкции содержал адрес другой инструкции, которая не имела отношения к исключению , как инструкция, которая вызвала исключение, выполненное ранее CPU, но кэшированное до этого момента (ссылка на это в здесь в последних параграфах).
Как Linux Kernel может выполнить приведенный выше код без побочных эффектов? как можно быть уверенным, что во время исключения ошибки страницы регистр указателя инструкций содержал адрес инструкции операции с памятью (которая может быть кэширована и выполнена позже), которая получила недопустимый адрес?
РЕДАКТИРОВАТЬ # 1:
Я полагаю, что то же руководство имеет подсказку в главе 2.4.7-
блок кэша вставлен между блоком подкачки и основной памятью
Возможно, это означает, что преобразование и проверка адресов всегда выполняются до (или во время) кеширования (по крайней мере, в архитектуре x86, на которой основано руководство), что может объяснить мою проблему тем, что проверка адреса выполнена в схеме MMU в момент выполнения инструкции ? К сожалению, я не смог найти однозначного «Да» ни в руководстве, ни в моих поисках в Интернете.
РЕДАКТИРОВАТЬ # 2:
В SuperUser я нашел другой источник, который укрепил мои предположения в EDIT # 1:
Разрешения еще нужно проверить, прежде чем доступ может быть
привержен
Таким образом, кажется (без какого-либо подтверждения из официального источника), что при доступе к памяти адрес передается в схему MMU для преобразования до или во время кэширования, что означает, что проверка адреса выполняется во время выполнения инструкции, и что это момент, когда ошибка страницы может быть поднята. Таким образом, задержка доступа к основной памяти кеша не зависит от времени сбоя страницы, и когда происходит сбой страницы, регистр указателя инструкций действительно содержит ошибочную инструкцию, которая пытается получить доступ к неверному адресу. Я буду продолжать искать источник, который подтверждает это, или, альтернативно, источник, который противоречит этому и который предлагает правильное решение.