Главная » Хабрахабр » [Перевод] Как физический адрес отображается в строках и банках DRAM

[Перевод] Как физический адрес отображается в строках и банках DRAM

В прошлой статье мы обсуждали, как процессоры Intel Sandy Bridge отображают физические адреса в кэше L3.

Назовём это отображением адресов DRAM. Теперь я расскажу, как контроллеры памяти этих процессоров сопоставляют физические адреса с местоположением в DRAM — в частности, с номерами строк, банков и столбцов в модулях DRAM. Я использую одну тестовую машину в качестве примера.

Мотивация: баг Rowhammer

Меня интересует отображение адресов DRAM, поскольку оно относится к багу Rowhammer.

В этих DRAM многократная активация строки памяти («забивание строки») вызывает электрические помехи, меняющие биты в уязвимых ячейках соседних строк.
Эти повторяющиеся активации строк могут быть вызваны многократным доступом к паре адресов DRAM, которые находятся в разных строках одного банка DRAM. Rowhammer — проблема с некоторыми модулями DRAM, когда определённые самые плохие модели доступа к памяти могут привести к повреждению памяти. Знание отображения адресов DRAM полезно, поскольку оно указывает, какие пары адресов удовлетворяют этому свойству «один банк, разные строки» (same bank, different row; SBDR).

Угадывание и проверка отображения адресов

Для теста у меня есть машина с модулями DRAM, уязвимыми к багу Rowhammer. Запуск rowhammer_test на этой машине демонстрирует смену битов.

Я хотел бы знать схему отображения адресов DRAM для этой машины, но она не задокументирована публично: здесь процессор Sandy Bridge, но Intel не документирует отображение адресов, используемое контроллерами памяти этих процессоров.

Он просто несколько раз пытается забивать случайно выбранные пары адресов. На самом деле тесту rowhammer_test не нужно знать пары адресов SBDR. Таким образом, нам не нужно знать отображение адресов DRAM, чтобы вызвать смену битов в памяти, но такое знание поможет проводить тест более целенаправленно. Обычно 1/8 или 1/16 из них оказываются парами SBDR, потому что в нашей машине 8 банков в каждом DIMM (и 16 банков в итоге).

Тест сообщает физические адреса, где происходят смены битов («жертвы») и пары физических адресов, которые производят эти смены («агрессоры»). Хотя отображение адресов не задокументировано, я обнаружил, что могу сделать обоснованное предположение о нём на основе геометрии DRAM, а затем проверить предположение на основе физических адресов, о которых сообщает rowhammer_test. Поскольку эти пары должны быть парами SBDR, мы можем проверить гипотетическое сопоставление адресов с этими эмпирическими данными.

Геометрия памяти

Первый шаг: проверить, сколько DIMM установлено в машине и как они внутренне организованы.

Этот инструмент декодирует метаданные SPD (Serial Presence Detect) в DIMM. Я могу запросить информацию о DIMM с помощью инструмента decode-dimms в Linux (в Ubuntu он находится в пакете I2C-tools).

На моей тестовой машине два четырёхгигабайтных SO-DIMM, что даёт 8 ГБ памяти.

Инструмент decode-dimms сообщает следующую информацию для каждого из модулей:

Size 4096 MB
Banks x Rows x Columns x Bits 8 x 15 x 10 x 64
Ranks 2

Это означает, что у обоих DIMM:

  • В каждом банке 2^15 строк (32768 строк).
  • Каждая строка содержит 2^10 * 64 бит = 2^16 бит = 2^13 байт = 8 Кбайт.

У каждого DIMM есть 2 ранга и 8 банков. Перекрёстная проверка ёмкости модуля DIMM даёт тот размер, какой и ожидалось:

8 Кбайт в строке * 32768 строк * 2 ранга * 8 банков = 4096 МБ = 4 ГБ

Отображение адресов DRAM

На моём тестовом компьютере биты физических адресов используются следующим образом:

  • Биты 0-5: это младшие 6 битов байтового индекса в строке (т.е. 6-битный индекс для 64-байтовой кэш-линии).
  • Бит 6: это 1-битный номер канала, который выбирает между двумя DIMM.
  • Биты 7-13: верхние 7 битов индекса в строке (т.е. верхние биты номера столбца).
  • Биты 14-16: XOR с нижними 3 битами номера строки, что выдаёт 3-битный номер банка.
  • Бит 17: 1-битный номер ранга, который выбирает между двумя рангами DIMM (которые обычно являются двумя сторонами микросхемы DIMM).
  • Биты 18-32: 15-битный номер строки.
  • Биты 33+: их можно установить, потому что физическая память начинается с физических адресов больше 0.

Почему такое отображение?

Данное отображение сходится с результатами rowhammer_test (см. ниже), но мы также можем объяснить, что адресные биты сопоставляются таким образом, чтобы обеспечить хорошую производительность для типичных шаблонов доступа к памяти, таких как последовательный доступ (sequential access) и ступенчатый или шаговый доступ (strided access):

  • Параллелизм каналов. Размещение номера канала в бите 6 означает, что кэш-линии станут чередоваться между двумя каналами (т.е. двумя модулями DIMM), к которым можно получить доступ параллельно. Это означает, что если мы обращаемся к адресам последовательно, нагрузка будет распределена по двум каналам.

    В презентации Intel упоминается «хэширование каналов» и говорится, что это «позволяет выбирать канал на основе нескольких адресных битов. Кстати, Ivy Bridge (преемник Sandy Bridge), по-видимому, усложняет отображение номера канала. Так обеспечивается более равномерное распределение доступа к памяти по каналам». Исторически оно равнялось “A[6]”.

  • Буксование банка: в целом, расположение номеров колонок, банков и строк должно минимизировать частую смену активных строк банка (bank thrashing).

    У каждого банка есть «текущая активированная строка»: её содержимое копируется в буфер строк, который действует как кэш, к которому можно быстро получить доступ. Небольшое введение: модули DRAM организованы в банки, которые, в свою очередь, организованы в строки. Итак, при отображении адресов DRAM пары SBDR разносятся как можно дальше в физическом адресном пространстве. Доступ к другой строке занимает больше времени, потому что её сначала нужно активировать.

    Чеканка строк (row hammering) — частный случай буксования банка, когда попеременно активируются две конкретные строки (возможно, специально).

  • Параллелизм банков: доступ к банкам может осуществляться параллельно (хотя и в меньшей степени, чем к каналам), поэтому номер банка изменяется перед номером строки по мере увеличения адреса.
  • Схема XOR: XOR'инг младших бит номера строки в номер банка — это трюк, чтобы избежать буксования банка при доступе к массивам большими шагами. Например, в приведённом выше отображении XOR'инг заставляет адреса X и X+256k разместиться в разных банках, не образуя пару SBDR.

    Схемы XOR'инга для банка/строки описаны в различной литературе, например:

Cверка c выдачей rowhammer_test

Работа rowhammer_test_ext (расширенная версия rowhammer_test) на тестовой машине в течение 6 часов выявила повторяемую смену битов в 22 местах. (см. исходные данные и код анализа).

Тест чеканки строк генерирует наборы из трёх адресов (A1, A2, V):

  • V — адрес жертвы, где мы видим смену бита.
  • А1 и А2 — адреса агрессора, которые мы чеканим.
  • Сортируем A1 и A2 так, чтобы A1 был ближе к V, чем A2. Мы предварительно предполагаем, что более близкий адрес, A1 фактически вызывает смену бита (хотя это не обязательно было бы верно, если бы использовалось более сложное отображение адресов DRAM).

Для всех этих результатов мы ожидаем выполнения трёх свойств:

  • Строка: номера строк A1 и V должны отличаться на 1, т.е. они должны быть в соседних строках. (у A2 может быть любой номер строки).

    Это свойство позволяет легко определить, где в физическом адресе находятся нижние биты номера строки.

    В этих двух результатах номера строк отличаются на 3, а не на 1. Тест показал, что это свойство выполняется для всех результатов, кроме двух.

  • Банк: V, A1 и A2 должны иметь одинаковый номер банка. Действительно, это свойство проявилось во всех 22 результатах. Оно сохраняетися только при применении схемы XOR'инга строк/банков.
  • Канал: V, A1 и A2 должны иметь одинаковый номер канала. Это справедливо для всех результатов. Бывает, что у всех результатов channel=0, потому что rowhammer_test выбирает только адреса, выровненные по 4k, и поэтому тестирует только один канал (возможно, это можно считать багом).

Возможные дальнейшие тесты

В будущем можно запустить ещё два эксперимента для проверки, правильно ли отображение адресов DRAM оценивает свойство SBDR:

  • Замер времени: многократный доступ к парам адресов SBDR должен быть медленнее, чем многократный доступ к парам без SBDR, потому что первый вызывает активацию строк, а второй — нет.
  • Исчерпывающее тестирование Rowhammer: как только мы нашли адрес агрессора A1, который вызывает повторяемую смену бита, мы можем проверить это на многих значениях A2. Эффект чеканки (A1, A2) произведёт смену битов только в том случае, если это пара SBDR.

Кроме того, изъятие одного модуля DIMM из системного блока должно изъять бит канала из отображения адресов DRAM и соответственно изменить адреса агрессора и жертвы. Это тоже можно проверить.


Оставить комментарий

Ваш email нигде не будет показан
Обязательные для заполнения поля помечены *

*

x

Ещё Hi-Tech Интересное!

Теория счастья. Случайности неслучайны

Продолжаю знакомить читателей Хабра с главами из своей книжки «Теория счастья» с подзаголовком «Математические основы законов подлости». Это ещё не изданная научно-популярная книжка, очень неформально рассказывающая о том, как математика позволяет с новой степенью осознанности взглянуть на мир и жизнь ...

Снежинки в стилистике StarWars своими руками (upd. 2018)

Для изготовления снежинок вам потребуется: Файл со схемой.2. 1. Ножницы.4. Принтер (думаю лазерный будет предпочтительней).3. Бумага.5. Скальпель.5. Лично мое мнение — при печати на стандартной офисной бумаге плотностью 80г/м2 становится не очень удобно вырезать (все-таки при складывании бумаги получается толстый ...