Код ядра Linux, кажется, игнорирует кеширование - PullRequest
0 голосов
/ 10 сентября 2018

С Общие сведения о ядре 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 для преобразования до или во время кэширования, что означает, что проверка адреса выполняется во время выполнения инструкции, и что это момент, когда ошибка страницы может быть поднята. Таким образом, задержка доступа к основной памяти кеша не зависит от времени сбоя страницы, и когда происходит сбой страницы, регистр указателя инструкций действительно содержит ошибочную инструкцию, которая пытается получить доступ к неверному адресу. Я буду продолжать искать источник, который подтверждает это, или, альтернативно, источник, который противоречит этому и который предлагает правильное решение.

...