Partager via


Remappage DMA IOMMU

Cette page décrit la fonctionnalité de remapping IOMMU DMA (IOMMUv2) qui a été introduite dans Windows 11 22H2 (WDDM 3.0). Consultez l’isolation GPU basée sur IOMMU pour plus d’informations sur l’isolation du GPU IOMMU avant WDDM 3.0.

Aperçu

Jusqu’à WDDM 3.0, Dxgkrnl n’a pris en charge que l’isolation IOMMU via le remapping physique 1:1, ce qui signifie que les pages logiques accessibles par le GPU ont été traduites vers le même numéro de page physique. Le remapping DMA IOMMU 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 peut fournir des plages d’adresses contiguës logiquement.

Dxgkrnl impose une restriction sur les GPU : les GPU doivent être en mesure d’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 traverse la limitation courante de l’espace d’adressage 40 bits de nombreux GPU. Le remappage 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. S’il est 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 des 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.

Adaptateurs logiques et physiques

Dxgkrnl distingue le concept d’un adaptateur logique et physique. Une carte physique représente un périphérique matériel individuel qui peut être lié à d’autres appareils d’une chaîne LDA. Un adaptateur logique représente un ou plusieurs adaptateurs physiques liés.

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

Prise en charge intégrée et discrète du GPU

Étant donné que le remapping DMA IOMMU offre peu de valeur aux GPU intégrés qui doivent, par définition, être déjà conçus pour accéder à toutes les mémoires physiques dans le 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, ce qui est une exigence pour la certification WDDM 3.0.

Modifications DDI

Les modifications DDI suivantes ont été apportées pour prendre en charge le re-mappage d’IOMMU DMA.

Fonctionnalités du pilote

Deux ensembles de bouchons de conducteur sont nécessaires pour prendre en charge le remapping linéaire.

  • Le pilote doit informer Dxgkrnl de ses restrictions de mémoire physique ; autrement dit, à propos de son adresse physique visible la plus élevée via DXGKQAITYPE_PHYSICAL_MEMORY_CAPS et sa structure de DXGK_PHYSICAL_MEMORY_CAPS associée.
  • Le pilote doit indiquer son support pour le remappage linéaire de l'IOMMU via DXGKQAITYPE_IOMMU_CAPS et sa structure associée DXGK_IOMMU_CAPS. En indiquant la prise en charge, le pilote indique que toutes les DDIS décrites ultérieurement sont prises en charge et utilisées.

Ces deux capacités 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 que l’accès à la mémoire soit possible. Le remapping linéaire ne peut être effectué que si l’appareil ne fait référence à aucune mémoire physique existante.

Accès exclusif

L’attachement et le détachement du domaine IOMMU sont extrêmement rapides, mais n’est néanmoins pas atomique. Cette condition signifie qu’une transaction émise sur PCIe n’est pas garantie d’être traduite correctement lors de l’échange vers un domaine IOMMU avec différents mappages.

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

Le pilote doit s’assurer que son matériel est inactif chaque fois que le périphérique est basculé vers un nouveau domaine IOMMU. C’est-à-dire que le pilote doit s’assurer qu’il ne lit ni n’écrit dans la mémoire système depuis le périphérique entre ces deux appels.

Entre ces deux appels, Dxgkrnl garantit les éléments suivants :

  • 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’adresse (ADL). Cette structure de données est similaire à un MDL, mais décrit un tableau de pages qui peuvent être physiques ou logiques. É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 l’accès direct au processeur.

Opération DXGK_OPERATION_MAP_APERTURE_SEGMENT2 pour DxgkddiBuildPagingBuffer

VidMm fournit le mode de buffer de pagination DXGK_OPERATION_MAP_APERTURE_SEGMENT2 pour mapper la mémoire au segment d'aperture, 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 re-mappage d’adresses logiques reçoit des appels au mode DXGK_OPERATION_MAP_APERTURE_SEGMENT2 et ne reçoit plus d’appels au 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 façon que l’opération d’origine, mais fournit une 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 opter pour l’opération DXGK_OPERATION_MAP_APERTURE_SEGMENT2, le pilote doit indiquer la prise en charge des appels MapApertureSegment2 dans les capacités de gestion de la mémoire :

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

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

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

Cette adresse peut ne pas être requise pour toutes les allocations. L’indicateur MapApertureCpuVisible a été ajouté aux indicateurs d’allocation pour indiquer quand cette adresse est requise.

Si MapApertureCpuVisible n’est pas spécifié, MapApertureSegment2.CpuVisibleAddress a la valeur NULL pour les opérations de 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.

De plus, pour recevoir l’opération DXGK_OPERATION_MAP_APERTURE_SEGMENT2, le pilote doit définir l’indicateur DXGK_ALLOCATIONINFOFLAGS_WDDM2_0 AccessedPhysically. 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’y a pas de plages 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/limites suivants :

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

Pour les appels MapApertureSegment2 , adL est toujours initialisé et transmis comme contigu lorsque le mappage logique est activé. Le pilote doit vérifier 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. Capacité à gérer la mémoire physique. Cette fonctionnalité 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ées telles que ZwCreateSection ou ZwAllocateVirtualMemory. La possibilité d’exprimer des plages d’espace d’E/S est également nécessaire.

  2. Possibilité de mapper une adresse logique visible par GPU à partir de la mémoire physique. Cette fonctionnalité fournirait à l’appelant une liste de pages logiques (tout comme le tableau PFN d’un MDL) que 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 noyau, avec un type de cache spécifié (cache vs é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 actualisé 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 fonctions de rappel plus anciennes sont déconseillé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 callback doivent être appelées à un IRQL <= APC_LEVEL. À partir de WDDM 3.2, les pilotes qui appellent l'une de ces fonctions sont validés par rapport à cette exigence et provoquent un bugcheck si l'IRQL est à DISPATCH_LEVEL ou supérieur.

Rappel Structure de callback 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é de Registre et la valeur suivantes à la section appropriée de l’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 soit 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 builds plus anciennes qui ne le prennent pas en charge. Cette valeur unique permet aux pilotes de définir cette clé dans l’INF et de ne pas s’inquiéter des problèmes de compatibilité de bas niveau.