Как отключить кэш процессора L1, L2, L3 на современных чипах x86/amd64?

каждый современный высокопроизводительный процессор архитектуры x86/x86_64 имеет некоторую иерархию кэшей данных: L1, L2, а иногда и L3 (и L4 в очень редких случаях), и данные, загруженные из/в основной ОЗУ, кэшируются в некоторых из них.

иногда программист может хотеть, чтобы некоторые данные не кэшировались на некоторых или всех уровнях кэша (например, при желании memset 16 ГБ ОЗУ и сохранить некоторые данные в кэше): для этого есть некоторые нетрадиционные (NT) инструкции, такие как MOVNTDQA (https://stackoverflow.com/a/37092 http://lwn.net/Articles/255364/)

но есть ли программный способ (для некоторых семейств процессоров AMD или Intel, таких как P3, P4, Core, Core i*, ...) полностью (но временно) отключить некоторые или все уровни кэша, чтобы изменить, как каждая инструкция доступа к памяти (глобально или для некоторых приложений / регионов ОЗУ) использует иерархию памяти? Например: выключить L1, выключить L1 и L2? Или изменить каждый доступ к памяти введите "uncached" UC (CD+NW бит CR0??? SDM vol3a страницы 423 424, 425 и "флаг отключения кэша третьего уровня, бит 6 MSR IA32_MISC_ENABLE (доступен только в процессорах на основе микроархитектуры Intel NetBurst) - позволяет отключить и включить кэш L3 независимо от кэшей L1 и L2.").

Я думаю, что такое действие поможет защитить данные от атак/утечек боковых каналов кэша, таких как кража AES ключи, скрытые каналы кэша, расплавление / спектр. Хотя это отключение будет иметь огромную стоимость производительности.

PS: Я помню такую программу, опубликованную много лет назад на каком-то техническом новостном сайте, но не могу найти ее сейчас. Это был просто Windows exe, чтобы записать некоторые магические значения в MSR и сделать каждую программу Windows, работающую после нее очень медленно. Кэши были отключены до перезагрузки или до запуска программы с опцией "отменить".

1 ответов


руководство Intel 3A раздел 11.5.3, предоставляет алгоритм отключение кэша:

11.5.3 Предотвращения Кэширования

чтобы отключить кэш L1, L2 и L3 после того, как они были включены и получили заливки кэша, выполните следующие действия:

  1. введите режим кэша без заполнения. (Установите флаг CD в регистре управления CR0 в 1 и флаг NW в 0.
  2. очистите все кэши с помощью инструкции WBINVD.
  3. отключите MTRRs и установите тип памяти по умолчанию для uncached или установите все MTRRs для uncached памяти тип (см. обсуждение обсуждения поля тип и флага E в разделе 11.11.2.1, "IA32_MTRR_DEF_TYPE MSR").

кэш должен быть сброшен (Шаг 2) после того, как флаг CD установлен для обеспечения согласованности системной памяти. Если кэши не смыто, кэш хитов на читает будет по-прежнему происходят и данные будут считываться из допустимых строк кэша.

цель трех отдельных шагов, перечисленных выше, касается трех различных требований: (i) прекратить использование новых данных замена существующих данных в кэше (ii) убедитесь, что данные, уже находящиеся в кэше, вытеснены в память, (iii) убедитесь, что последующие ссылки на память соблюдают семантику типа памяти UC. Различная процессорная реализация кэширования аппаратное обеспечение управления может позволить некоторую вариацию программной реализации этих трех требования. См. Примечание ниже.

Примечания Установка флага CD в регистре управления CR0 изменяет поведение кэширования процессора, как указано в таблице 11-5, но установка только флага CD может быть недостаточной для всех семейств процессоров заставьте эффективный тип памяти для всей физической памяти быть UC и не заставляйте строгую память упорядочение, из-за вариаций аппаратной реализации в разных семействах процессоров. Заставлять память UC тип и строгий порядок памяти на всей физической памяти, достаточно либо программа MTRRs для всех физической памяти, тип памяти UC или отключить все MTRRs.

для процессоров Pentium 4 и Intel Xeon после приведенной выше последовательности шагов выполняется, строки кэша, содержащие код между концом инструкции WBINVD и перед MTRRS были инвалиды могут быть сохранены в иерархии кэша. Здесь, чтобы удалить код из кэш полностью, вторая инструкция WBINVD должна быть выполнена после MTRRs были отключены.

Это длинная цитата, но она сводится к этот код

;Step 1 - Enter no-fill mode
mov eax, cr0
or eax, 1<<30        ; Set bit CD
and eax, ~(1<<29)    ; Clear bit NW
mov cr0, eax

;Step 2 - Invalidate all the caches
wbinvd

;All memory accesses happen from/to memory now, but UC memory ordering may not be enforced still.  

;For Atom processors, we are done, UC semantic is automatically enforced.

xor eax, eax
xor edx, edx
mov ecx, IA32_MTRR_DEF_TYPE    ;MSR number is 2FFH
wrmsr

;P4 only, remove this code from the L1I
wbinvd

большинство из которых не исполняется из пользовательского режима.


руководство AMD 2 предоставляет аналогичный алгоритм в разделе 7.6.2

7.6.2 Механизмы Управления Кэшем
Архитектура AMD64 предоставляет ряд механизмы контроля за кэширования памяти. Они описаны в следующих разделах.

Кэш Отключить. Бит 30 регистра CR0-это бит отключения кэша, CR0.CD. Кэширование включено когда поля CR0.Компакт-диск сбрасывается в 0, и кэширование отключено, когда поля CR0.Компакт-диск установлен в 1. Когда кэширование отключен, читает и записывает доступ к основной памяти.

программное обеспечение может отключить кэш, а кэш еще содержит допустимые данные (или инструкции). Если чтения или записи попадает в кэш данных L1 или кэш L2, когда CR0.CD=1, процессор делает следующее:

  1. записывает строку кэша обратно, если она находится в измененном или принадлежащем состоянии.
  2. инвалидирует кэш-линию.
  3. выполняет кэширование оперативной памяти для чтения или записи данных.

если выборка инструкции попадает в кэш инструкций L1, когда CR0.CD=1, Некоторые модели процессоров могут читать кэшированный инструкции, а не доступ к основной памяти. Когда CR0.CD=1, точное поведение L2 и кэш L3 зависит от модели и может варьироваться для разных типов доступа к памяти.

процессор также реагирует на кэш-зонды, когда CR0.CD=1. Зонды, которые попали в кэш, вызывают процессор для выполнения шага 1. Шаг 2 (аннулирование строки кэша) выполняется только в том случае, если зонд выполняется от имени записи в память или эксклюзивного чтения.

Writethrough Отключить. Бит 29 регистра CR0-это бит not writethrough disable, CR0.NW. В рано процессоров x86, поля CR0.NW используется для управления поведением записи кэша и комбинацией Почтовый индекс CR0.NW и CR0.CD определяет режим работы кэша.

[...]

в реализациях архитектуры AMD64, CR0.NW не используется для квалификации работы кэша режиме, установленном поля CR0.Компакт-диск.

это переводится на этот код (очень похожие на Intel один):

;Step 1 - Disable the caches
mov eax, cr0
or eax, 1<<30
mov cr0, eax

;For some models we need to invalidated the L1I
wbinvd

;Step 2 - Disable speculative accesses
xor eax, eax
xor edx, edx
mov ecx, MTRRdefType  ;MSR number is 2FFH
wrmsr

кэши также могут быть выборочно отключены по адресу:

  • уровень страницы, с атрибутом bits PCD (кэш страницы отключен) [только для Pentium Pro и Pentium II].
    Когда оба ясны, используется MTTR релевантности, если PCD установлен боль
  • уровень страницы, с механизмом PAT (таблица атрибутов страницы).
    Заполняя IA32_PAT с типами кэширования и использованием бит PAT, PCD, PWT в качестве 3-бит индекс можно выбрать один из шести типов кэширования (UC -, UC, WC, WT, WP, WB).
  • использование MTTRs (фиксированной или переменной).
    Установив тип кэширования в UC или UC-для конкретного физическая местах.

из этих параметров только атрибуты страницы могут быть доступны для программ пользовательского режима (см., например,этой).