Remapping iommu DMA

Cette page décrit la fonctionnalité de remapping iommu DMA (IOMMUv2) introduite dans Windows 11 22H2 (WDDM 3.0). Pour plus d’informations sur l’isolation de GPU IOMMU avant WDDM 3.0, consultez Isolation GPU basée sur IOMMU .

Vue d’ensemble

Jusqu’à WDDM 3.0, Dxgkrnl ne prend en charge l’isolation IOMMU que par le biais d’un remapping physique 1 :1, ce qui signifie que les pages logiques consultées par le GPU étaient traduites en le même numéro de page physique. Le remapping iomMU DMA permet au GPU d’accéder à la mémoire via des adresses logiques qui ne sont plus mappées 1 :1. Au lieu de cela, Dxgkrnl est en mesure de fournir des plages d’adresses contiguës logiquement.

Dxgkrnl impose une restriction sur les GPU : les GPU doivent pouvoir accéder à toute la mémoire physique pour que l’appareil démarre. Si l’adresse visible la plus élevée du GPU ne dépasse pas l’adresse physique la plus élevée installée sur le système, Dxgkrnl échoue à l’initialisation de l’adaptateur. Les serveurs à venir et les stations de travail haut de gamme peuvent être configurés avec plus de 1 To de mémoire qui dépasse la limite d’espace d’adressage 40 bits courante de nombreux GPU. Le remapping DMA est utilisé comme mécanisme pour permettre aux GPU de fonctionner dans cet environnement.

Au moment du démarrage, Dxgkrnl détermine si le remapping logique est nécessaire en comparant l’adresse physique la plus accessible de l’appareil à la mémoire installée sur le système. Si nécessaire, le remapping DMA est utilisé pour mapper une plage d’adresses logique qui se trouve dans les limites visibles du GPU à n’importe quelle mémoire physique sur le système. Par exemple, si le GPU a une limite de 1 To, Dxgkrnl alloue les adresses logiques de [0, 1 To) qui peuvent ensuite être mappées à n’importe quelle mémoire physique sur le système via l’IOMMU.

Cartes logiques et physiques

Dxgkrnl fait la distinction entre le concept d’adaptateur logique et physique. Un adaptateur physique représente un périphérique matériel individuel qui peut ou non être lié à d’autres appareils d’une chaîne LDA. Un adaptateur logique représente une ou plusieurs cartes physiques liées.

Un seul domaine DMA IOMMU est créé par adaptateur logique et attaché à toutes les cartes physiques liées. Ainsi, toutes les cartes physiques partagent le même domaine et la même vue de la mémoire physique.

Prise en charge des GPU intégrés et discrets

Étant donné que le remapping iommu DMA offre peu de valeur aux GPU intégrés qui, par définition, doivent déjà être conçus pour accéder à toute la mémoire physique du système, l’implémentation de la prise en charge sur les composants intégrés est facultative mais recommandée.

Les GPU discrets doivent prendre en charge le remapping IOMMU DMA, qui est une exigence pour la certification WDDM 3.0.

Modifications DDI

Les modifications DDI suivantes ont été apportées pour prendre en charge la réappapping de DMA IOMMU.

Fonctionnalités du pilote

Deux ensembles de majuscules de pilote sont nécessaires pour prendre en charge le remapping linéaire :

  • Le pilote doit informer Dxgkrnl de ses restrictions de mémoire physique ; c’est-à-dire à propos de son adresse physique visible la plus élevée via DXGKQAITYPE_PHYSICAL_MEMORY_CAPS et de sa structure DXGK_PHYSICAL_MEMORY_CAPS associée.
  • Le pilote doit indiquer sa prise en charge du remapping linéaire IOMMU via DXGKQAITYPE_IOMMU_CAPS et sa structure de DXGK_IOMMU_CAPS associée. En indiquant la prise en charge, le pilote indique que tous les DDIS décrits ultérieurement sont pris en charge et utilisés.

Ces deux majuscules doivent être fournies avant que Dxgkrnl ne démarre l’appareil via DXGKDDI_START_DEVICE afin que l’appareil puisse être créé et attaché à un domaine IOMMU avant d’accéder à toute mémoire. Le remapping linéaire ne peut être effectué que si l’appareil ne référence aucune mémoire physique existante.

Accès exclusif

L’attachement et le détachement de domaine IOMMU sont extrêmement rapides, mais ne sont pas atomiques actuellement. Cela signifie qu’une transaction émise via PCIe n’est pas garantie d’être correctement traduite lors de l’échange vers un domaine IOMMU avec différents mappages.

Pour gérer cette situation, à compter de Windows 10 version 1803 (WDDM 2.4), un KMD doit implémenter la paire DDI suivante pour que Dxgkrnl appelle :

Le pilote doit s’assurer que son matériel est silencieux chaque fois que l’appareil est basculé vers un nouveau domaine IOMMU. Autrement dit, le pilote doit s’assurer qu’il ne lit ni n’écrit dans la mémoire système à partir de l’appareil entre ces deux appels.

Entre ces deux appels, Dxgkrnl offre les garanties suivantes :

  • Le planificateur est suspendu. Toutes les charges de travail actives sont vidées et aucune nouvelle charge de travail n’est envoyée ou planifiée sur le matériel.
  • Aucun autre appel DDI n’est effectué.

Dans le cadre de ces appels, le pilote peut choisir de désactiver et de supprimer les interruptions (y compris les interruptions Vsync) pendant l’accès exclusif, même sans notification explicite du système d’exploitation.

Listes de descripteurs d’adresses

Pour prendre en charge les modes d’accès physique et logique et basculer entre les deux modes en toute transparence au moment de l’exécution, Dxgkrnl fournit une structure DXGK_ADL qui décrit une liste de descripteurs d’adresses (ADL). Cette structure de données est similaire à une mdl, mais décrit un tableau de pages qui peut être physique ou logique. Étant donné que ces pages peuvent être des pages logiques, les adresses décrites par un ADL ne peuvent pas être mappées à une adresse virtuelle pour un accès direct au processeur.

DXGK_OPERATION_MAP_APERTURE_SEGMENT2 opération pour DxgkddiBuildpagingbuffer

VidMm fournit le mode de mémoire tampon de pagination DXGK_OPERATION_MAP_APERTURE_SEGMENT2 pour le mappage de la mémoire au segment d’ouverture, car la version précédente utilise un MDL incompatible avec les adresses logiques. Le rappel DxgkddiBuildpagingbuffer des pilotes WDDM 3.0 qui prennent en charge le remapping d’adresses logiques reçoit des appels en mode DXGK_OPERATION_MAP_APERTURE_SEGMENT2 et ne reçoit plus d’appels vers le mode DXGK_OPERATION_MAP_APERTURE_SEGMENT d’origine .

Cette opération est nécessaire pour prendre en charge le remapping DMA logique. Il se comporte de la même manière que l’opération d’origine, mais fournit un DXGK_ADL au lieu d’un MDL.

typedef enum _DXGK_BUILDPAGINGBUFFER_OPERATION
{
#if (DXGKDDI_INTERFACE_VERSION >= DXGKDDI_INTERFACE_VERSION_WDDM2_9)
    DXGK_OPERATION_MAP_APERTURE_SEGMENT2 = 17,
#endif //  DXGKDDI_INTERFACE_VERSION
};

// struct _DXGKARG_BUILDPAGINGBUFFER:
struct
{
    HANDLE  hDevice;
    HANDLE  hAllocation;
    UINT    SegmentId;
    SIZE_T  OffsetInPages;
    SIZE_T  NumberOfPages;
    DXGK_ADL Adl;
    DXGK_MAPAPERTUREFLAGS Flags;
    ULONG   AdlOffset;
    PVOID   CpuVisibleAddress;
} MapApertureSegment2;

Pour accepter l’opération de DXGK_OPERATION_MAP_APERTURE_SEGMENT2 , le pilote doit indiquer la prise en charge des appels MapApertureSegment2 dans les majuscules de gestion de la mémoire :

typedef struct _DXGK_VIDMMCAPS {
  union {
    struct {
        ...
        UINT MapAperture2Supported : 1;
        ...
    }
    ...
} DXGK_VIDMMCAPS;

Les DXGK_VIDMMCAPS limites de gestion de la mémoire font partie de la structure de données DXGK_DRIVERCAPS . Le pilote ne peut pas utiliser la fonctionnalité de remapping DMA (autrement dit, le remapping d’adresses logiques) sans cette prise en charge activée.

Certains pilotes peuvent nécessiter l’accès du processeur à la mémoire lors d’un appel MapApertureSegment2 . Cette fonctionnalité est éventuellement fournie via un autre paramètre MapApertureSegment2.CpuVisibleAddress . Cette adresse est une adresse virtuelle en mode noyau qui est valide tant que l’allocation est mappée au segment d’ouverture. Autrement dit, cette adresse sera libérée immédiatement après l’appel DXGK_OPERATION_UNMAP_APERTURE_SEGMENT correspondant pour la même allocation.

Cette adresse n’étant peut-être pas requise pour toutes les allocations, un indicateur MapApertureCpuVisible a été ajouté aux indicateurs d’allocation pour indiquer quand il est nécessaire.

Si MapApertureCpuVisible n’est pas spécifié, MapApertureSegment2.CpuVisibleAddress a la valeur NULL pour les opérations DXGK_OPERATION_MAP_APERTURE_SEGMENT2 .

MapApertureCpuVisible fait partie de la fonctionnalité MapAperatureSegment2 de DxgkDdiBuildPagingBuffer. Le pilote doit donc définir DXGK_VIDMMCAPS MapAperature2Supported pour utiliser ce champ. Si MapAperature2Supported n’est pas défini, mais que le pilote spécifie MapApertureCpuVisible, l’appel à DxgkDdiCreateAllocation échoue.

En outre, pour recevoir l’opération de DXGK_OPERATION_MAP_APERTURE_SEGMENT2 , le pilote doit définir l’indicateur DXGK_ALLOCATIONINFOFLAGS_WDDM2_0 AccessedPhysical . Si AccessedPhysical n’est pas défini, toute allocation qui spécifie un segment d’ouverture dans son jeu de segments pris en charge est mise à niveau vers le segment de mémoire système implicite, qui ne reçoit pas d’appels MAP_APERTURE (car il n’existe aucune plage d’ouverture à mapper).

En résumé, pour recevoir correctement l’adresse processeur d’une allocation de mémoire système, le pilote doit définir les indicateurs/majuscules suivants :

  • DXGK_DRIVERCAPS ::MemoryManagementCaps.MapAperture2Supported = 1
  • DXGK_ALLOCATIONINFOFLAGS_WDDM2_0 ::MapApertureCpuVisible = 1
  • DXGK_ALLOCATIONINFOFLAGS_WDDM2_0 ::AccessedPhysical = 1

Pour les appels MapApertureSegment2 , l’ADL est toujours initialisé et passé comme contigu lorsque le mappage logique est activé. Le pilote doit case activée les indicateurs ADL pour déterminer si l’allocation est contiguë et se comporter en conséquence.

Services de gestion de la mémoire

Il existe trois exigences fondamentales pour les fonctions de gestion de la mémoire :

  1. Possibilité de gérer la mémoire physique. Cela peut inclure l’allocation de mémoire via des fonctions de mémoire non paginées telles que MmAllocatePagesforMdl ou MmAllocateContiguousMemory, et des fonctions de mémoire paginée telles que ZwCreateSection ou ZwAllocateVirtualMemory. La possibilité d’exprimer des plages d’espace d’E/S est également requise.

  2. Possibilité de mapper une adresse logique visible par GPU à partir de la mémoire physique. Cela fournirait à l’appelant une liste de pages logiques (tout comme le tableau PFN d’un MDL) auxquelles le GPU peut être programmé pour accéder. L’appel de ces fonctions garantit que les pages physiques sous-jacentes sont verrouillées et non paginables.

  3. Possibilité de mapper les adresses virtuelles du processeur à partir de la mémoire physique en mode utilisateur et en mode noyau, avec un type de cache spécifié (Mis en cache ou Écriture combinée).

Le tableau suivant répertorie les DDIS et les structures d’entrée associées introduites pour décrire l’allocation de mémoire physique et le mappage des vues logiques/virtuelles. Ces DDIs sont un ensemble mis à jour pour remplacer les rappels précédents fournis aux pilotes pour la gestion des mappages IOMMU (DxgkCbAllocatePagesforMdl, DxgkCbAllocateContiguousMemory, DxgkCbMapMdlToIoMmu). Pour les pilotes WDDM 3.0 qui prennent en charge le remapping logique, ces anciennes fonctions de rappel sont dépréciées et ne peuvent pas être utilisées. Le pilote doit plutôt utiliser les fonctions de rappel de gestion de la mémoire suivantes.

Les fonctions de rappel doivent être appelées à IRQL <= APC_LEVEL. À compter de WDDM 3.2, les pilotes qui appellent l’une de ces fonctions sont validés par rapport à cette exigence et vérifient les bogues si l’IRQL est DISPATCH_LEVEL ou supérieur.

Rappel Structure de rappel associée
DXGKCB_CREATEPHYSICALMEMORYOBJECT DXGKARGCB_CREATE_PHYSICAL_MEMORY_OBJECT
DXGKCB_DESTROYPHYSICALMEMORYOBJECT DXGKARGCB_DESTROY_PHYSICAL_MEMORY_OBJECT
DXGKCB_MAPPHYSICALMEMORY DXGKARGCB_MAP_PHYSICAL_MEMORY
DXGKCB_UNMAPPHYSICALMEMORY DXGKARGCB_UNMAP_PHYSICAL_MEMORY
DXGKCB_ALLOCATEADL DXGKARGCB_ALLOCATE_ADL
DXGKCB_FREEADL
DXGKCB_OPENPHYSICALMEMORYOBJECT DXGKARGCB_OPEN_PHYSICAL_MEMORY_OBJECT
DXGKCB_CLOSEPHYSICALMEMORYOBJECT DXGKARGCB_CLOSE_PHYSICAL_MEMORY_OBJECT

Modifications INF

Chaque type d’appareil pris en charge doit ajouter la clé et la valeur de Registre suivantes à la section appropriée du fichier INF :

[DMAr.reg]
; Add REG_DWORD 'DmaRemappingCompatible' with value of 3 
HKR,Parameters,DmaRemappingCompatible,0x00010001,```3

Cette valeur informe PnP que l’appareil prend en charge le remapping DMA. Dxgkrnl et hal se coordonnent ensuite pour déterminer le type de mode de mappage à utiliser (remapping, passthrough, etc.).

Bien que cette clé de Registre ait été présente sur les versions antérieures de Windows, la valeur « 3 » est unique à partir de Windows 10 version 1803 (WDDM 2.4) et est ignorée sur les versions plus anciennes qui ne la prennent pas en charge. Cela permet aux pilotes de définir cette clé dans l’INF et de ne pas se soucier des problèmes de compatibilité au niveau inférieur.