Comment l'adresse physique est affichée dans les chaînes DRAM et les banques

Dans un article précédent, nous avons expliqué comment les processeurs Intel Sandy Bridge mappent les adresses physiques dans le cache L3.

Je vais maintenant vous expliquer comment les contrôleurs de mémoire de ces processeurs mappent les adresses physiques à un emplacement dans la DRAM - en particulier, les numéros de ligne, de banque et de colonne dans les modules DRAM. Appelez-le mappage d'adresse DRAM . J'utilise une machine de test comme exemple.

Motivation: bug de Rowhammer


Je suis intéressé par le mappage des adresses DRAM, car il se rapporte à un bogue Rowhammer .

Rowhammer est un problème avec certains modules DRAM où certains modèles d'accès à la mémoire dans le pire des cas peuvent entraîner une corruption de la mémoire. Dans ces DRAM, l'activation multiple d'une ligne de mémoire («colmatage de ligne») provoque un bruit électrique qui modifie les bits dans les cellules vulnérables des lignes adjacentes.

Ces activations de ligne répétées peuvent être provoquées par un accès multiple à une paire d'adresses DRAM qui se trouvent sur différentes lignes de la même banque DRAM. La connaissance du mappage des adresses DRAM est utile car elle indique quelles paires d'adresses satisfont cette propriété «une banque, une ligne différente» (même banque, ligne différente; SBDR).

Deviner et vérifier le mappage d'adresses


Pour le test, j'ai une machine avec des modules DRAM vulnérable au bug Rowhammer. L'exécution de rowhammer_test sur cette machine montre un peu de changement.

Je voudrais connaître le schéma de mappage d'adresse DRAM pour cette machine, mais il n'est pas publiquement documenté: voici le processeur Sandy Bridge, mais Intel ne documente pas le mappage d'adresse utilisé par les contrôleurs de mémoire de ces processeurs.

En fait, le test rowhammer_test pas besoin de connaître les paires d'adresses SBDR. Il essaie juste plusieurs fois de marteler des paires d'adresses sélectionnées au hasard. Habituellement, 1/8 ou 1/16 d'entre eux se révèlent être des paires SBDR, car dans notre voiture, il y a 8 banques dans chaque DIMM (et 16 banques au total). Ainsi, nous n'avons pas besoin de connaître le mappage des adresses DRAM pour provoquer un changement de bit dans la mémoire, mais de telles connaissances aideront à effectuer le test de manière plus ciblée.

Bien que le mappage des adresses ne soit pas documenté, j'ai trouvé que je pouvais faire une hypothèse raisonnable à ce sujet en fonction de la géométrie de la DRAM, puis vérifier l'hypothèse en fonction des adresses physiques signalées par rowhammer_test . Le test rapporte les adresses physiques où les bits changent ( «victimes» ) et les paires d'adresses physiques qui font ces changements ( «agresseurs» ). Étant donné que ces paires doivent être des paires SBDR, nous pouvons vérifier un mappage hypothétique d'adresses à ces données empiriques.

Géométrie mémoire


Première étape: vérifiez le nombre de modules DIMM installés sur la machine et leur organisation interne.

Je peux demander des informations DIMM en utilisant l' decode-dimms sous Linux (sur Ubuntu, il est dans le package I2C-tools ). Cet outil décode les métadonnées SPD (Serial Presence Detect) dans DIMM.

Sur ma machine de test, deux SO-DIMM de quatre gigaoctets, ce qui donne 8 Go de mémoire.

L' decode-dimms rapporte les informations suivantes pour chacun des modules:

  Taille 4096 MB
 Banques x rangées x colonnes x bits 8 x 15 x 10 x 64
 Rangs 2 

Cela signifie que les deux modules DIMM:

  • Chaque banque a 2 ^ 15 lignes (32768 lignes).
  • Chaque ligne contient 2 ^ 10 * 64 bits = 2 ^ 16 bits = 2 ^ 13 octets = 8 Ko.

Chaque module DIMM a 2 rangs et 8 banques. Le recoupement de la capacité du module DIMM donne la taille attendue:

8 Ko par ligne * 32768 lignes * 2 rangs * 8 banques = 4096 Mo = 4 Go

Cartographie des adresses DRAM


Sur mon ordinateur de test, des bits d'adresses physiques sont utilisés comme suit:

  • Bits 0-5 : ce sont les 6 bits inférieurs de l'index d'octets dans la chaîne (c'est-à-dire l'index 6 bits pour la ligne de cache de 64 octets).
  • Bit 6 : il s'agit d'un numéro de canal à 1 bit qui sélectionne entre deux modules DIMM.
  • Bits 7-13 : les 7 bits supérieurs de l'index dans une ligne (c'est-à-dire les bits supérieurs du numéro de colonne).
  • Bits 14-16 : XOR avec les 3 bits inférieurs du numéro de ligne, ce qui donne un numéro de banque de 3 bits.
  • Bit 17 : Un numéro de rang sur 1 bit qui sélectionne entre deux rangs DIMM (qui sont généralement les deux côtés d'une puce DIMM).
  • Bits 18-32 : numéro de ligne 15 bits.
  • Bits 33+ : ils peuvent être définis car la mémoire physique commence par des adresses physiques supérieures à 0.

Pourquoi un tel affichage?


Ce mappage est rowhammer_test aux résultats de rowhammer_test (voir ci-dessous), mais nous pouvons également expliquer que les bits d'adresse sont mappés de manière à fournir de bonnes performances pour les modèles d'accès à la mémoire typiques, tels que l'accès séquentiel et l'accès pas à pas ( accès stridé):

  • Canaux d'accès simultané . Placer un numéro de canal dans le bit 6 signifie que les lignes de cache alterneront entre deux canaux (c'est-à-dire, deux barrettes DIMM) accessibles en parallèle. Cela signifie que si nous accédons aux adresses de manière séquentielle, la charge sera répartie sur deux canaux.

    Soit dit en passant, Ivy Bridge (le successeur de Sandy Bridge) semble compliquer l'affichage du numéro de chaîne. La présentation d'Intel mentionne le «hachage de canal» et déclare qu'elle «vous permet de sélectionner un canal en fonction de plusieurs bits d'adresse. Historiquement, c'était «A [6]». Cela garantit une répartition plus uniforme de l'accès à la mémoire entre les canaux. »
  • Glissement de banque : en général, la disposition des numéros de colonne, des banques et des lignes devrait minimiser le changement fréquent de lignes actives de banque (débordement de banque).

    Une petite introduction: les modules DRAM sont organisés en banques, qui, à leur tour, sont organisées en lignes. Chaque banque dispose d'une «ligne activée en cours»: son contenu est copié dans le buffer de ligne , qui fait office de cache accessible rapidement. L'accès à une autre ligne prend plus de temps car elle doit d'abord être activée. Ainsi, lors du mappage d'adresses DRAM, les paires SBDR sont transportées autant que possible dans l'espace d'adressage physique.

    La poursuite des lignes (martelage des lignes) est un cas particulier de glissement d'une banque lorsque deux lignes spécifiques sont activées en alternance (éventuellement à dessein).
  • Parallélisme bancaire : les banques sont accessibles en parallèle (quoique dans une moindre mesure que les canaux), de sorte que le numéro de banque change avant le numéro de ligne à mesure que l'adresse augmente.
  • Schéma XOR : XOR'ing les bits les moins significatifs d'un numéro de ligne à un numéro de banque est une astuce pour éviter de glisser la banque lors de l'accès aux tableaux en grandes étapes. Par exemple, dans l'affichage ci-dessus, XOR'ing force les adresses X et X + 256k à se trouver dans différentes banques, sans former de paire SBDR.

    Les schémas XOR pour banque / ligne sont décrits dans diverses publications, par exemple:

Réconciliation avec rowhammer_test


L'exécution de rowhammer_test_ext (une version étendue de rowhammer_test ) sur une machine de test pendant 6 heures a révélé un changement répété de bits à 22 endroits. (voir données source et code d'analyse ).

Le test de frappe des chaînes génère des ensembles de trois adresses (A1, A2, V):

  • V est l'adresse de la victime, où l'on voit le changement de bits.
  • A1 et A2 sont les adresses de l'agresseur que nous frappons.
  • Triez A1 et A2 de sorte que A1 soit plus proche de V que A2. Nous supposons provisoirement qu'une adresse plus proche, A1, provoque en fait un changement de bit (bien que cela ne serait pas nécessairement vrai si un mappage plus complexe d'adresses DRAM était utilisé).

Pour tous ces résultats, nous nous attendons à ce que trois propriétés soient terminées:

  • Ligne : les numéros de ligne A1 et V doivent différer de 1, c'est-à-dire ils devraient être dans des lignes adjacentes. (A2 peut avoir n'importe quel numéro de ligne).

    Cette propriété facilite la détermination de l'emplacement des bits les plus bas du numéro de ligne dans l'adresse physique.

    Le test a montré que cette propriété est valable pour tous les résultats sauf deux. Dans ces deux résultats, les numéros de ligne diffèrent de 3 plutôt que de 1.
  • Banque : V, A1 et A2 doivent avoir le même numéro de banque. En effet, cette propriété s'est manifestée dans les 22 résultats. Il n'est enregistré que lors de l'application du schéma XOR'ing de lignes / banques.
  • Canal : V, A1 et A2 doivent avoir le même numéro de canal. Cela est vrai pour tous les résultats. Il arrive que tous les résultats aient canal = 0, car rowhammer_test sélectionne uniquement les adresses alignées en 4k, et ne teste donc qu'un seul canal (cela peut être considéré comme un bug).

Autres tests possibles


À l'avenir, vous pouvez exécuter deux autres expériences pour vérifier si le mappage d'adresse DRAM évalue correctement la propriété SBDR:

  • Mesure du temps : l'accès multiple à des paires d'adresses SBDR devrait être plus lent que l'accès multiple à des paires sans SBDR, car le premier provoque l'activation des lignes, et le second non.
  • Test exhaustif de Rowhammer : dès que l'on trouve l'adresse de l'agresseur A1, ce qui provoque un changement répété de bits, on peut le vérifier sur de nombreuses valeurs de A2. L'effet de la monnaie (A1, A2) ne changera les bits que s'il s'agit d'une paire de SBDR.

De plus, la suppression d'un module DIMM de l'unité centrale doit supprimer le bit de canal du mappage d'adresse DRAM et modifier en conséquence les adresses d'agresseur et de victime. Cela peut également être vérifié.

Source: https://habr.com/ru/post/fr431102/


All Articles