Как буфер хранилища и буфер заполнения строки взаимодействуют друг с другом? - PullRequest
5 голосов
/ 09 апреля 2020

Я читал документ о нападении на MDS RIDL: Rogue In-Flight Data Load . Они обсуждают, как буфер заполнения линии может вызвать утечку данных. Существует вопрос Об уязвимостях RIDL и «воспроизведении» нагрузок , в котором рассматриваются микроархитектурные детали эксплойта.

Одна вещь, которая мне не ясна после прочтения этого вопрос в том, зачем нам нужен буфер заполнения строки, если у нас уже есть буфер хранения.

Джон МакКалпин обсуждает, как буфер хранения и буфер заполнения строки связаны в Как W-1052 * -буфер связан с LFB? на форумах Intel, но это на самом деле не делает меня более понятным.

Для хранилищ в пространстве WB данные хранилища остаются в буфере хранилища до тех пор, пока не будет отменено магазины. После удаления данные могут быть записаны в кэш данных L1 (если строка присутствует и имеет разрешение на запись), в противном случае LFB выделяется для пропуска хранилища. LFB в конечном итоге получит «текущую» копию строки кэша, чтобы его можно было установить в кэш данных L1, а данные хранилища можно записать в кэш. Детали слияния, буферизации, упорядочения и «коротких сокращений» неясны ... Одна интерпретация, которая в достаточной степени согласуется с вышесказанным, состоит в том, что LFB служат буферами размера кэша, в которых данные хранилища объединяются перед отправкой в кэш данных L1. По крайней мере, я думаю, что это имеет смысл, но я, вероятно, что-то забываю ...

Я только недавно начал читать о неправильном исполнении, поэтому, пожалуйста, извините за мое невежество. Вот мое представление о том, как хранилище будет проходить через буфер хранилища и буфер заполнения строки.

  1. Инструкция хранилища запланирована во внешнем интерфейсе.
  2. Выполняется в хранилище.
  3. Запрос хранилища помещается в буфер хранилища (адрес и данные)
  4. Из хранилища отправляется недействительный запрос на чтение. буфер к системе кеша
  5. Если он пропускает кэш L1d, то запрос помещается в буфер заполнения строки
  6. Буфер заполнения строки направляет недействительный запрос чтения в L2
  7. Буфер хранилища применяет свое значение к входящей строке кеша
  8. А? Буфер заполнения строки помечает запись как недействительную

enter image description here

Вопросы

  1. Зачем нам нужно буфер заполнения строки, если буфер хранилища уже существует для отслеживания исходящих запросов хранилища?
  2. Правильно ли упорядочен порядок событий в моем описании?

1 Ответ

5 голосов
/ 10 апреля 2020

Зачем нам нужен буфер заполнения строки, если буфер хранилища уже существует для отслеживания внешних обращений к хранилищу?

Буфер хранилища используется для отслеживания хранилищ по порядку, оба до они удаляются и после того, как они удаляются, но до того, как они фиксируются в кэше L1. Буфер хранилища концептуально является полностью локальной вещью, которая на самом деле не заботится о промахах кэша. Буфер магазина имеет дело с «единицами» отдельных магазинов разных размеров. Чипы, такие как Intel Skylake, имеют буферы хранения из 50+ записей .

Основная строка буферов заполнения строки при обе загружает и сохраняет, что отсутствует в кеше L1 . По сути, это путь от кэша L1 до остальной части подсистемы памяти, и он обрабатывается в единицах размера строки кэша. Мы не ожидаем, что LFB включится, если загрузка или сохранение попадет в кэш L1 1 . Чипы Intel, такие как Skylake, имеют намного меньше записей LFB, вероятно, от 10 до 12.

Правильно ли упорядочен порядок событий в моем описании?

Довольно близко. Вот как я могу изменить ваш список:

  1. Инструкции хранилища декодируются и разделяются на мопы store-data и store-address, которые переименовываются, планируются и для них назначается запись в буфере хранилища.
  2. Хранилища выполняются в любом порядке или одновременно (два подпункта могут выполняться в любом порядке, в основном в зависимости от того, какие зависимости выполняются первыми).
    1. Uop данных хранилища записывает данные хранилища в буфер хранилища.
    2. Uop адреса хранилища выполняет преобразование VP и записывает адрес (а) в буфер хранилища.
  3. В какой-то момент, когда все более старые инструкции устарели, инструкция сохранения удаляется . Это означает, что инструкция больше не является умозрительной, и результаты можно сделать видимыми. На этом этапе хранилище остается в буфере хранилища и называется senior store.
  4. Хранилище теперь ждет, пока оно не окажется во главе буфера хранилища (это самый старый зафиксированное хранилище), после чего он будет фиксироваться (становиться глобально наблюдаемым) в L1, если соответствующая строка кэша присутствует в L1 в состоянии MESIF Modified или Exclusive. (то есть это ядро ​​владеет линией)
  5. Если строка отсутствует в требуемом состоянии (либо отсутствует полностью, т. е. отсутствует кэш, либо присутствует, но в неисключительном состоянии), разрешение на изменение строки и данных строки (иногда) должно быть получено из подсистемы памяти: это выделяет LFB для всей строки, если она еще не выделена. Это так называемый запрос на владение (RFO), что означает, что иерархия памяти должна вернуть строку в исключительном состоянии, подходящем для модификации, в отличие от общего состояния, подходящего только для чтения (это делает недействительными копии строки, присутствующей в любых других частных кешах).

    RFO для преобразования Shared в Exclusive все еще должен ждать ответа, чтобы убедиться, что все другие кеши сделали недействительными их копии. Ответ на такой недействительный запрос не должен включать копию данных, потому что у этого кэша уже есть тот. Это все еще можно назвать RFO; важная часть заключается в получении права собственности перед изменением строки.

  6. В сценарии промаха LFB в конечном итоге возвращается с полным содержимым строки, которое передается в L1, и ожидающее хранилище теперь может зафиксировать .

Это грубое приближение процесса. Некоторые детали могут отличаться для некоторых или для всех чипов, включая детали, которые не совсем понятны.

В качестве одного примера, в приведенном выше порядке строки пропуска магазина не выбираются, пока магазин не достигнет начала очереди магазина. , В действительности подсистема хранилища может реализовывать тип RFO prefetch , где очередь хранилища проверяется на наличие предстоящих хранилищ, и если строки не присутствуют в L1, запрос запускается рано (фактическая видимая фиксация для L1 все еще должен происходить по порядку, на x86 или, по крайней мере, «как если бы» по порядку).

Таким образом, запрос и использование LFB могут произойти уже после завершения шага 3 (если предварительная выборка RFO применяется только после хранилище удаляется), или, возможно, даже уже после завершения 2.2, если младшие хранилища подлежат предварительной выборке.

В качестве другого примера, шаг 6 описывает строку, возвращающуюся из иерархии памяти и фиксируемую в L1 , то магазин фиксирует. Возможно, что ожидающее хранилище фактически объединено вместо возвращаемых данных, а затем оно записывается в L1. Также возможно, что хранилище может покинуть буфер хранилища даже в случае пропуска и просто ждать в LFB, освобождая некоторые записи буфера хранилища.


1 В случае из хранилищ, которые попадают в кэш L1, существует предложение о том, что LFB действительно задействованы: что каждое хранилище фактически входит в объединяющий буфер (который может быть просто LFB) до того, как будет передано в кэш, таким образом, что ряд магазинов, нацеленных на одну и ту же строку кэша, объединяется в кэше и должен получить доступ к L1 только один раз. Это не доказано, но в любом случае это не является частью основного использования LFB (более очевидно из того факта, что мы даже не можем точно сказать, происходит это или нет).

...