Почему ASID только в TLB в ARMv8-A? Как избежать несанкционированного доступа к памяти, присутствующей в таблицах, но извлеченной из TLB?
У меня есть быстрый вопрос о TLB и ASID в ARMv8-A.
Из того, что я понимаю (из руководства программиста ARM и Справочного руководства по архитектуре):
- Дескрипторы страницы / блока (листовые записи таблицы MMU) не содержат идентификатора ASID, только бит nG (неглобальный), который говорит, что ASID должен использоваться для этой страницы.
- Фактическое значение ASID, которое сопоставляется со значением регистра, находится в TLB. Он устанавливается, когда происходит просмотр страницы и соответствующая запись добавляется в TLB (с текущим ASID, чтобы последующие просмотры TLB проверяли, совпадает ли новый ASID).
Скажем, я хочу использовать ASID, чтобы избежать обновления таблиц при переключении контекста. Каждый процесс имеет резидентное значение ASID. Обработайте 1 некоторые данные в vaddr a1
, процесс 2 у vaddr a2
, Я переключаю контекст с 1 на 2. Во время выполнения запись TLB, соответствующая a1
выталкивается (по какой-то причине). Процесс 2 доступа a1
происходит промах TLB, а при просмотре страницы происходит успешное выполнение и сохранение записи процесса 1 с использованием значения ASID2, что дает процессу 2 доступ к данным процесса 1.
Что я не понимаю? Разве механизм ASID не должен обеспечивать безопасность между процессами 1 и 2, избегая обновления таблиц?
Дополнительный вопрос: все ли мои программы имеют .text
раздел по одному и тому же виртуальному адресу (по крайней мере, все программы имеют один и тот же адрес точки входа), мне нужно обновлять таблицы каждый раз, когда я переключаю контекст, или я могу иметь несколько записей, соответствующих одному и тому же vaddr, используя разные ASID?
4 ответа
Кажется, у меня было неправильное представление о ASID. Я получил ответ благодаря комментарию @artlessnoise.
В случае, который я описывал, я упустил тот факт, что в какой-то момент мы должны отобразить страницы процесса 2.
Итак, что мы на самом деле делаем это:
- Обновление таблиц: добавьте страницы процесса 2 и удалите все страницы, процесс 2 не должен видеть (включая, в моем примере, страницу по адресу a1
)
- Измените ASID, чтобы любое кэшированное значение со старым ASID нельзя было использовать в TLB
- Запустить процесс 2. Если соответствующая страница процесса 1 все еще кэшируется в TLB, она игнорируется (поскольку несовпадение ASID). В обоих случаях происходит обход страниц с обновленной таблицей, содержащей только страницы, доступные для процесса 2.
Таким образом, (основная) безопасность обеспечивается таблицами, присутствующими при запуске процесса 2. А дополнительную безопасность только в TLB обеспечивает механик ASID, что позволяет нам не очищать TLB при каждом переключении контекста.
РЕДАКТИРОВАТЬ: Другое (надуманное) решение было бы отключить обход страниц для некэшированных страниц (вместо этого вызвать ошибку MMU) и вручную проверять (из ядра) разрешения процесса каждый раз, когда процесс обращается к некэшированной странице. Это кажется ужасным с точки зрения производительности (а также с точки зрения дизайна).
Обработайте 1 некоторые данные в vaddr a1, обработайте 2 в vaddr a2. I переключение контекста с 1 на 2. Во время выполнения запись TLB, соответствующая a1, удаляется (по какой-то причине). Процесс 2 обращается к a1, происходит промах TLB, и происходит просмотр страницы, он успешно выполняется и сохраняет запись процесса 1 с использованием значения ASID2, предоставляя процессу 2 доступ к данным процесса 1.
Когда процесс 1 хочет получить доступ к vaddr a1, это фактически адрес, помеченный как vaddr_a1_with_asid_P1. Когда процесс 2 хочет получить доступ к vaddr a1, это фактически адрес, помеченный как vaddr_a1_with_asid_P2. Таким образом, в TLB каждая запись TLB содержит как vaddr, так и информацию ASID процесса.
Тогда "Процесс 2 обращается к a1, происходит пропадание TLB, и происходит просмотр страницы, она завершается успешно и сохраняет запись процесса 2 с использованием значения ASID2" не произойдет.
Даже для одного и того же vaddr a1 два разных процесса доступа a1 сгенерируют две разные записи TLB. Один помечен ASID P1, другой помечен ASID P2.
Необязательный вопрос: если все мои программы имеют раздел.text по одному и тому же виртуальному адресу (по крайней мере, все программы имеют одинаковый адрес точки входа), нужно ли мне обновлять таблицы каждый раз, когда я переключаю контекст, или я могу иметь несколько записей, совпадающих с одним и тем же? vaddr, используя разные ASID?
Actullay, OS позаботится об этом. Например, ОС Linux назначит уникальный ASID процессу. Для 8-битного или 16-битного регистра ASID общий диапазон ASID ограничен.
Таким образом, когда все ASID будут использованы, ОС Linux сделает недействительным весь TLB и переназначит номер ASID с 0 в качестве начала второго цикла.
Там будет сравнение ПА в VIPT
кеш, который потерпит неудачу для Process2 с VA1
отображение на PA_process_2_with_asid_proc2
,
Так что это будет пропустить кеш для Process2
доступ.
Защита TLB с использованием ASID
Сброса TLB можно избежать, используя вышеописанный механизм, но как насчет записей кэша. Кэш не очищается при переключении контекста (при изменении битов ASID). Ни один кеш не содержит биты ASID. Например.
- Процесс 1 и процесс 2 там.
- Сначала выполнялся процесс 1, и TLB имел биты ASID, относящиеся к процессу 1.
- Это привело к заполнению кэша данными процесса 1(предположим, что процесс 1 заполнил кэш записями pa1 и pa2 согласно PAGE TABLE).
- Теперь есть переключение контекста.
- Va из ядра для процесса 2 будет иметь разные биты ASID в TLB, поэтому он будет пропущен по TLB и будет проходить таблица страниц.
- Новый PTE, относящийся к процессу 2, входит в TLB, так что теперь это хит TLB.
- Удар TLB вызывает поиск данных в кеше (который содержит данные, относящиеся к процессу 1, которые не были аннулированы или очищены)
- Таким образом, может иметь место случай, когда pa процесса 1 может перекрываться с pa процесса 2, и, таким образом, кажется, что нет защиты данных между процессами, даже если есть защита TLB
- Я где-то ошибаюсь, или я не рассматриваю некоторые основные вещи, пожалуйста, скажите....