Partager via


Paravirtualisation GPU

Cet article décrit la paravirtualisation GPU dans WDDM. Cette fonctionnalité est disponible à partir de Windows 10, version 1803 (WDDM 2.4).

À propos de la virtualisation GPU

La virtualisation GPU est une fonctionnalité importante pour le client Windows et Windows Server. Il existe de nombreux scénarios qui nécessitent une utilisation efficace des ressources GPU dans une machine virtuelle.

Les scénarios de serveur (où le système d’exploitation hôte n’exécute pas d’applications utilisateur) incluent :

  • Virtualisation de bureau
  • Calcul (IA, ML, etc.)

Les scénarios clients (où le système d’exploitation hôte partage le GPU entre les machines virtuelles et les applications utilisateur) sont les suivants :

  • Développement et test d’applications graphiques (où les tests sont exécutés dans une machine virtuelle)
  • Exécution d’applications dans une machine virtuelle à des fins de sécurité
  • Exécution de Linux dans une machine virtuelle avec accélération GPU

Paravirtualisation GPU dans WDDM

La paravirtualisation (PV) fournit une interface aux machines virtuelles similaires à leur matériel sous-jacent. Dans PV, vous transférez explicitement le système d’exploitation invité avant d’installer une machine virtuelle, car un système d’exploitation invité non personnalisé ne peut pas s’exécuter sur un moniteur de machine virtuelle (VMM).

Avantages:

  • Plusieurs machines virtuelles partagent les ressources matérielles.
  • Quelques modifications doivent être apportées dans le code du pilote.

La figure suivante illustre différents composants impliqués dans la conception paravirtualisée de WDDM.

Diagramme montrant les composants impliqués dans la conception paravirtualisée.

Les runtimes D3D de la machine virtuelle invitée ne sont pas modifiés. Les interfaces avec le runtime en mode utilisateur et avec des thunks du noyau KMT restent identiques.

Les composants du pilote ne nécessitent pas de nombreuses modifications :

  • L’UMD dans la machine virtuelle invitée doit :

    • N’oubliez pas que les communications avec le pilote en mode noyau hôte (KMD) se produisent sur la limite de la machine virtuelle.
    • Utilisez les services Dxgkrnl ajoutés pour accéder aux paramètres du Registre.
  • Il n’y a pas de KMD dans l’invité, uniquement de l’UMD. Le KMD (Virtual Render Device) remplace le KMD. L’objectif de VRD est de faciliter le chargement de Dxgkrnl.

  • Il n’existe aucun gestionnaire de mémoire vidéo (VidMm) ou planificateur (VidSch) dans l’invité.

  • Dxgkrnl dans une machine virtuelle reçoit des appels de thunk et les transmet à la partition hôte via les canaux du bus de la machine virtuelle. Dxgkrnl dans l’invité crée également des objets locaux pour les allocations, les processus, les appareils et d’autres ressources, ce qui réduit le trafic avec l’hôte.

Appareil de rendu virtuel (VRD)

Lorsqu’un GPU paravirtualisé n’est pas présent dans une machine virtuelle, le Gestionnaire de périphériques de la machine virtuelle affiche l’adaptateur « Microsoft Hyper-V Video ». Cet adaptateur d’affichage uniquement est associé par défaut à l’adaptateur BasicRender pour le rendu.

Lorsque vous ajoutez un GPU paravirtualisé à une machine virtuelle, le Gestionnaire de périphériques de la machine virtuelle affiche deux adaptateurs :

  • Carte vidéo Microsoft Hyper-V ou adaptateur d'affichage à distance Microsoft
  • Pilote de rendu virtuel Microsoft (le nom réel correspond à celui de l’adaptateur GPU sur l’hôte)

Par défaut, le VRD est associé à l’adaptateur vidéo Hyper-V, de sorte que tout le rendu de l’interface utilisateur se produit avec l’adaptateur VRD.

Si vous rencontrez des problèmes de rendu, vous pouvez désactiver ce jumelage à l’aide de l'GpuVirtualizationFlags paramètre de Registre. Dans ce cas, l’adaptateur de rendu uniquement (VRD) est utilisé lorsqu’une application la sélectionne spécifiquement. Par exemple, certains exemples DirectX vous permettent de modifier l’appareil de rendu. Les runtimes Direct3D ajoutent une sortie d’affichage logique à la VRD lorsqu’une application décide de l’utiliser.

Lorsque vous ajoutez plusieurs GPU virtuels à la machine virtuelle, il peut y avoir plusieurs adaptateurs VRD dans l’invité. Toutefois, un seul d’entre eux peut être associé à l’adaptateur vidéo Hyper-V. Il n’existe aucun moyen de spécifier celui-ci ; le système d’exploitation choisit.

Conteneurs et machines virtuelles

La virtualisation GPU est prise en charge pour les machines virtuelles et les conteneurs. Les conteneurs sont des machines virtuelles légères, où les fichiers binaires du système d’exploitation hôte sont mappés à la machine virtuelle conteneur.

Pour plus d’informations sur les conteneurs, consultez Windows et conteneurs.

Sécuriser les machines virtuelles

Les limitations suivantes existent pour une machine virtuelle sécurisée :

  • Les appels d’échappement de pilote ne sont pas autorisés, sauf les échappements connus, qui sont utilisés avec l’indicateur DriverKnownEscape.
  • L’isolation IoMmu est activée. La création de machine virtuelle échoue si le pilote ne prend pas en charge l’isolation IoMmu.

Lorsque le mode sécurisé est activé :

Il existe des paramètres de Registre pour forcer le mode sécurisé ou désactiver l’isolation IoMmu pendant le développement. Pour plus d’informations, voir Paramètres du registre.

Accès à distance du bureau de la machine virtuelle/du conteneur

Vous pouvez mettre à distance le contenu d’un bureau sur une machine virtuelle à l’hôte à l’aide de deux méthodes :

  • adaptateur d’affichage Hyper-V
  • Communication à distance de session de terminal

Lorsque le RDP (bureau à distance) est utilisé pour se connecter à une machine virtuelle, c’est la communication à distance de session de terminal qui est utilisée.

Le gestionnaire Hyper-V utilise l’application VMConnect pour afficher un bureau de machine virtuelle. VMConnect fonctionne en deux modes :

  • Mode amélioré, qui utilise la communication à distance de session de terminal.
  • Mode de base, qui utilise l’adaptateur d’affichage Hyper-V.

Processus worker de machine virtuelle et mémoire de machine virtuelle

Lorsque vous lancez une machine virtuelle ou un conteneur, le système d’exploitation crée les processus suivants sur l’hôte :

  • Processus de travail de machine virtuelle (vmwp.exe)
  • Processus de mémoire de machine virtuelle (vmmem.exe)

vmwp contient différents pilotes de périphériques virtuels, notamment vrdumed.dll, le pilote pour les adaptateurs graphiques paravirtualisés.

L’espace d’adressage virtuel du processus vmmem sert de support pour l’espace d’E/S du vGPU dans l’invité. Lorsque l’invité accède à l’espace d’E/S, l’adresse physique qui en résulte est l’entrée à la traduction de deuxième niveau, qui utilise les tables de pages du processus vmmem.

Dans un environnement virtualisé, différents appels KMD DDI qui s’exécutent généralement dans le contexte d’un processus utilisateur sur l’hôte sont exécutés dans le contexte du processus vmmem lors de l’exécution d’une machine virtuelle.

Dxgkrnl crée un seul DXGPROCESS (et l’objet de processus KMD correspondant) pour ces processus, appelé processus de travail de machine virtuelle dans cet article. L’EPROCESS associé au processus Worker de la machine virtuelle DXG est vmmem.

Processus de machine virtuelle

Lorsqu’un DXGPROCESS est créé dans la machine virtuelle invitée, Dxgkrnl crée un objet DXGPROCESS correspondant sur l’hôte. Ce processus est appelé processus de machine virtuelle dans cet article. Le EPROCESS associé au DXGPROCESS est vmmem.

Toutes les opérations de rendu issues de la création d'une machine virtuelle ou d'une allocation de machine virtuelle sont effectuées dans le contexte du DXGPROCESS de cette machine virtuelle.

À des fins de débogage, Dxgkrnl informe le KMD sur le processus qui est soit un processus Worker de machine virtuelle, soit un processus de machine virtuelle dans DxgkDdiCreateProcess. À l’aide de ces informations, le pilote peut lier un processus de machine virtuelle au processus worker de la machine virtuelle. Ces informations permettent de déboguer dans les scénarios où plusieurs machines virtuelles sont en cours d’exécution.

Exigences du pilote

Un KMD qui prend en charge la paravirtualisation GPU doit définir la capacité DXGK_VIDMMCAPS::ParavirtualizationSupported.

Le pilote en mode utilisateur (UMD) ne doit pas utiliser de données contextuelles de processus dans les données du pilote privé (pointeurs, handle, etc.). Au lieu de cela, le KMD obtient les données privées dans l’hôte dans un contexte de processus différent.

L’UMD dans la machine virtuelle ne peut pas partager de mémoire avec le KMD dans l’hôte. Il doit utiliser les fonctions décrites dans Accès au registre à partir de l’UMD pour accéder au registre.

L’implémentation de paravirtualisation actuelle utilise le bus de machine virtuelle pour communiquer entre l’invité et l’hôte. La taille maximale du message est de 128 Ko. Actuellement, Dxgkrnl n’interrompt pas les messages pour les envoyer en blocs. Par conséquent, le pilote doit limiter la taille des données privées transmises avec la création d’objets. Par exemple, lorsque Pfnd3dddiAllocatecb est utilisé pour créer de nombreuses allocations, la taille totale du message inclut un en-tête, des données privées globales, ainsi que la taille des données privées par allocation multipliée par le nombre d’allocations. Ces informations doivent toutes s’adapter à un seul message.

Exécution d’applications en mode émulé plein écran

L’adaptateur d’affichage indirect doit être activé pour la communication à distance (il l’est par défaut). Pour le désactiver, procédez comme suit.

  • Démarrer la modification de la stratégie de groupe
  • Accédez à Configuration de l'ordinateur - Modèles d'administration>- Composants Windows>- Services Bureau à distance>- Hôte de session Bureau à distance>- Environnement de session à distance>
  • Ouvrez l’élément « Utiliser le pilote d’affichage graphique WDDM pour la connexion Bureau à distance »
  • Sélectionnez Désactiver et sélectionner OK
  • Redémarrer

La prise en charge de DXGI pour les applications en plein écran dans les machines virtuelles est activée par défaut. Pour le désactiver, utilisez StagingTool.exe /disable 19316777.

Les applications plein écran doivent s’exécuter en mode plein écran émulé.

Activez eFSE pour toutes les applications DXGI et définissez la version minimale de WDDM pour la transition de l’effet d’échange vers WDDM 2.0 :

  • D3DEnableFeature.exe /enable DXGI_eFSE_Enablement_Policy
  • D3DEnableFeature.exe /setvariant DXGI_eFSE_Enablement_Policy 7

eFSE est activé par défaut pour les applications D3D9.

DriverStore dans la machine virtuelle

Les fichiers binaires du pilote sur l’hôte se trouvent dans un magasin de pilotes %windir%\system32\drivers\DriverStore\FileRepository<DriverDirectory>.

Pour la paravirtualisation, les fichiers binaires de l’UMD dans une machine virtuelle doivent être dans %windir%\system32\drivers\HostDriverStore\FileRepository<DriverDirectory>.

L’hôte KMD rapporte les noms des DLL UMD qui ont le chemin d’accès complet au magasin de pilotes. Par exemple, c :\windows\system32\DriverStore\FileRepository\DriverSpecificDirectory\d3dumd.dll.

Lorsque la machine virtuelle demande un nom UMD, le nom est traduit en <VmSystemDrive>:\windows\system32\HostDriverStore\FileRepository\DriverSpecificDirectory\d3dumd.dll.

Host DriverStore pour conteneurs

Pour les conteneurs, Hyper-V mappe le répertoire complet du magasin de pilotes hôtes dans l’hôte à <%windir%\HostDriverStore dans le conteneur.

Host DriverStore pour les machines virtuelles complètes

Les fichiers du magasin de pilotes sont copiés sur la machine virtuelle lorsque l’adaptateur GPU virtuel démarre dans la machine virtuelle. Cette fonctionnalité est désactivée dans la version publiée du système d’exploitation.

La clé de Registre et les valeurs possibles suivantes contrôlent l’opération de copie. La clé n’existe pas par défaut.

DWORD RTL_REGISTRY_CONTROL\GraphicsDrivers\DriverStoreCopyMode
Valeur Description
0 Désactiver la copie du magasin de pilotes
1 Opération normale (activez la copie des fichiers du magasin de pilotes et ne remplacez pas les fichiers existants).
2 Activez la copie du magasin de pilotes et remplacez les fichiers existants.

Accès au Registre à partir de l’UMD

Les clés de Registre KMD existent sur l’hôte et ne sont pas reflétées sur la machine virtuelle. Par conséquent, l’UMD ne peut pas lire directement ces clés de Registre de pilotes. Le rappel pfnQueryAdapterInfoCb2 est ajouté à la structure D3DDDI_ADAPTERCALLBACKS du runtime D3D. L’UMD peut appeler pfnQueryAdapterInfoCb2 avec D3DDDICB_QUERYADAPTERINFO2 défini de la manière suivante pour lire certaines clés de registre :

  • D3DDDICB_QUERYADAPTERINFO2::QueryType défini sur D3DDDI_QUERYADAPTERTYPE_QUERYREGISTRY.
  • pPrivateDriverData pointe vers une mémoire tampon avec une structure D3DDDI_QUERYREGISTRY_INFO dans laquelle retourner les informations de Registre. L’UMD renseigne les membres suivants :
  • PrivateDriverDataSize est sizeof(D3DDDI_QUERYREGISTRY_INFO) plus la taille de la mémoire tampon pour la valeur de sortie dont la taille est dynamique.

L’UMD peut également appeler D3DKMTQueryAdapterInfo directement. Cet appel est utile pour l’UMD dans l’invité, car il est marshalé vers l’hôte et permet de traduire certains noms en espace de noms de l’invité.

D3DKMTQueryAdapterInfo est appelé avec D3DKMT_QUERYADAPTERINFO défini comme suit pour lire certaines clés de Registre :

  • Le Type est défini sur KMTQAITYPE_QUERYREGISTRY
  • pPrivateDriverData pointe vers une structure D3DKMT_ADAPTERREGISTRYINFO
  • PrivateDriverDataSize est sizeof(D3DKMT_ADAPTERREGISTRYINFO) plus la taille de la mémoire tampon pour la valeur de sortie dont la taille est dynamique.

Exemple 1 : Lecture d’une valeur à partir de la clé de service


WCHAR ValueName = L"EnableDebug";
    D3DDDI_QUERYREGISTRY_INFO Args = {};
    Args.QueryType = D3DDDI_QUERYREGISTRY_SERVICEKEY;
    Args.QueryFlags.TranslatePath = FALSE or TRUE;
    Args.ValueType = Supported registry value type;
    wcscpy_s(Args.ValueName, ARRAYSIZE(Args.ValueName), ValueName);

    D3DKMT_QUERYADAPTERINFO Args1 = {};
    Args1.hAdapter = hAdapter;
    Args1.Type = KMTQAITYPE_QUERYREGISTRY;
    Args1.pPrivateDriverData = &Args;
    Args1.PrivateDriverDataSize = sizeof(Args);
    NTSTATUS Status = D3DKMTQueryAdapterInfo(&Args1);
    if (NT_SUCCESS(Status) &&
        Args.Status == D3DDDI_QUERYREGISTRY_STATUS_SUCCESS)
    {
       if (ValueType == REG_SZ || ValueType == REG_EXPAND_SZ) {

wprintf(L"Value: \"%s\"\n", Args.OutputString);
       } else
       if (ValueType == REG_MULTI_SZ) {
          wprintf(L"Value: ");
          for (UINT i = 0; i < Args.OutputValueSize; i++) {
             if (Args.OutputString[i] == 0) {
                wprintf(L" ");
             } else {
                wprintf(L"%c", Args.OutputString[i]);
             }
          }
          wprintf(L"\n");
       } else
       if (ValueType == REG_DWORD) {
          wprintf(L"Value: %d\n", Args.OutputDword);
       } else
       if (ValueType == REG_QWORD) {
          wprintf(L"Value: 0x%I64x\n", Args.OutputQword);
       } else
       if (ValueType == REG_BINARY) {
          wprintf(L"Num bytes: %d\n", Args.OutputValueSize);

for (UINT i = 0; i < Args.OutputValueSize; i++) {
             wprintf(L"%d ", Args.OutputBinary[i]);
          }
          wprintf(L"\n");
       }
    }

Exemple 2 : lecture du chemin du magasin de pilotes

    D3DDDI_QUERYREGISTRY_INFO Args = {};
    Args.QueryType = D3DDDI_QUERYREGISTRY_DRIVERSTOREPATH;

    D3DKMT_QUERYADAPTERINFO Args1 = {};
    Args1.hAdapter = hAdapter;
    Args1.Type = KMTQAITYPE_QUERYREGISTRY;
    Args1.pPrivateDriverData = &Args;
    Args1.PrivateDriverDataSize = sizeof(Args);
    NTSTATUS Status = D3DKMTQueryAdapterInfo(&Args1);
    if (NT_SUCCESS(Status) &&
        Args.Status == D3DDDI_QUERYREGISTRY_STATUS_SUCCESS)
    {
        Args.OutputString holds the output NULL terminated string.
        Args.OutputValueSize holds the number of characters in the string
    }

Copie de fichiers dans %windir%\system32 et %windir%\syswow64 dans la machine virtuelle

Dans certains cas, les DLL en mode utilisateur du pilote doivent être présentes dans les répertoires %windir%\system32 et %windir%\syswow64.

Le système d’exploitation permet au pilote de spécifier des fichiers qui doivent être copiés depuis le magasin de pilotes de l’hôte vers %windir%\system32 ou %windir%\syswow64 dans l’invité.

Dans l’INF d’installation, le pilote peut définir plusieurs valeurs dans les sous-clés suivantes dans la clé de Registre de l’adaptateur graphique :

  1. CopyToVmOverwrite
  2. CopyToVmWhenNewer
  3. CopyToVmOverwriteWow64
  4. CopyToVmWhenNewerWow64

Les sous-clés CopyToVmOverwrite et CopyToVmWhenNewer sont utilisées pour copier des fichiers dans le répertoire %windir%\system32.

Les sous-clés CopyToVmOverwriteWow64 et CopyToVmWhenNewerWow64 sont utilisées pour copier des fichiers dans le répertoire %windir%\syswow64.

Les fichiers sous CopyToVmOverwrite et CopyToVmOverwriteWow64 remplacent toujours les fichiers de destination.

Les fichiers sous CopyToVmWhenNewer et CopyToVmWhenNewerWow64 remplacent les fichiers dans la destination uniquement si leur date de modification est plus récente. Les critères « plus récents » comparent deux éléments d’information :

  • FileVersion
  • LastWriteTime

Lorsque le fichier de destination se termine par le suffixe .dll ou .exe, fileVersion est utilisé comme valeur de comparaison la plus significative où la plus grande version est considérée comme « plus récente ». Lorsque le fichier de destination ne se termine pas par le suffixe .dll ou .exe ou que les deux FileVersion sont égaux, LastWriteTime est utilisé comme valeurs de comparaison les moins significatives où la date/heure ultérieure est considérée comme « plus récente ».

Chaque type de valeur sous une sous-clé doit être REG_MULTI_SZ ou REG_SZ. Si le type valeur est REG_MULTI_SZ, il doit y avoir un maximum de deux chaînes dans la valeur. Cette exigence signifie que chaque valeur définit une seule chaîne ou une paire de chaînes, où la deuxième chaîne peut être vide.

Le premier nom dans une paire est un chemin vers un fichier dans le magasin de pilotes. Le chemin est relatif à la racine du magasin de pilotes et peut contenir des sous-répertoires.

Le deuxième nom d’une paire est le nom du fichier tel qu’il doit apparaître dans le répertoire %windir%\system32 ou %windir%\syswow64. Le deuxième nom doit être uniquement le nom du fichier, et non pas le chemin d’accès. Si le deuxième nom est vide, le nom de fichier est le même que dans le magasin de pilotes (à l’exception des sous-répertoires).

Cette approche permet au pilote d’avoir des noms différents dans le magasin de pilotes hôte et dans l’invité.

Exemple 1

L’exemple suivant montre comment obtenir le système d’exploitation pour copier <DriverStorePath>\CopyToVm\softgpu1.dll dans %windir%\system32\softgpu2.dll.

INF [DDInstall] section
HKR,"softgpukmd\CopyToVmOverwrite",SoftGpuFiles,%REG_MULTI_SZ%,"CopyToVm\softgpu1.dll”, “softgpu2.dll”
The directive creates the registry key in the software (adapter) key:
"HKLM\SYSTEM\CurrentControlSet\Control\Class\{4d36e968-e325-11ce-bfc1-08002be10318}\<number>\CopyToVmOverwrite”, SoftGpuFiles = REG_MULTI_SZ, “CopyToVm\softgpu1.dll”, “softgpu2.dll"

Exemple 2

L’exemple suivant montre comment obtenir le système d’exploitation pour copier <DriverStorePath>\softgpu1.dll vers %windir%\system32\softgpu.dll et <DriverStorePath>\softgpu2.dll vers %windir%\system32\softgpu2.dll.

INF [DDInstall] section:
HKR,"CopyToVmOverwrite",SoftGpuFiles1,%REG_MULTI_SZ%,"softgpu1.dll”,”softgpu.dll"
HKR,"CopyToVmOverwrite",SoftGpuFiles2,%REG_SZ%, “softgpu2.dll"
The directive creates the registry key in the software (adapter) key:
“HKLM\SYSTEM\CurrentControlSet\Control\Class\{4d36e968-e325-11ce-bfc1-08002be10318}\<number>\CopyToVmOverwrite”,  SoftGpuFiles1 = REG_MULTI_SZ, “softgpu1.dll”, “softgpu.dll"

“HKLM\SYSTEM\CurrentControlSet\Control\Class\{4d36e968-e325-11ce-bfc1-08002be10318}\<number>\CopyToVmOverwrite”,  SoftGpuFiles2 = REG_SZ, “softgpu2.dll””

Exemple 3

L’exemple suivant montre comment obtenir le système d’exploitation pour copier <DriverStorePath>\Subdir1\Subdir2\softgpu2wow64.dll vers %windir%\syswow64\softgpu.dll et <DriverStorePath>\softgpu.dll vers %windir%\syswow64\softgpu2wow64.dll.

INF [DDInstall] section:
HKR,"CopyToVmOverwriteWow64",SoftGpuFiles,%REG_MULTI_SZ%,“Subdir1\Subdir2\softgpu2wow64.dll”,”softgpu.dll”.
The directive creates the registry key in the software (adapter) key:
“HKLM\SYSTEM\CurrentControlSet\Control\Class\{4d36e968-e325-11ce-bfc1-08002be10318}\<number>\CopyToVmOverwriteWow64”,  SoftGpuFiles = REG_MULTI_SZ, “Subdir1\Subdir2\softgpu2wow64.dll”,”softgpu.dll

Modifications apportées à DxgkDdiCreateProcess

La fonction DxgkDdiCreateProcess de KMD doit être mise à jour pour prendre en charge les processus de travailleurs de machines virtuelles ainsi que les processus de machines virtuelles. Les champs suivants sont ajoutés à la structure DXGKARG_CREATEPROCESS :

  • hKmdVmWorkerProcess
  • ProcessNameLength
  • pProcessName

Les indicateurs suivants sont ajoutés à DXGK_CREATEPROCESSFLAGS pour prendre en charge les processus de travail de machine virtuelle et les processus de machine virtuelle :

  • VirtualMachineProcess
  • VirtualMachineWorkerProcess

DxgkDdiSetVirtualMachineData

DxgkDdiSetVirtualMachineData est ajouté pour Dxgkrnl pour transmettre des informations sur une machine virtuelle au KMD.

Messages asynchrones du bus de la machine virtuelle vers l'hôte

Certains messages de Dxgkrnl dans le système d’exploitation invité vers l’hôte sont asynchrones. Cette approche améliore les performances des appels d’API Dxgkrnl à fréquence élevée dans l’invité. La surcharge de chaque message de bus de machine virtuelle synchrone sur l’hôte peut être élevée.

Les messages asynchrones sont les suivants :

Prise en charge du LDA dans GPU-PV

Le LDA (Adaptateur d’affichage lié) est pris en charge dans GPU-PV. Pour garantir une implémentation cohérente et prendre en charge le portage arrière possible de la prise en charge LDA vers les versions antérieures de Windows, le KMD doit vérifier la prise en charge de LDA dans GPU-PV en appelant DxgkCbIsFeatureEnabled(DXGK_FEATURE_LDA_GPUPV). La prise en charge est activée si la fonction réussit et renvoie Activé. Si le KMD n’appelle pas ce callback, Dxgkrnl suppose que le KMD ne supporte pas LDA dans GPU-PV.

Si le système d’exploitation prend en charge la fonctionnalité, il appartient au pilote d’activer LDA en mode utilisateur. Si le pilote active LDA en mode utilisateur, il doit le faire comme suit.

Temps d'exécution État du LDA
Environnement d'exécution pré-D3D12 Activez si DXGK_FEATURE_LDA_GPUPV est pris en charge et que le système d’exploitation invité est Windows 11, version 22H2 (WDDM 3.1) ou ultérieure.
Runtimes non DX (Windows) Activez si DXGK_FEATURE_LDA_GPUPV est pris en charge et que le système d’exploitation invité est Windows 11, version 22H2 (WDDM 3.1) ou ultérieure. Au lieu de vérifier la version du système d’exploitation, l’UMD peut appeler D3DKMTQueryAdapterInfo(KMTQAITYPE_PHYSICALADAPTERCOUNT) et activer LDA lorsqu’il retourne le nombre de cartes physiques supérieures à 1.
Runtime D3D12 (Windows) Activer. Consultez Définition de l’état du LDA pour le runtime D3D12.
Linux (runtime d3d12 et non-DX) Activez si DXGK_FEATURE_LDA_GPUPV est pris en charge.

Les pilotes compilés avec une version d’interface antérieure à DXGKDDI_INTERFACE_VERSION_WDDM3_0 ne procèdent pas à la vérification de DXGK_FEATURE_LDA_GPUPV. Ces pilotes peuvent toujours activer LDA pour les runtimes Linux.

Définition de l’état LDA pour le runtime D3D12

Lors de l’activation ou de la désactivation de LDA pour le runtime D3D12, l’UMD doit retourner les informations de mappage de nœud et de niveau correctes au runtime. Le flux de code est le suivant :

  • D3D12 obtient le plafond de D3D12_CROSS_NODE_SHARING_TIER à partir de l’UMD.

  • D3D12 obtient le nombre d’adaptateurs physiques à partir de Dxgkrnl en appelant D3DKMTQueryAdapterInfo(KMTQAITYPE_PHYSICALADAPTERCOUNT).

  • D3D12 appelle pfnQueryNodeMap(PhysicalAdapterCount, &map) pour obtenir le mappage des index de nœud logique aux nœuds physiques. Le nœud dans ce cas signifie un adaptateur physique. L’UMD doit définir l’indice de l’adaptateur physique réel dans la carte ou D3D12DDI_NODE_MAP_HIDE_NODE pour désactiver un nœud.

  • En fonction des résultats pfnQueryNodeMap, D3D12 calcule le nombre d’adaptateurs physiques effectifs en ne comptant pas les nœuds masqués.

  • Si l’état du niveau et le nombre d’adaptateurs physiques effectifs ne correspondent pas, D3D12 échoue à créer le périphérique. Une incompatibilité se produit quand :

    • Le niveau est D3D12DDI_CROSS_NODE_SHARING_TIER_NOT_SUPPORTED et le nombre d’adaptateurs est supérieur à 1.
    • Le niveau n’est pas D3D12DDI_CROSS_NODE_SHARING_TIER_NOT_SUPPORTED et le nombre d’adaptateurs est égal à 1.

Pour désactiver le LDA, l’UMD doit renvoyer le niveau D3D12DDI_CROSS_NODE_SHARING_TIER_NOT_SUPPORTED et conserver un seul adaptateur physique activé dans le mappage de nœuds.

D3DKMTQueryAdapterInfo(KMTQAITYPE_PHYSICALADAPTERCOUNT)

Une requête KMTQAITYPE_PHYSICALADAPTERCOUNT pour le nombre d’adaptateurs physiques retourne toujours le nombre correct d’adaptateurs physiques à l’invité :

  • Sur les invités antérieurs à Windows 11 version 22H2, il renvoie 1. Cette valeur est codée en dur dans le code invité. Elle pourrait changer à l’avenir si la prise en charge de LDA est transférée vers des versions antérieures du système d’exploitation.
  • Sur Windows 11, version 22H2 et versions ultérieures, elle retourne :

Lancement de la paravirtualisation

Activer la prise en charge de la virtualisation dans le BIOS (VT-d ou similaire). GPU-PV configuration est différente pour les machines virtuelles VMMS et les conteneurs.

Dans PowerShell (en tant qu’administrateur), activez l’exécution de script sur le serveur :

set-executionpolicy unrestricted

Configuration de la machine virtuelle VMMS

Configuration de l’hôte et de la machine virtuelle

La build du système d’exploitation dans la machine virtuelle peut être plus ancienne ou plus récente que la build du système d’exploitation dans l’hôte.

  1. Activez la fonctionnalité Hyper-V dans les rôles serveur ou la fonctionnalité de Hyper-V sur le client. Lorsque vous activez cette fonctionnalité sur le serveur, sélectionnez l’option permettant d’utiliser la carte réseau comme commutateur externe.

  2. (facultatif) Activer la signature test (bcdedit -définir TESTSIGNING ON)

  3. Redémarrer.

  4. Installez un pilote GPU qui prend en charge la para-virtualisation.

  5. (facultatif) Certains pilotes ne définissent pas le plafond ParavirtualizationSupported. Dans ce cas, ajoutez le registre suivant avant d’installer le pilote ou de désactiver/activer l’appareil une fois l’indicateur défini.

    DWORD HKLM\System\CurrentControlSet\Control\GraphicsDrivers\GpuVirtualizationFlags = 1   
    
  6. Pour vérifier si le système d’exploitation reconnaît le GPU paravirtualisé, exécutez la commande PowerShell suivante :

    Get-VMPartitionableGpu
    
    # Example output from running the command
    Name                    : \\?\PCI#VEN_10DE&DEV_1C02&SUBSYS_11C210DE&REV_A1#4&275d7527&0&0010#{064092b3-625e-43bf-9eb5-d
                              c845897dd59}\GPUPARAV
    ValidPartitionCounts    : {32}
    PartitionCount          : 32
    TotalVRAM               : 1,000,000,000
    AvailableVRAM           : 1,000,000,000
    MinPartitionVRAM        : 0
    MaxPartitionVRAM        : 1,000,000,000
    OptimalPartitionVRAM    : 1,000,000,000
    TotalEncode             : 18,446,744,073,709,551,615
    AvailableEncode         : 18,446,744,073,709,551,615
    MinPartitionEncode      : 0
    MaxPartitionEncode      : 18,446,744,073,709,551,615
    
    OptimalPartitionEncode  : 18446744073709551615
    TotalDecode             : 1000000000
    AvailableDecode         : 1000000000
    MinPartitionDecode      : 0
    MaxPartitionDecode      : 1000000000
    OptimalPartitionDecode  : 1000000000
    TotalCompute            : 1000000000
    AvailableCompute        : 1000000000
    MinPartitionCompute     : 0
    MaxPartitionCompute     : 1000000000
    OptimalPartitionCompute : 1000000000
    CimSession              : CimSession: .
    ComputerName            : MYCOMPUTER-TEST2
    IsDeleted               : False
    
  7. Exécutez les commandes suivantes dans PowerShell pour créer une machine virtuelle avec GPU. Une machine virtuelle nommée TEST est créée.

    $vm = “TEST“
    New-VM -VMName $vm -Generation 2
    Set-VM -GuestControlledCacheTypes $true -VMName $vm
    
  8. Définissez l’espace d’E/S pour la machine virtuelle. GPU-PV utilise l’espace d’E/S pour gérer les allocations visibles par le processeur. Au moins 8 Go d’espace d’E/S sont nécessaires.

    Set-VM -LowMemoryMappedIoSpace 1GB -VMName $vm
    Set-VM -HighMemoryMappedIoSpace 16GB -VMName $vm
    
  9. [facultatif] Par défaut, l’adresse de base de l’espace d’E/S mémoire élevée est définie sur (64 Go - 512 Mo). Sur les microprogrammes Haswell avec un adressage de mémoire physique 36 bits, l’adresse de fin de la région d’espace d’E/S doit être inférieure à 64 Go, de sorte que l’adresse de début doit être définie en conséquence. Le script suivant, nommé SetHighMmioBase.ps1, définit l’adresse de début sur 47 Go lors de l’exécution avec les paramètres suivants :

    SetHightMmioBase.ps1 “TEST” 48128
    
    # SetHighMmioBase.ps1
    
    param( [string]$VmName, $BaseInMB)
    
    function Get-WMIVM
    {
        [CmdletBinding()]
        param(
            [parameter(Mandatory=$true)]
            [ValidateNotNullOrEmpty()]
            [string]$VmName = ""
            )
    
        gwmi -namespace root\virtualization\v2 -query "select * from Msvm_ComputerSystem where ElementName = '$VmName'"
    }
    function Get-WMIVmSettingData
    {
        [CmdletBinding()]
        param(
            [parameter(Mandatory=$true)]
            [ValidateNotNullOrEmpty()]
            [string]$VmName = ""
            )
        $vm = Get-WMIVM $VmName
    
        return $vm.GetRelated ("Msvm_VirtualSystemSettingData","Msvm_SettingsDefineState",$null,$null, "SettingData", "ManagedElement", $false, $null)
    }
    
    Write-Host "Setting HighMmioGapBase to $BaseInMB for VmName $VmName"
    $vssd = Get-WMIVmSettingData $VmName
    $vmms = Get-WmiObject -Namespace "root\virtualization\v2" -Class Msvm_VirtualSystemManagementService
    $vssd.HighMmioGapBase = $BaseInMB
    $settingsText = $vssd.PSBase.GetText("CimDtd20")
    $ret=$vmms.ModifySystemSettings($settingsText).ReturnValue
    if ($ret -eq 0)
    {
       Write-Host "Successfully set" $vssd.HighMmioGapBase
    } else
    {
       Write-Host "Error $ret"
    }
    
  10. Ajoutez un GPU virtuel à la machine virtuelle et désactivez les points de contrôle.

    Add-VMGpuPartitionAdapter -VMName $vm
    Set-VM -CheckpointType Disabled -VMName $vm
    
  11. Pour vérifier que la machine virtuelle a un GPU paravirtualisé, exécutez la commande suivante :

    Get-VMGpuPartitionAdapter -VMName $vm in PowerShell. The output should show the adapter.
    
    
    # Example output from running the command
    
    MinPartitionVRAM        :
    MaxPartitionVRAM        :
    OptimalPartitionVRAM    :
    MinPartitionEncode      :
    MaxPartitionEncode      :
    OptimalPartitionEncode  :
    MinPartitionDecode      :
    MaxPartitionDecode      :
    OptimalPartitionDecode  :
    MinPartitionCompute     :
    MaxPartitionCompute     :
    OptimalPartitionCompute :
    Name                    : GPU Partition Settings
    Id                      : Microsoft:9ABB95E2-D12D-43C3-B840-6F4A9CFB217B\929890BC-BB33-4687-BC1A-F72A4F1B3B3F
    VMId                    : 9abb95e2-d12d-43c3-b840-6f4a9cfb217b
    VMName                  : TEST
    VMSnapshotId            : 00000000-0000-0000-0000-000000000000
    VMSnapshotName          :
    
    CimSession              : CimSession: .
    ComputerName            : MYCOMPUTER-TEST2
    IsDeleted               : False
    VMCheckpointId          : 00000000-0000-0000-0000-000000000000
    VMCheckpointName        :
    
  12. Copiez le VHDX de la même build cliente que celle que vous utilisez dans la machine virtuelle dans un répertoire hôte. Par exemple, d:\VM\os.vhdx.

  13. Ouvrez Hyper-V manager et modifiez les paramètres de machine virtuelle (sélectionnez machine virtuelle et sélectionnez Paramètres) :

    • Sécurité : décochez Activer le démarrage sécurisé.
    • Mémoire : vérifiez et activez la mémoire dynamique. Définissez la quantité de mémoire sur 1 024 Mo ou plus.
    • Processeur : définir le Nombre de processeurs virtuels à 2 ou 4.
    • Carte réseau : sélectionnez la carte réseau à utiliser avec la machine virtuelle dans la zone de liste déroulante. Si le débogage réseau est activé, veillez à choisir l'adaptateur de débogage réseau Microsoft NET.
    • Contrôleur SCSI - Disque dur - Ajouter - Disque dur virtuel - Parcourir - Sélectionner d:\VM\os.vhdx
  14. Le système d'exploitation copie les fichiers du magasin de pilotes hôtes vers le répertoire HostDriverStore de l'invité lorsque l'adaptateur y est initialisé.

    • Montez le disque VHDX de la machine virtuelle. Par exemple, sur le disque f:.
    • Dans la machine virtuelle montée, créez un répertoire nommé f :\%windir%\system32\HostDriverStore\FileRepository.
    • Répliquez les fichiers de pilotes à partir de %windir%\system32\DriverStore dans l’hôte vers la machine virtuelle. Il doit y avoir f :\%windir%\system32\HostDriverStore\FileRepository\YourDriverDirectory\* dans la machine virtuelle.
  15. Si le pilote doit accéder aux fichiers à partir de %windir%\system32 ou de %windir%\syswow64, copiez manuellement les fichiers sur la machine virtuelle.

  16. Activez la signature de test dans la machine virtuelle si les pilotes ne sont pas signés par Microsoft. Dans la fenêtre d’administration CMD, exécutez la commande suivante :

    bcdedit /store <VM drive>:\EFI\Microsoft\Boot\BCD -set {bootmgr} testsigning on
    

    Démonter le VHDX de la machine virtuelle.

  17. Démarrez la machine virtuelle.

  18. Connectez-vous à la machine virtuelle à l’aide de l’option Hyper-V manager Connect.

INTÉRIEUR DE MACHINE VIRTUELLE

Vérifiez qu’il existe un appareil de rendu virtuel dans le gestionnaire d’appareils de la machine virtuelle. Tout le rendu à l’intérieur de la machine virtuelle passe par le GPU virtuel.

Script PowerShell pour configurer une machine virtuelle

Le script PowerShell suivant est un exemple de configuration d’une machine virtuelle à partir de zéro. Modifiez-le en fonction de vos besoins.


Param(
   [string]$VMName,
   [string]$VHDPath,
   [string]$SwitchName,
   [switch]$CreateVm,
   [switch]$InitDebug,
   [switch]$CopyRegistry,
   [switch]$CopyDriverStore,
   [switch]$CreateSwitch,
   [switch]$AddGpu,
   [switch]$All
)

if($All)
{
   $CreateVm = $True
   $CreateInitDebug = $True
   $CopyRegistry = $True
   $CopyDriverStore = $True
   $CreateSwitch = $True
   $AddGpu = $True
   $InitDebug = $True
}

   $vm = $VMName

#
# Validate parameters
#
if ($CreateSwitch -or $CreateVM)
{
    if ($SwitchName -eq "")
    {
        write "SwitchName is not set"
        exit
    }
}

if ($AddGpu -or $CreateVM)
{
    if ($VMName -eq "")
    {
        write "VMName is not set"
        exit
    }
}

if ($InitDebug -or $CreateVM -or $CopyDriverStore -or $CopyRegistry)
{
    if ($VHDPath -eq "")
    {
        write "VHDPath is not set"
        exit
    }
}

enable-windowsoptionalfeature -FeatureName Microsoft-Hyper-V-All -online

#
# Create a network switch for the VM
#
if ($CreateSwitch)
{
    New-VMSwitch $SwitchName -NetAdapterName "Ethernet (Kernel Debugger)"
}

#
# Create a VM and assign VHD to it
#
if ($CreateVm)
{
   New-VM -VMName $vm -Generation 2
   Set-VM -GuestControlledCacheTypes $true -VMName $vm


Set-VM -LowMemoryMappedIoSpace 1Gb -VMName $vm
   Set-VM -HighMemoryMappedIoSpace 32GB -VMName $vm
   Set-VMProcessor -VMname $vm -count 4
   Set-VMMemory -VMName $vm -DynamicMemoryEnabled $true -MinimumBytes 1024MB -MaximumBytes 4096MB -StartupBytes 1024MB -Buffer 20
   Add-VMHardDiskDrive -VMName $vm -Path $VHDPath
   Connect-VMNetworkAdapter -VMName $vm -Name "Network Adapter" -SwitchName $SwitchName
   Set-VMFirmware -VMName $vm -EnableSecureBoot off
   Set-VMFirmware -VMName $vm -FirstBootDevice (Get-VMHardDiskDrive -VMName $vm)
}

#
# Enable debugger and testsiging
#
if ($InitDebug)

```powershell
{
   Mount-vhd $VHDPath
   Add-PartitionAccessPath  -DiskNumber (Get-DiskImage -ImagePath $VHDPath | Get-Disk).Number -PartitionNumber 1 -AssignDriveLetter
   $efidrive = (Get-DiskImage -ImagePath $VHDPath | Get-Disk | Get-Partition -PartitionNumber 1).DriveLetter
   bcdedit /store ${efidrive}:\EFI\Microsoft\Boot\BCD -set '{bootmgr}' testsigning on
   bcdedit /store ${efidrive}:\EFI\Microsoft\Boot\BCD -set '{default}' debug on
   bcdedit /store ${efidrive}:\EFI\Microsoft\Boot\BCD /dbgsettings net port:50052 key:a.b.c.d hostip:10.131.18.133
   Dismount-VHD $VHDPath
}

#

# Now boot the VM without vGPU to verify that it's initialized correctly
# If everything is OK, turn off the VM
#
if ($CreateVm)
{
   Write-Output "Boot the VM and turn it OFF after it's initialized"
   pause
}

#
# Add virtual GPU
#
if($AddGpu)
{
   Add-VMGpuPartitionAdapter -VMName $vm
   Get-VMGpuPartitionAdapter -VMName $vm
}

#
# Copy the driver store to the VM
#
if ($CopyDriverStore)
{
   Write "Copying driver store"
   Mount-vhd $VHDPath
   $drive = (Get-DiskImage -ImagePath $VHDPath | Get-Disk | Get-Partition -PartitionNumber 3).DriveLetter
   xcopy /s $Env:windir\system32\driverstore\* ${drive}:\windows\system32\hostdriverstore\


Dismount-VHD $VHDPath
}

#
# Export driver registry settings
#
if ($CopyRegistry)
{
   Write "Copying registry"
   Mount-vhd $VHDPath
   $drive = (Get-DiskImage -ImagePath $VHDPath | Get-Disk | Get-Partition -PartitionNumber 3).DriveLetter
   reg load HKLM\VMSettings ${drive}:\Windows\System32\config\SYSTEM
   reg copy "HKLM\System\CurrentControlSet\Control\Class\{4d36e968-e325-11ce-bfc1-08002be10318}\0000" "HKLM\VmSettings\CurrentControlSet\Control\Class\{4d36e968-e325-11ce-bfc1-08002be10318}\0000" /s /f
   reg unload "HKLM\VmSettings"
   Dismount-VHD $VHDPath
}

Débogage de la machine virtuelle

Configurez le débogueur de machine virtuelle de la même façon que le débogage réseau sur un ordinateur client normal.

Si la machine virtuelle ne démarre pas ou si vous voyez un écran noir :

  • Désactivez la machine virtuelle et supprimez le GPU virtuel de celui-ci à l’aide des commandes suivantes :

    $vm = “TEST“
    remove-VMGpuPartitionAdapter  -VMName $vm -AdapterId “<Id from Get-VMGpuPartitionAdapter>”
    

    Par exemple:

    remove-VMGpuPartitionAdapter  -VMName $vm -AdapterId “Microsoft:9ABB95E2-D12D-43C3-B840-6F4A9CFB217B\929890BC-BB33-4687-BC1A-F72A4F1B3B3F”
    
  • Démarrez la machine virtuelle. S’il démarre correctement, vérifiez que les fichiers du pilote sont copiés correctement dans le HostDriverStore dans la machine virtuelle.

  • Ajoutez un processeur virtuel à la machine virtuelle à l’aide de la commande Add-VMGpuPartitionAdapter.

  • Recommencez la machine virtuelle.

Pour plus d’informations, consultez Résolution des problèmes.

Configuration du conteneur

La différence entre les conteneurs (également appelés machines virtuelles système de calcul hôte (HCS) et la machine virtuelle complète est que les fichiers binaires du système d’exploitation et les fichiers de magasin de pilotes sont mappés au conteneur. Par conséquent, il n’est pas nécessaire de copier les fichiers du pilote dans le conteneur, sauf s’ils sont nécessaires dans le répertoire windows\system32.

Pour les conteneurs sécurisés :

  • Les échappements de pilote sont désactivés.
  • Le pilote doit prendre en charge l’isolation IOMMU pour pouvoir être utilisé à l’intérieur d’un conteneur sécurisé.

Lorsque vous mettez à jour le pilote sur l’hôte et démarrez ou arrêtez le GPU hôte, les modifications sont reflétées dans le conteneur.

Bac à sable Windows

Ce type de conteneur est utilisé pour essayer des applications à risque. L'image de bureau complète est transmise à distance vers l'hôte. Le pilote d’affichage indirect est utilisé pour la communication à distance. Graphics VAIL n’est pas utilisé, de sorte que l’apport de l’image de bureau à l’hôte est lent.

Le GPU virtuel est désactivé par défaut dans le bac à sable Windows. Pour l’activer, créez un fichier de configuration WSB (par exemple, config.wsb) et définissez l’option GPU virtuel. Démarrez le bac à sable en cliquant sur le fichier de configuration.

Exemple de fichier de configuration :

<Configuration>
    <VGpu>Enable</VGpu>
</Configuration>

Par défaut, le vGPU dans le conteneur a les fonctions d'échappement du pilote désactivées. Il existe une option de configuration permettant d’activer les échappements de pilotes. L’exemple de fichier WSB suivant active à la fois le vGPU dans le bac à sable et les échappées de pilote :

<Configuration>
    <VGpu>EnableVendorExtensions</VGpu>
</Configuration>

Le bac à sable Windows prend en charge l’adaptateur GPU enfichable à chaud.

Conteneur VAIL (Application Virtuelle Intégrée Localement)

Utilisez ce type de conteneur pour exécuter des applications Win32 à l’intérieur d’un hôte basé sur WINDOWS Core Operated System. L’image de chaque application du conteneur est transférée à distance à l'hôte. Graphics VAIL est activé pour distancer chaque chaîne d’échange d’application. Les échappements de pilotes sont activés.

Exigences courantes en matière de conteneur

La configuration requise pour l’ordinateur est la suivante :

  • Vtx et Vtd doivent être activés dans le BIOS (ou leurs équivalents : AMD-V, AMD-IOMMU).
  • Au moins 8 Go de RAM.
  • Plus de 5 Go d’espace disque système.

Configuration du débogage du noyau pour Windows Sandbox

Utilisation de CMDIAG

Un service de gestionnaire de conteneur (cmservice) contrôle les conteneurs isolés Hyper-V. CMDIAG.EXE est une application disponible lorsque vous installez des fonctionnalités Hyper-V et conteneurs. Il active le débogage en mode noyau pour les conteneurs, active la signature de test, et bien plus encore.

Le gestionnaire de conteneur prend en charge le débogage série et .NET.

Exécutez cmdiag.exe Debug pour afficher les options.

CMDIAG modifie les paramètres du débogueur dans l’image de base du conteneur. Il ne doit y avoir qu’une seule instance d’un conteneur en cours d’exécution lorsque le débogueur du noyau est activé.

Arrêtez le service HVSICS avant de modifier les paramètres du débogueur.


# Example 1:

C:\Windows\system32>sc stop hvsics
SERVICE_NAME: HVSICS
        TYPE               : 30  WIN32
        STATE              : 3  STOP_PENDING
                                (STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x1
        WAIT_HINT          : 0xbb8

C:\Windows\system32>cmdiag debug -on -Serial  -Force
Debugging successfully enabled. Connection string: -k com:pipe,port=\\.\pipe\debugpipe,reconnect -v

# Example 2:

C:\Windows\system32>cmdiag debug -on -net -port 51000 -key a.b.c.d -hostip 10.131.18.34

Exécution du débogueur sur un autre ordinateur

Lorsque vous utilisez le débogueur série, vous pouvez envisager de l’exécuter sur un autre ordinateur. Utilisez kdsrv.exe pour exécuter le débogueur sur un autre ordinateur. Pour plus d’informations, consultez Serveurs de connexion KD.

Pour désactiver les délais d’attente pendant le débogage du noyau, définissez les clés de Registre suivantes :

reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Virtualization\Containers\UtilityVm" /v BridgeTransactionTimeout /t REG_DWORD /d 0xffffffff /f
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Virtualization\Containers\UtilityVm" /v BridgeServerConnectTimeout /t REG_DWORD /d 0xffffffff /f
reg add "HKLM\SOFTWARE\Microsoft\HVSI" /f /v DisableResetContainer /t REG_DWORD /d 1
reg add "HKLM\SOFTWARE\Microsoft\HVSI" /f /v AppLaunchTimeoutInSeconds /t REG_DWORD /d 0x7fffffff
reg add "HKLM\Software\Microsoft\Terminal Server Client" /f /v ConnectionHealthMonitoringSupported /t REG_DWORD /d 0

reg add "HKLM\Software\Microsoft\Terminal Server Client" /f /v DisableUDPTransport /t REG_DWORD /d 1
reg add "HKEY_CURRENT_USER\Software\Microsoft\Terminal Server Client" /f /v ConnectionHealthMonitoringSupported /t REG_DWORD /d 0
reg add "HKEY_CURRENT_USER\Software\Microsoft\Terminal Server Client" /f /v DisableUDPTransport /t REG_DWORD /d 1

Configuration du débogueur de noyau pour le conteneur VAIL

  • Connectez-vous à l’hôte à l’aide de telnet. Vous pouvez obtenir l’adresse IP de l’hôte à partir des paramètres réseau dans le système d’exploitation hôte.
  • Utilisez cmdiag.exe pour configurer le débogueur.

Configuration du débogueur Hypervisor

bcdedit /hypervisorsettings NET port:50000 key:a.b.c.d hostip:1.1.1.1
bcdedit /set {hypervisorsettings} hypervisorbusparams 0.0.0 (if needed)
bcdedit /set hypervisordebug on
reboot host

Dépannage

Cette section fournit des informations sur la résolution des problèmes liés au GPU-PV.

Get-VMHostPartitionableGpu

Appelez Get-VMHostPartitionableGpu pour voir s’il existe un GPU virtualisé. Si la sortie est vide, il existe une erreur quelque part (le pilote n’a pas défini la limite de virtualisation, la virtualisation n’est pas activée, etc.).

Get-VMHostPartitionableGpu

# Example output from running the command

Name                    : \\?\PCI#VEN_10DE&DEV_1188&SUBSYS_095B10DE&REV_A1#6&cfd27c8&0&00400008#{064092b3-625e-43bf-9eb5-dc845897dd59}\PARAV
ValidPartitionCounts    : {32, 4}
PartitionCount          : 32
TotalVRAM               : 2,000,000
AvailableVRAM           : 1,800,000
MinPartitionVRAM        : 100,000
MaxPartitionVRAM        : 1,000,000
OptimalPartitionVRAM    : 1,000,000
TotalEncode             : 20
AvailableEncode         : 20
MinPartitionEncode      : 1
MaxPartitionEncode      : 5
OptimalPartitionEncode  : 4
TotalDecode             : 40
AvailableDecode         : 30
MinPartitionDecode      : 2


MaxPartitionDecode      : 20
OptimalPartitionDecode  : 15
TotalCompute            : 100
AvailableCompute        : 100
MinPartitionCompute     : 1
MaxPartitionCompute     : 50
OptimalPartitionCompute : 30
CimSession              : CimSession: .
ComputerName            : WIN-T3H0LVHJJ59
IsDeleted               : False

Utilisation d’événements ETW

Dxgkrnl dispose de canaux d’administration et opérationnels pour les événements ETW. Les événements sont affichés dans l’Observateur d’événements Windows : Journal des applications et services - Microsoft - Windows - Dxgkrnl.

L’Observateur d’événements a des événements provenant d’autres composants qui participent à la création d’une machine virtuelle avec GPU-PV (Hyper-V-Compute, Hyper-V-Worker, Hyper-V-VID, etc.).

Utilisation de Add-VMGpuPartitionAdapter

Lorsque vous utilisez Add-VMGpuPartitionAdapter, ne spécifiez pas de fonctionnalité (par exemple, décoder) si elle n’est pas nécessaire. N’utilisez pas 0 pour cette fonctionnalité.

Utilisation de Remove-VMGpuPartitionAdapter

Si une machine virtuelle ne parvient pas à démarrer ou a des problèmes de rendu, essayez de supprimer le GPU virtuel de la machine virtuelle à l’aide de Remove-VMGpuPartitionAdapter.

remove-VMGpuPartitionAdapter  -VMName $vm -AdapterId "Microsoft:9ABB95E2-D12D-43C3-B840-6F4A9CFB217B\929890BC-BB33-4687-BC1A-F72A4F1B3B3F"

Empêcher le démarrage de la machine virtuelle pendant le démarrage

set-vm -AutomaticStartAction Nothing -VmName TEST

Événements de l’observateur d’événements

Ajoutez des événements au canal de visionneuse d’événements pour identifier les problèmes liés au démarrage du processeur virtuel. Vous trouverez les événements dans « Journaux des applications et services\Microsoft\Windows\Dxgkrnl ». Les canaux d’événements sont Administration et Opérationnel.

Les événements sont émis lorsque :

  • Le vGPU est créé
  • Le processeur virtuel est détruit
  • L’invité ouvre un adaptateur virtuel

Les fichiers d’événements se trouvent dans :

  • c:\Windows\System32\winevt\Logs\Microsoft-Windows-DxgKrnl-Admin.evtx
  • c:\Windows\System32\winevt\Logs\Microsoft-Windows-DxgKrnl-Operational.evtx

Vérifiez si un processeur virtuel a été créé et si des erreurs ont été détectées.

Paramètres du Registre

GpuVirtualizationFlags

La clé de Registre GpuVirtualizationFlags est utilisée pour définir le comportement des GPU paravirtualized. La clé se trouve dans :

DWORD HKLM\System\CurrentControlSet\Control\GraphicsDrivers\GpuVirtualizationFlags

Les bits suivants sont définis :

bit Description
0x1 Forcez le plafond de ParavirtualizationSupported pour toutes les cartes matérielles. Utilisez ce bit dans l’hôte.
0x2 Forcez le plafond ParavirtualizationSupported pour BasicRender. Utilisez ce bit dans le système hôte.
0x4 Forcer le mode de machine virtuelle sécurisée, où toutes les machines virtuelles seront traitées comme sécurisées. Dans ce mode, il existe des restrictions sur le pilote en mode utilisateur. Par exemple, le conducteur ne peut pas utiliser les appels d'évasion, donc ils échoueront. Utilisez ce bit dans l’hôte.
0x8 Activez le jumelage d’adaptateurs paravirtualisés avec l’adaptateur d’affichage uniquement. Utilisez ce bit dans la machine virtuelle invitée. Le jumelage est activé par défaut.

GuestIoSpaceSizeInMb

La clé de Registre GuestIoSpaceSizeInMb est utilisée pour définir la taille de l’espace d’E/S invité pour les GPU virtuels, en mégaoctets. La valeur par défaut est de 1 000 Mo (1 Go). La clé se trouve à l’emplacement suivant :

DWORD HKLM\System\CurrentControlSet\Control\GraphicsDrivers\Paravirtualization\GuestIoSpaceSizeInMb

L’espace d’E/S invité implémente actuellement des allocations visibles par le processeur. Un magasin de stockage d’allocation visible par le processeur dans l’hôte est épinglé en mémoire et mappé à l’espace d’E/S invité. Dans l’invité, l’adresse virtuelle en mode utilisateur d’allocation est redirigée vers la région espace E/S. Sur certains systèmes Haswell, le processeur a des adresses physiques 36 bits. Hyper-V sur ces systèmes a une taille d’espace d’E/S limitée.

Désactiver l’isolation IOMMU pour les machines virtuelles sécurisées

Si un pilote ne prend pas en charge l’isolation IoMmu, utilisez le paramètre de registre suivant pendant le développement pour désactiver l’isolation IoMmu.

`DWORD HKLM\SYSTEM\CurrentControlSet\Control\GraphicsDrivers\IoMmuFlags = 8`

Limiter le nombre de fonctions virtuelles

Par défaut, le nombre de fonctions virtuelles exposées par un adaptateur prenant en charge la paravirtualisation GPU est 32. Ce nombre signifie que l’adaptateur peut être ajouté à 32 machines virtuelles, en supposant que chaque machine virtuelle a un adaptateur.

Vous pouvez utiliser le paramètre de Registre suivant pour limiter le nombre de fonctions virtuelles exposées.

DWORD HKLM\SYSTEM\CurrentControlSet\Control\GraphicsDrivers\NumVirtualFunctions

Par exemple, si vous définissez NumVirtualFunctions sur 1, l’adaptateur ne peut être ajouté qu’à un seul GPU une seule fois. Ce paramètre est utile lorsqu’un ordinateur a plusieurs adaptateurs GPU qui prennent en charge GPU-PV et que vous souhaitez affecter chaque adaptateur à une machine virtuelle. Add-VMGpuPartitionAdapter ne vous permet pas de spécifier l’adaptateur à ajouter. Par conséquent, si deux adaptateurs sont ajoutés à une machine virtuelle, les deux pourraient obtenir le même adaptateur GPU-PV à partir de l’hôte.

Mises à jour WDDM/DDI 2.4

Les mises à jour DDI suivantes sont apportées pour prendre en charge la paravirtualisation GPU dans WDDM 2.4.

Ajout du plafond DXGK_VIDMMCAPS

La fonctionnalité ParavirtualizationSupported est ajoutée à la structure DXGK_VIDMMCAPS. Le kmD hôte définit cette limite s’il implémente toutes les DDIS décrites dans cette section.

Données privées du pilote passées via DDI

L’UMD utilise différentes DDIS pour échanger des informations privées avec son KMD correspondant. Lorsque l’UMD s’exécute dans la machine virtuelle invitée, l’appel DDI KMD correspondant se produit dans la partition hôte. Par conséquent, l’UMD :

  1. Ne peut pas transmettre des pointeurs dans les données privées.
  2. Ne peut pas gérer des handlers dans les données privées.
  3. Ne doit pas indiquer au KMD d’apporter des modifications globales de l’état du GPU, car cette modification peut affecter d’autres machines virtuelles en cours d’exécution.

Ajout de l’indicateur VirtualMachineProcess pour DxgkDdiCreateProcess

Le système d’exploitation crée un processus de travail de machine virtuelle pour chaque machine virtuelle en cours d’exécution. Dxgkrnl crée un DXGPROCESS correspondant et appelle DxgkDdiCreateProcess avec l’indicateur VirtualMachineWorkerProcess. Il n’y a pas de rendu ni de création de ressource pilote dans ce contexte de processus. Par conséquent, le pilote peut ignorer l’allocation de certaines ressources.

Le système d’exploitation crée un DXGPROCESS dans l’hôte pour chaque processus d’une machine virtuelle invitée qui utilise un GPU. Dxgkrnl appelle DxgkDdiCreateProcess avec l’indicateur VirtualMachineProcess défini. Chaque processus DXG de machine virtuelle appartient au même processus EPROCESS que le processus de travail de machine virtuelle.

Mises à jour de DxgkDdiQueryAdapterInfo

La structure DXGKARG_QUERYADAPTERINFO est mise à jour pour inclure les champs suivants pour la prise en charge de la paravirtualisation :

  • Le membre Flags est ajouté, ce qui permet à Dxgkrnl d’indiquer ce qui suit :

    • Il définit VirtualMachineData pour indiquer que l’appel provient d’une machine virtuelle.
    • Il définit SecureVirtualMachine pour indiquer que la machine virtuelle s’exécute en mode sécurisé.
  • hKmdProcessHandle est ajouté, ce qui permet au pilote d’identifier et d’utiliser le contexte de processus correct côté hôte lors du traitement des requêtes provenant d’une machine virtuelle invitée.

Mises à jour de DxgkDdiEscape

Le membre hKmdProcessHandle est ajouté à la structure DXGKARG_ESCAPE pour permettre au pilote d’identifier et d’utiliser le contexte de processus correct côté hôte lors de la gestion des échappements provenant d’une machine virtuelle invitée.

L’indicateur VirtualMachineData est ajouté à la structure D3DDDI_ESCAPEFLAGS pour indiquer que DxgkDdiEscape est appelé à partir d’une machine virtuelle.

Accès physique aux allocations GPU

Actuellement, le pilote n’implémente pas l’accès physique aux allocations. Le pilote doit prendre en charge GpuMmu.

Mises à jour WDDM/DDI 2.5

Pour WDDM 2.5, les modifications DDI suivantes sont également requises pour la prise en charge de la paravirtualisation.

Annonce d'événements invités par l'hôte KMD

Il existe des scénarios sans virtualisation lorsque le KMD doit signaler un événement créé par une UMD. Pour gérer ces scénarios lorsque la paravirtualisation est utilisée, le KMD sur l’hôte doit signaler un événement créé dans l’invité. Le rappel DxgkCbSignalEvent est ajouté à cet effet. KMD peut également utiliser ce rappel pour signaler les événements des processus hôtes.

Prise en charge des handles fournis par l’UMD dans une machine virtuelle

Certains rappels de pilotes acceptent une allocation ou un handle de ressources Dxgkrnl que transmet l’UMD, par exemple :

Les appels sur l’hôte doivent se trouver dans le contexte du même thread qui a appelé une fonction DxgkDdiXxx.

Par exemple, supposons que, sans virtualisation, le KMD appelle DxgkCbAcquireHandleData dans le contexte du thread en mode utilisateur qui appelle D3DKMTEscape , qui appelle DxgkDdiEscape.

Quand l’UMD s’exécute sur une machine virtuelle, il connaît uniquement les handles d’allocation d’invité et ne peut pas transmettre ces handles à KMD, car KMD s’exécute sur le système hôte. L’UMD dans l’invité appelle D3DKMTEscape et KMD dans l’hôte reçoit l’appel DxgkDdiEscape correspondant. KMD doit appeler DxgkCbAcquireHandleData dans le contexte de ce thread.

Pour pouvoir traduire le handle d’allocation/de ressource invité vers le handle hôte correspondant, on ajoute l’indicateur d’échappée du pilote D3DDDI_ESCAPEFLAGS::DriverKnownEscape.

Lorsque vous appelez D3DKMTEscape avec l’indicateur DriverKnownEscape défini :

  • Définir D3DKMT_ESCAPE::Type sur D3DKMT_ESCAPE_DRIVERPRIVATE.

  • Définissez D3DKMT_ESCAPE ::p PrivateDriverData pour pointer vers une structure d’échappement de pilote connue, définie dans la section suivante. Chaque structure commence par une valeur D3DDDI_DRIVERESCAPETYPE.

Lorsque la virtualisation n’est pas utilisée, le handle traduit est identique au handle d’entrée.

Les échappées de pilotes connus suivants sont définis.

L’extrait de code suivant montre comment utiliser l’indicateur DriverKnownEscape.

D3DDDI_DRIVERESCAPE_TRANSLATEALLOCATIONEHANDLE Command = {};
    Command.EscapeType = D3DDDI_DRIVERESCAPETYPE_TRANSLATEALLOCATIONHANDLE;
    Command.hAllocation = hAlloc;
    D3DKMT_ESCAPE Args = {};
    Args.hAdapter = hAdapter;
    Args.Flags.DriverKnownEscape = TRUE;
    Args.Type = D3DKMT_ESCAPE_DRIVERPRIVATE;
    Args.pPrivateDriverData = &Command;
    Args.PrivateDriverDataSize = sizeof(Command);
    Status = D3DKMTEscape(&Args);

Mises à jour WDDM/DDI 2.6

À partir de WDDM 2.6 (Windows 10, version 1903), les mises à jour suivantes ont été apportées pour la prise en charge de la paravirtualisation :

  • Le pilote peut utiliser l’indicateur DXGK_ALLOCATIONINFOFLAGS::ACCESSEDPHYSICALLY dans une machine virtuelle. Avant WDDM 2.6, le pilote n’a pas pu utiliser cet indicateur dans une machine virtuelle et la création d’allocation avec cet indicateur a échoué.

  • UMD peut utiliser Pfnd3dkmtUpdateallocationproperty dans une machine virtuelle. Avant WDDM 2.6, cet appel échouerait.