In einem
früheren Artikel haben wir erläutert, wie Intel Sandy Bridge-Prozessoren physische Adressen im L3-Cache zuordnen.
Jetzt erkläre ich Ihnen, wie die Speichercontroller dieser Prozessoren physische Adressen einem Ort im DRAM zuordnen - insbesondere den Zeilen-, Bank- und Spaltennummern in DRAM-Modulen. Nennen
wir es
DRAM-Adresszuordnung . Ich benutze eine Testmaschine als Beispiel.
Motivation: Rowhammer Bug
Ich bin daran interessiert, DRAM-Adressen zuzuordnen, da es sich um einen
Rowhammer-Fehler handelt .
Rowhammer ist ein Problem bei einigen DRAM-Modulen, bei denen bestimmte Worst-Case-Speicherzugriffsmodelle zu Speicherbeschädigungen führen können. In diesen DRAMs verursacht die mehrfache Aktivierung einer Speicherleitung ("Leitungsverstopfung") elektrisches Rauschen, das die Bits in den anfälligen Zellen benachbarter Leitungen ändert.
Diese wiederholten Leitungsaktivierungen können durch Mehrfachzugriff auf ein Paar von DRAM-Adressen verursacht werden, die sich auf verschiedenen Leitungen derselben DRAM-Bank befinden. Die Kenntnis der Zuordnung von DRAM-Adressen ist nützlich, da sie angibt, welche Adresspaare diese Eigenschaft "eine Bank, unterschiedliche Zeile" (dieselbe Bank, unterschiedliche Zeile; SBDR) erfüllen.
Adresszuordnung erraten und überprüfen
Für den Test habe ich eine Maschine mit DRAM-Modulen, die für den Rowhammer-Fehler anfällig sind. Das Ausführen von
rowhammer_test auf diesem Computer zeigt eine geringfügige Änderung.
Ich möchte das DRAM-Adresszuordnungsschema für diesen Computer kennen, aber es ist nicht öffentlich dokumentiert: Hier ist der Sandy Bridge-Prozessor, aber Intel dokumentiert nicht die Adresszuordnung, die von den Speichercontrollern dieser Prozessoren verwendet wird.
Tatsächlich muss der
rowhammer_test
Test
rowhammer_test
SBDR-Adresspaare kennen. Er versucht nur mehrmals, zufällig ausgewählte Adresspaare einzuschlagen. Normalerweise stellen sich 1/8 oder 1/16 von ihnen als SBDR-Paare heraus, da in unserem Auto 8 Banken in jedem DIMM (und insgesamt 16 Banken) vorhanden sind. Daher müssen wir die Zuordnung von DRAM-Adressen nicht kennen, um eine Bitänderung im Speicher zu bewirken, aber dieses Wissen hilft, den Test zielgerichteter durchzuführen.
Obwohl die Zuordnung von Adressen nicht dokumentiert ist, habe ich festgestellt, dass ich basierend auf der DRAM-Geometrie eine vernünftige Annahme treffen und dann die Annahme anhand der von
rowhammer_test
gemeldeten physischen Adressen überprüfen kann. Der Test meldet die physischen Adressen, an denen sich die Bits ändern (
"Opfer" ), und die Paare physischer Adressen, die diese Änderungen vornehmen (
"Angreifer" ). Da diese Paare SBDR-Paare sein müssen, können wir eine hypothetische Zuordnung von Adressen zu diesen empirischen Daten überprüfen.
Speichergeometrie
Der erste Schritt: Überprüfen Sie, wie viele DIMMs auf dem Computer installiert sind und wie sie intern organisiert sind.
Ich kann DIMM-Informationen mit dem
decode-dimms
unter Linux
decode-dimms
(unter Ubuntu im
I2C-tools
Paket). Dieses Tool decodiert
SPD- Metadaten
(Serial Presence Detect) in DIMM.
Auf meinem Testcomputer zwei
SO-DIMMs mit vier Gigabyte, die 8 GB Speicher
bieten .
Das
decode-dimms
meldet die folgenden Informationen für jedes der Module:
Größe 4096 MB
Bänke x Zeilen x Spalten x Bits 8 x 15 x 10 x 64
Ränge 2
Dies bedeutet, dass beide DIMMs:
- Jede Bank hat 2 ^ 15 Zeilen (32768 Zeilen).
- Jede Zeile enthält 2 ^ 10 * 64 Bit = 2 ^ 16 Bit = 2 ^ 13 Byte = 8 KB.
Jedes DIMM hat 2 Ränge und 8 Banken. Wenn Sie die Kapazität des DIMM überprüfen, erhalten Sie die erwartete Größe:
8 KB pro Zeile * 32768 Zeilen * 2 Ränge * 8 Banken = 4096 MB = 4 GB
Zuordnung von DRAM-Adressen
Auf meinem Testcomputer werden Bits physischer Adressen wie folgt verwendet:
- Bits 0-5 : Dies sind die unteren 6 Bits des Byte-Index in der Zeichenfolge (d. H. Der 6-Bit-Index für die 64-Byte-Cache-Zeile).
- Bit 6 : Dies ist eine 1-Bit-Kanalnummer, die zwischen zwei DIMMs auswählt.
- Bits 7-13 : die oberen 7 Bits des Index in einer Zeile (d. H. Die oberen Bits der Spaltennummer).
- Bits 14-16 : XOR mit den unteren 3 Bits der Zeilennummer, was eine 3-Bit-Banknummer ergibt.
- Bit 17 : Eine 1-Bit-Rangnummer, die zwischen zwei DIMM-Rängen auswählt (die normalerweise zwei Seiten eines DIMM-Chips sind).
- Bits 18-32 : 15-Bit-Zeilennummer.
- Bits 33+ : Sie können gesetzt werden, da der physische Speicher mit physischen Adressen größer als 0 beginnt.
Warum so ein Display?
Diese Zuordnung
rowhammer_test
den Ergebnissen von
rowhammer_test
(siehe unten), wir können jedoch auch erklären, dass die Adressbits so zugeordnet sind, dass sie eine gute Leistung für typische Speicherzugriffsmuster wie sequentiellen Zugriff und Schritt- oder Schrittzugriff bieten ( schrittweiser Zugang):
- Parallelitätskanäle . Das Platzieren einer Kanalnummer in Bit 6 bedeutet, dass sich die Cache-Zeilen zwischen zwei Kanälen (d. H. Zwei DIMMs) abwechseln, auf die parallel zugegriffen werden kann. Dies bedeutet, dass wenn wir nacheinander auf Adressen zugreifen, die Last auf zwei Kanäle verteilt wird.
Übrigens scheint Ivy Bridge (der Nachfolger von Sandy Bridge) die Anzeige der Kanalnummer zu erschweren. In der Präsentation von Intel wird "Channel-Hashing" erwähnt und es wird angegeben, dass "Sie einen Kanal basierend auf mehreren Adressbits auswählen können". Historisch war es "A [6]". Dies gewährleistet eine gleichmäßigere Verteilung des Speicherzugriffs auf die Kanäle. “ - Bankrutschen : Im Allgemeinen sollte die Anordnung von Spaltennummern, Banken und Zeilen den häufigen Wechsel der aktiven Bankzeilen (Bank Thrashing) minimieren.
Eine kleine Einführung: DRAM-Module sind in Banken organisiert, die wiederum in Zeilen organisiert sind. Jede Bank hat eine „aktuell aktivierte Zeile“: Ihr Inhalt wird in den Zeilenpuffer kopiert, der als Cache fungiert und auf den schnell zugegriffen werden kann. Der Zugriff auf eine andere Leitung dauert länger, da sie zuerst aktiviert werden muss. Bei der Zuordnung von DRAM-Adressen werden SBDR-Paare so weit wie möglich im physischen Adressraum übertragen.
Das Verfolgen von Linien (Reihenhämmern) ist ein Sonderfall des Ausrutschens einer Bank, wenn zwei bestimmte Linien abwechselnd aktiviert werden (möglicherweise absichtlich). - Bankparallelität : Auf Banken kann parallel zugegriffen werden (wenn auch in geringerem Umfang als auf Kanäle), sodass sich die Banknummer mit zunehmender Adresse vor der Zeilennummer ändert.
- XOR-Schema : Das XOR- Verknüpfen der niedrigstwertigen Bits einer Zeilennummer mit einer Banknummer ist ein Trick, um ein Verrutschen der Bank beim Zugriff auf Arrays in großen Schritten zu vermeiden. In der obigen Anzeige erzwingt XOR'ing beispielsweise, dass sich die X- und X + 256k-Adressen in verschiedenen Bänken befinden, ohne ein SBDR-Paar zu bilden.
XOR'ing-Schemata für Bank / Line sind in verschiedenen Literaturstellen beschrieben, zum Beispiel:
Abstimmung mit rowhammer_test
Das 6-stündige Ausführen von
rowhammer_test_ext (eine erweiterte Version von
rowhammer_test
) auf einem
rowhammer_test
ergab eine wiederholte Änderung der Bits an 22 Stellen. (siehe
Quelldaten und Analysecode ).
Der Test zum Prägen von Zeichenfolgen generiert Sätze von drei Adressen (A1, A2, V):
- V ist die Adresse des Opfers, wo wir die Änderung der Bits sehen.
- A1 und A2 sind die Adressen des Angreifers, den wir prägen.
- Sortieren Sie A1 und A2 so, dass A1 näher an V als an A2 liegt. Wir nehmen vorläufig an, dass eine nähere Adresse, A1, tatsächlich eine Bitänderung verursacht (obwohl dies nicht unbedingt zutreffen würde, wenn eine komplexere Zuordnung von DRAM-Adressen verwendet würde).
Für all diese Ergebnisse erwarten wir, dass drei Eigenschaften abgeschlossen sind:
- Zeile : Die Zeilennummern A1 und V müssen sich um 1 unterscheiden, d. H. Sie sollten in benachbarten Zeilen stehen. (A2 kann eine beliebige Zeilennummer haben).
Mit dieser Eigenschaft können Sie leicht feststellen, wo sich die niedrigsten Bits der Zeilennummer in der physischen Adresse befinden.
Der Test zeigte, dass diese Eigenschaft für alle bis auf zwei Ergebnisse gilt. In diesen beiden Ergebnissen unterscheiden sich die Zeilennummern eher um 3 als um 1. - Bank : V, A1 und A2 müssen dieselbe Banknummer haben. In der Tat manifestierte sich diese Eigenschaft in allen 22 Ergebnissen. Es wird nur gespeichert, wenn das XOR-Schema von Leitungen / Banken angewendet wird.
- Kanal : V, A1 und A2 müssen dieselbe Kanalnummer haben. Dies gilt für alle Ergebnisse. Es kommt vor, dass alle Ergebnisse Kanal = 0 haben, da
rowhammer_test
nur Adressen auswählt, die in 4k ausgerichtet sind, und daher nur einen Kanal testet (möglicherweise kann dies als Fehler angesehen werden).
Mögliche weitere Tests
In Zukunft können Sie zwei weitere Experimente durchführen, um zu überprüfen, ob die DRAM-Adresszuordnung die SBDR-Eigenschaft korrekt bewertet:
- Zeitmessung : Der Mehrfachzugriff auf Paare von SBDR-Adressen sollte langsamer sein als der Mehrfachzugriff auf Paare ohne SBDR, da der erste die Aktivierung der Leitungen bewirkt und der zweite nicht.
- Umfassende Rowhammer-Tests : Sobald wir die Adresse des Angreifers A1 gefunden haben, die eine wiederholte Änderung der Bits verursacht, können wir dies bei vielen Werten von A2 überprüfen. Der Münzeffekt (A1, A2) ändert die Bits nur, wenn es sich um ein Paar SBDR handelt.
Darüber hinaus sollte durch Entfernen eines DIMMs von der Systemeinheit das Kanalbit aus der DRAM-Adresszuordnung entfernt und die Aggressor- und Opferadresse entsprechend geändert werden. Dies kann auch überprüft werden.