Condividi tramite


Paravirtualizzazione GPU

Questo articolo descrive la paravirtualizzazione GPU in WDDM. Questa funzionalità è disponibile a partire da Windows 10 versione 1803 (WDDM 2.4).

Informazioni sulla virtualizzazione GPU

La virtualizzazione GPU è una funzionalità importante sia per Client Windows che per Windows Server. Esistono molti scenari che richiedono un utilizzo efficace delle risorse GPU in una macchina virtuale.

Gli scenari del server (in cui il sistema operativo host non esegue applicazioni utente) includono:

  • Virtualizzazione desktop
  • Calcolo (intelligenza artificiale, Machine Learning e così via)

Gli scenari client (in cui il sistema operativo host condivide la GPU tra macchine virtuali e applicazioni utente) includono:

  • Sviluppo e test di applicazioni grafiche (in cui viene eseguito il test in una macchina virtuale)
  • Esecuzione di applicazioni in una macchina virtuale per scopi di sicurezza
  • Esecuzione di Linux in una macchina virtuale con accelerazione GPU

Paravirtualizzazione della GPU in WDDM

La paravirtualizzazione (PV) fornisce un'interfaccia alle macchine virtuali (VM) simili all'hardware sottostante. In PV, il sistema operativo guest viene portato in modo esplicito prima di installare una macchina virtuale perché un sistema operativo guest non personalizzato non può essere eseguito su un monitor di macchine virtuali (VMM).

Vantaggi:

  • Più macchine virtuali condividono le risorse hardware.
  • Nel codice del driver devono essere apportate alcune modifiche.

La figura seguente illustra vari componenti coinvolti nella progettazione paravirtualizzata di WDDM.

Diagramma che mostra i componenti coinvolti nella progettazione paravirtualizzata.

I runtime D3D nella macchina virtuale guest non vengono modificati. Le interfacce con il runtime modalità utente e con KMT kernel thunks rimangono invariate.

I componenti driver non richiedono molte modifiche:

  • L'UMD nella macchina virtuale guest deve:

    • Tenere presente che le comunicazioni con il driver in modalità kernel host (KMD) si verificano oltre il limite della macchina virtuale.
    • Usare i servizi dxgkrnl aggiunti per accedere alle impostazioni del Registro di sistema.
  • Non c'è alcun kmD nel guest, solo UMD. Il KMD (Virtual Render Device) sostituisce il KMD. Lo scopo di VRD è facilitare il caricamento di Dxgkrnl.

  • Non esiste alcun gestore di memoria video (VidMm) o un'utilità di pianificazione (VidSch) nel guest.

  • Dxgkrnl in una macchina virtuale riceve chiamate di thunk e le trasferisce alla partizione host eseguendo il marshalling di queste attraverso i canali del bus della macchina virtuale. Dxgkrnl nell'ospite crea inoltre oggetti locali per allocazioni, processi, dispositivi e altre risorse, riducendo così il traffico con l'host.

Dispositivo di rendering virtuale (VRD)

Quando una GPU paravirtualizzata non è presente in una macchina virtuale, Gestione dispositivi della macchina virtuale mostra la scheda "Microsoft Hyper-V Video". Questa scheda di sola visualizzazione è associata per impostazione predefinita all'adattatore BasicRender per il rendering.

Quando si aggiunge una GPU paravirtualizzata a una macchina virtuale, il Gestione dispositivi della macchina virtuale mostra due adattatori.

  • Adattatore video Microsoft Hyper-V o Adattatore di visualizzazione remota Microsoft
  • Driver di rendering virtuale Microsoft (il nome effettivo è il nome dell'adattatore GPU nell'host)

Per impostazione predefinita, il VRD è associato alla scheda video Hyper-V, quindi tutto il rendering dell'interfaccia utente viene eseguito con la scheda VRD.

Se si verificano problemi di rendering, è possibile disabilitare questa associazione usando l'impostazione GpuVirtualizationFlags registro di sistema. In questo caso, l'adattatore VRD (Render-Only Adapter) viene usato quando un'applicazione lo seleziona in modo specifico. Ad esempio, alcuni esempi DirectX consentono di modificare il dispositivo di rendering. I runtime Direct3D aggiungono un output di visualizzazione logico al VRD quando un'applicazione decide di usarlo.

Quando si aggiungono più GPU virtuali alla macchina virtuale, nel guest possono essere presenti più schede VRD. Tuttavia, solo uno di essi può essere associato alla scheda video Hyper-V. Non c'è modo di specificare quale; il sistema operativo sceglie.

Contenitori e macchine virtuali

La virtualizzazione GPU è supportata per macchine virtuali e contenitori. I contenitori sono macchine virtuali leggere, in cui i file binari del sistema operativo host vengono mappati alla macchina virtuale del contenitore.

Per altre informazioni sui contenitori, vedere Windows e contenitori.

Macchine virtuali sicure

Esistono le limitazioni seguenti per una macchina virtuale sicura:

  • Le chiamate di escape del driver non sono consentite, ad eccezione dei escape noti, usati con il flag DriverKnownEscape.
  • L'isolamento IoMmu è abilitato. La creazione della macchina virtuale non riesce se il driver non supporta l'isolamento IoMmu.

Quando la modalità protetta è abilitata:

Sono disponibili impostazioni del Registro di sistema per forzare la modalità protetta o disabilitare l'isolamento IoMmu durante lo sviluppo. Per altre informazioni, vedere impostazioni del Registro di sistema.

Accesso remoto al desktop della macchina virtuale/del contenitore

È possibile accedere a distanza al contenuto di un desktop in una macchina virtuale (VM) verso l'host usando due metodi:

  • scheda di visualizzazione Hyper-V
  • Gestione remota della sessione del terminale

Quando si usa RDP (Desktop remoto) per connettersi a una macchina virtuale, viene usata la comunicazione remota della sessione del terminale.

Il gestore Hyper-V utilizza l'applicazione VMConnect per visualizzare un desktop di una macchina virtuale. VMConnect funziona in due modalità:

  • Modalità avanzata, che utilizza la remotizzazione della sessione del terminale.
  • Modalità di base, che usa l'adattatore di visualizzazione Hyper-V.

Processo di lavoro della macchina virtuale e memoria della macchina virtuale

Quando si avvia una macchina virtuale o un contenitore, il sistema operativo crea i processi seguenti nell'host:

  • Processo di lavoro della macchina virtuale (vmwp.exe)
  • Processo di memoria della macchina virtuale (vmmem.exe)

Vmwp contiene vari driver di dispositivi virtuali, tra cui vrdumed.dll, il driver per le schede grafiche paravirtualizzate.

Lo spazio degli indirizzi virtuali del processo vmmem serve come supporto per lo spazio di I/O della vGPU nella macchina virtuale. Quando il guest accede allo spazio di I/O, l'indirizzo fisico risultante è la voce alla conversione di secondo livello, che usa le tabelle di pagina del processo di vmmem.

In un ambiente virtualizzato, varie chiamate KMD DDI che tipicamente vengono eseguite nel contesto di un processo utente sull'host vengono invece eseguite nel contesto del processo vmmem quando è in esecuzione una macchina virtuale.

Dxgkrnl crea un singolo oggetto DXGPROCESS (e l'oggetto processo KMD corrispondente) per questi processi, chiamato in questo articolo processo di lavoro della macchina virtuale . L'EPROCESS associato al processo di lavoro della macchina virtuale DXG è vmmem.

Processi di macchina virtuale

Quando viene creato un DXGPROCESS nella macchina virtuale guest, Dxgkrnl crea un oggetto DXGPROCESS corrispondente nell'host. Questo processo è denominato processo macchina virtuale in questo articolo. L'EPROCESS associato a DXGPROCESS è vmmem.

Tutte le operazioni di rendering da una macchina virtuale o dalla creazione dell'allocazione di una macchina virtuale vengono eseguite nel contesto del DXGPROCESS associato alla macchina virtuale.

Ai fini del debug, Dxgkrnl notifica al KMD quale processo è un processo di lavoro della macchina virtuale o un processo di macchina virtuale in DxgkDdiCreateProcess. Usando queste informazioni, il driver può collegare un processo di macchina virtuale al processo di lavoro della macchina virtuale. Queste informazioni consentono di eseguire il debug in scenari in cui sono in esecuzione più macchine virtuali.

Requisiti del driver

Un KMD che supporta la paravirtualizzazione GPU deve impostare la funzionalità DXGK_VIDMMCAPS::ParavirtualizationSupported.

Il driver in modalità utente (UMD) non deve usare dati correlati al contesto del processo nei dati del driver privato (puntatori, handle e così via). Il kmD ottiene invece i dati privati nell'host in un contesto di processo diverso.

L'UMD nell'ospite non può condividere la memoria con il KMD nell'host. Per accedere al Registro di sistema, è necessario usare le funzioni descritte in accesso al Registro di sistema da UMD.

L'implementazione della paravirtualizzazione corrente usa il bus di macchine virtuali per comunicare tra il guest e l'host. La dimensione massima del messaggio è 128 KB. Attualmente, Dxgkrnl non interrompe i messaggi per inviarli in blocchi. Pertanto, il driver deve limitare le dimensioni dei dati privati passati con la creazione di oggetti. Ad esempio, quando Pfnd3dddiAllocatecb viene usato per creare molte allocazioni, la dimensione totale del messaggio include un'intestazione, dati privati globali, oltre alle dimensioni di per ogni allocazione dei dati privati moltiplicati per il numero di allocazioni. Queste informazioni devono essere incluse in un singolo messaggio.

Esecuzione di applicazioni in modalità emulata a schermo intero

La scheda di visualizzazione indiretta deve essere abilitata per l'accesso remoto (è abilitata per impostazione predefinita). Per disabilitarla, seguire questa procedura.

  • Avvia la modifica dei criteri di gruppo
  • Passare a Configurazione computer - Modelli amministrativi>- Componenti di Windows>->Servizi Desktop remoto - Host sessione Desktop remoto>- ambiente sessione remota>
  • Aprire l'elemento "Use WDDM graphics display driver for Remote Desktop Connection" (Usa driver di visualizzazione grafica WDDM per Connessione Desktop remoto)
  • Selezionare Disabilita e selezionare OK
  • Riavviare

Il supporto DXGI per le applicazioni a schermo intero nelle macchine virtuali è abilitato per impostazione predefinita. Per disabilitarla, usare StagingTool.exe /disable 19316777.

Le applicazioni a schermo intero devono essere in esecuzione in modalità schermo intero emulato.

Abilitare eFSE per tutte le applicazioni DXGI e impostare la versione minima WDDM per la transizione dell'effetto di scambio a WDDM 2.0:

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

EFSE è abilitato per impostazione predefinita per le applicazioni D3D9.

DriverStore nella macchina virtuale

I file binari del driver nell'host si trovano in un archivio driver %windir%\system32\drivers\DriverStore\FileRepository<DriverDirectory>.

Per la paravirtualizzazione, i file binari di UMD in una macchina virtuale devono trovarsi in %windir%\system32\drivers\HostDriverStore\FileRepository<DriverDirectory>.

L'host KMD segnala i nomi delle DLL UMD con il percorso completo dell'archivio dei driver. Ad esempio, c:\windows\system32\DriverStore\FileRepository\DriverSpecificDirectory\d3dumd.dll.

Quando la macchina virtuale richiede un nome UMD, il nome viene convertito in <VmSystemDrive>:\windows\system32\HostDriverStore\FileRepository\DriverSpecificDirectory\d3dumd.dll.

Host DriverStore per contenitori

Per i contenitori, Hyper-V mappa la directory dell'archivio driver host completo nell'host a <%windir%\HostDriverStore nel contenitore.

Host DriverStore per le macchine virtuali complete

I file dell'archivio driver vengono copiati nella macchina virtuale all'avvio della scheda GPU virtuale nella macchina virtuale. Questa funzionalità è disabilitata nella versione rilasciata del sistema operativo.

La chiave del Registro di sistema seguente e i possibili valori controllano l'operazione di copia. La chiave non esiste per impostazione predefinita.

DWORD RTL_REGISTRY_CONTROL\GraphicsDrivers\DriverStoreCopyMode
Valore Descrizione
0 Disabilitare la copia dell'archivio driver
1 Normale operazione (abilitare la copia dei file dell'archivio driver e non sovrascrivere i file esistenti).
2 Abilitare la copia dell'archivio driver e sovrascrivere i file esistenti.

Accesso al Registro di sistema da UMD

Le chiavi del Registro di sistema kmD esistono nell'host e non vengono riflesse nella macchina virtuale. Pertanto, l'UMD non è in grado di leggere direttamente tali chiavi del Registro di sistema del driver. Il callback pfnQueryAdapterInfoCb2 viene aggiunto alla struttura di D3DDDI_ADAPTERCALLBACKS del runtime D3D. UMD può chiamare pfnQueryAdapterInfoCb2 con D3DDDICB_QUERYADAPTERINFO2 impostato come segue per leggere determinate chiavi del Registro di sistema:

  • D3DDDICB_QUERYADAPTERINFO2::QueryType impostato su D3DDDI_QUERYADAPTERTYPE_QUERYREGISTRY.
  • pPrivateDriverData punta a un buffer con una struttura D3DDDI_QUERYREGISTRY_INFO in cui restituire le informazioni del Registro di sistema. UMD compila i membri seguenti:
  • PrivateDriverDataSize è sizeof(D3DDDI_QUERYREGISTRY_INFO) più le dimensioni del buffer per il valore di output con dimensioni dinamiche.

UMD può anche chiamare direttamente D3DKMTQueryAdapterInfo. Questa chiamata è utile per UMD nell'ambiente guest perché effettua il marshalling verso l'host e fornisce un modo per tradurre determinati nomi nello spazio dei nomi dell'ambiente guest.

D3DKMTQueryAdapterInfo viene chiamato con D3DKMT_QUERYADAPTERINFO impostato come segue per leggere alcune chiavi del registro:

  • Tipo è impostato su KMTQAITYPE_QUERYREGISTRY
  • pPrivateDriverData punta a una struttura di D3DKMT_ADAPTERREGISTRYINFO
  • PrivateDriverDataSize è sizeof(D3DKMT_ADAPTERREGISTRYINFO) più la dimensione del buffer per un valore di output a dimensione dinamica.

Esempio 1: Lettura di un valore dalla chiave del servizio


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");
       }
    }

Esempio 2: Lettura del percorso dell'archivio driver

    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
    }

Copiare file in %windir%\system32 e %windir%\syswow64 nella macchina virtuale

In alcuni casi, le DLL in modalità utente del driver devono essere presenti nelle directory %windir%\system32 e %windir%\syswow64.

Il sistema operativo consente al driver di specificare i file che devono essere copiati dall'archivio driver dall'host a %windir%\system32 o %windir%\syswow64 nell'ospite.

Nell'INF di installazione il driver può definire più valori nelle sottochiavi seguenti nella chiave del Registro di sistema della scheda grafica:

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

Le sottochiavi copyToVmOverwrite e CopyToVmWhenNewer vengono usate per copiare i file nella directory %windir%\system32.

Le CopyToVmOverwriteWow64 e CopyToVmWhenNewerWow64 sottochiavi vengono usate per copiare i file nella directory %windir%\syswow64.

I file in CopyToVmOverwrite e CopyToVmOverwriteWow64 sovrascrivono sempre i file di destinazione.

I file in CopyToVmWhenNewer e CopyToVmWhenNewerWow64 sovrascrivono i file nella destinazione solo se la data di modifica del file è più recente. I criteri "più recenti" confrontano due informazioni:

  • Versione del File
  • LastWriteTime

Quando il file di destinazione termina con il suffisso .dll o .exe, FileVersion viene usato come valore di confronto più significativo in cui la versione più grande viene considerata "più recente". Quando il file di destinazione non termina con il suffisso .dll o .exe o i due FileVersion sono uguali, l'opzione LastWriteTime viene usata come valori di confronto meno significativi in cui la data/ora successiva viene considerata "più recente".

Ogni tipo di valore in una sottochiave deve essere REG_MULTI_SZ o REG_SZ. Se il tipo di valore è REG_MULTI_SZ, nel valore deve essere presente un massimo di due stringhe. Questo requisito significa che ogni valore definisce una singola stringa o una coppia di stringhe, in cui la seconda stringa può essere vuota.

Il primo nome di una coppia è il percorso di un file nell'archivio driver. Il percorso è relativo alla radice dello store dei driver e può contenere directory secondarie.

Il secondo nome in una coppia è il nome del file come dovrebbe essere visualizzato nella directory %windir%\system32 o %windir%\syswow64. Il secondo nome deve essere solo il nome del file, non incluso il percorso. Se il secondo nome è vuoto, il nome del file corrisponde a quello dell'archivio driver (escluse le sottodirectory).

Questo approccio consente al driver di avere nomi diversi nell'archivio driver host e nel guest.

Esempio 1

L'esempio seguente illustra come far copiare al sistema operativo <DriverStorePath>\CopyToVm\softgpu1.dll a %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"

Esempio 2

L'esempio seguente illustra come ottenere il sistema operativo per copiare <DriverStorePath>\softgpu1.dll in %windir%\system32\softgpu.dll e <DriverStorePath>\softgpu2.dll in %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””

Esempio 3

L'esempio seguente illustra come ottenere il sistema operativo per copiare <DriverStorePath>\Subdir1\Subdir2\softgpu2wow64.dll in %windir%\syswow64\softgpu.dll e <DriverStorePath>\softgpu.dll in %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

Modifiche a DxgkDdiCreateProcess

La funzione di DxgkDdiCreateProcess kmD deve essere aggiornata per supportare i processi di lavoro delle macchine virtuali e i processi delle macchine virtuali. I campi seguenti vengono aggiunti alla struttura DXGKARG_CREATEPROCESS:

  • hKmdVmWorkerProcess
  • ProcessNameLength
  • pProcessName

I flag seguenti vengono aggiunti a DXGK_CREATEPROCESSFLAGS per supportare i processi di lavoro delle macchine virtuali e i processi delle macchine virtuali:

  • VirtualMachineProcess
  • VirtualMachineWorkerProcess

DxgkDdiSetVirtualMachineData

è stato aggiunto DxgkDdiSetVirtualMachineData a Dxgkrnl per trasmettere informazioni su una macchina virtuale al KMD.

Messaggi asincroni del bus di macchine virtuali all'host

Alcuni messaggi dal sistema operativo guest al host, provenienti da Dxgkrnl, sono asincroni. Questo approccio migliora le prestazioni delle chiamate API Dxgkrnl nel guest. Il sovraccarico computazionale di ogni messaggio del bus sincrono della macchina virtuale (VM) per l'host può essere elevato.

I messaggi asincroni includono:

Supporto LDA in GPU-PV

LDA (Linked Display Adapter) è supportato in GPU-PV. Per garantire un'implementazione coerente e supportare il possibile back-porting futuro del supporto LDA alle versioni precedenti di Windows, il KmD deve controllare il supporto LDA in GPU-PV chiamando DxgkCbIsFeatureEnabled(DXGK_FEATURE_LDA_GPUPV). Il supporto è abilitato se la funzione ha esito positivo e restituisce Abilitato. Se il KMD non chiama questo callback, Dxgkrnl presuppone che il KMD non supporti LDA in GPU-PV.

Se il sistema operativo supporta la funzionalità, spetta al driver abilitare LDA in modalità utente. Se il driver abilita LDA in modalità utente, deve farlo come indicato di seguito.

Tempo di esecuzione Stato LDA
Runtime ante-D3D12 Abilitare se DXGK_FEATURE_LDA_GPUPV è supportato e il sistema operativo guest è Windows 11, versione 22H2 (WDDM 3.1) o versione successiva.
Runtime non DX (Windows) Abilitare se DXGK_FEATURE_LDA_GPUPV è supportato e il sistema operativo guest è Windows 11, versione 22H2 (WDDM 3.1) o versione successiva. Invece di controllare la versione del sistema operativo, UMD potrebbe chiamare D3DKMTQueryAdapterInfo(KMTQAITYPE_PHYSICALADAPTERCOUNT) e abilitare LDA quando restituisce il numero di schede fisiche maggiori di 1.
Runtime D3D12 (Windows) Abilitare. Consultare Impostazione dello stato LDA per il runtime D3D12.
Linux (d3d12 e runtime non DX) Abilitare se DXGK_FEATURE_LDA_GPUPV è supportato.

I driver che sono stati compilati con una versione dell'interfaccia inferiore a DXGKDDI_INTERFACE_VERSION_WDDM3_0 non controllano DXGK_FEATURE_LDA_GPUPV. Questi driver possono comunque abilitare LDA per i runtime Linux.

Impostazione dello stato LDA per il runtime D3D12

Quando si abilita o disabilita LDA per il runtime D3D12, il driver in modalità utente (UMD) deve restituire le informazioni corrette sul livello e sulla mappa dei nodi al runtime. Il flusso di codice è il seguente:

  • D3D12 ottiene il limite di D3D12_CROSS_NODE_SHARING_TIER da UMD.

  • D3D12 ottiene il numero di adattatori fisici da Dxgkrnl chiamando D3DKMTQueryAdapterInfo(KMTQAITYPE_PHYSICALADAPTERCOUNT).

  • D3D12 chiama pfnQueryNodeMap(PhysicalAdapterCount, &map) per ottenere il mapping degli indici dei nodi logici ai nodi fisici. Il nodo in questo caso indica l'adattatore fisico. Il UMD deve impostare l'indice effettivo dell'adattatore fisico nella mappa o D3D12DDI_NODE_MAP_HIDE_NODE per disabilitare un nodo.

  • In base ai risultati pfnQueryNodeMap, D3D12 calcola il numero effettivo di adattatori fisici senza contare i nodi nascosti.

  • Se lo stato del livello e il numero effettivo di adattatori fisici non corrispondono, D3D12 fallisce nella creazione del dispositivo. La mancata corrispondenza si verifica quando:

    • Il livello è D3D12DDI_CROSS_NODE_SHARING_TIER_NOT_SUPPORTED e il conteggio degli adattatori è maggiore di 1.
    • Il livello non è D3D12DDI_CROSS_NODE_SHARING_TIER_NOT_SUPPORTED e il numero di adattatori è 1.

Per disabilitare LDA, la UMD deve restituire il livello D3D12DDI_CROSS_NODE_SHARING_TIER_NOT_SUPPORTED e mantenere abilitato un solo adattatore fisico nella mappa dei nodi.

D3DKMTQueryAdapterInfo(KMTQAITYPE_PHYSICALADAPTERCOUNT)

Una query KMTQAITYPE_PHYSICALADAPTERCOUNT relativa al conteggio degli adattatori fisici restituisce sempre il numero corretto di adattatori fisici all'ospite:

  • Nei guest precedenti alla versione 22H2 di Windows 11, restituisce 1. Questo valore è codificato staticamente nel codice ospite. Potrebbe cambiare in futuro se il supporto LDA venisse portato alle versioni precedenti del sistema operativo.
  • In Windows 11, versione 22H2 e sistemi successivi, restituisce:

Avvio della paravirtualizzazione

Abilitare il supporto della virtualizzazione nel BIOS (VT-d o simile). La configurazione GPU-PV è diversa per le macchine virtuali di VMMS e i contenitori.

In PowerShell (in esecuzione come amministratore) abilitare l'esecuzione di script nel server:

set-executionpolicy unrestricted

Configurazione della macchina virtuale VMMS

Configurazione dell'host e della macchina virtuale

La build del sistema operativo nella macchina virtuale può essere precedente o successiva alla build del sistema operativo nell'host.

  1. Abilitare la funzionalità Hyper-V nei ruoli del server o nella funzionalità di Hyper-V nel client. Quando si abilita questa funzionalità nel server, selezionare l'opzione per usare la scheda di rete come commutatore esterno.

  2. (facoltativo) Abilitare la firma di test (bcdedit -set TESTSIGNING ON)

  3. Riavviare.

  4. Installare un driver GPU che supporta la paravirtualizzazione.

  5. (facoltativo) Alcuni driver non impostano il limite ParavirtualizationSupported. In questo caso, aggiungere il registro seguente prima di installare il driver o disabilitare/abilitare il dispositivo dopo l'impostazione del flag.

    DWORD HKLM\System\CurrentControlSet\Control\GraphicsDrivers\GpuVirtualizationFlags = 1   
    
  6. Per verificare se il sistema operativo riconosce la GPU paravirtualizzata, eseguire il comando di PowerShell seguente:

    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. Eseguire i comandi seguenti in PowerShell per creare una macchina virtuale con GPU. Viene creata una macchina virtuale denominata TEST.

    $vm = “TEST“
    New-VM -VMName $vm -Generation 2
    Set-VM -GuestControlledCacheTypes $true -VMName $vm
    
  8. Impostare lo spazio di I/O per la macchina virtuale. GPU-PV usa lo spazio di I/O per gestire le allocazioni visibili della CPU. Sono necessari almeno 8 GB di spazio di I/O.

    Set-VM -LowMemoryMappedIoSpace 1GB -VMName $vm
    Set-VM -HighMemoryMappedIoSpace 16GB -VMName $vm
    
  9. [facoltativo] Per impostazione predefinita, l'indirizzo di base per lo spazio di I/O con memoria elevata è impostato su (64 GB - 512 MB). Nei chipset Haswell con indirizzamento di memoria fisica a 36 bit, l'indirizzo finale dell'area spaziale di I/O deve essere inferiore a 64 GB, quindi l'indirizzo iniziale deve essere impostato di conseguenza. Lo script seguente, denominato SetHighMmioBase.ps1, imposta l'indirizzo iniziale su 47 GB quando viene eseguito con i parametri seguenti:

    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. Aggiungere una GPU virtuale alla macchina virtuale e disabilitare i checkpoint.

    Add-VMGpuPartitionAdapter -VMName $vm
    Set-VM -CheckpointType Disabled -VMName $vm
    
  11. Per verificare che la macchina virtuale disponga di una GPU paravirtualizzata, eseguire il comando seguente:

    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. Copiare il VHDX della stessa build client usata nella macchina virtuale in una directory host. Ad esempio, d:\VM\os.vhdx.

  13. Aprire Hyper-V manager e modificare i parametri della macchina virtuale (selezionare MACCHINA virtuale e selezionare Impostazioni):

    • Sicurezza: deseleziona Abilita il Secure Boot.
    • Memoria: controllare abilitare la memoria dinamica. Impostare la quantità di memoria su 1.024 MB o più.
    • Processore: impostare Numero di processori virtuali su 2 o 4.
    • Scheda di rete: selezionare la scheda di rete da usare con la macchina virtuale dall'elenco a discesa. Se il debug di rete è abilitato, verificare di selezionare l'adattatore di debug Microsoft NET.
    • Controller SCSI - Disco rigido - Aggiungi - Disco rigido virtuale - Sfoglia - Selezionare d:\VM\os.vhdx
  14. Il sistema operativo copia i file dall'archivio driver host nella directory HostDriverStore nel guest quando l'adattatore viene inizializzato.

    • Montare il VHDX della macchina virtuale. Ad esempio, al disco f:.
    • Nella macchina virtuale montata creare una directory denominata f:\%windir%\system32\HostDriverStore\FileRepository.
    • Copiare i file dei driver da %windir%\system32\DriverStore dall'host alla macchina virtuale. Deve essere presente f:\%windir%\system32\HostDriverStore\FileRepository\YourDriverDirectory\* nella macchina virtuale.
  15. Se il driver deve accedere ai file da %windir%\system32 o %windir%\syswow64, copiare manualmente i file nella macchina virtuale.

  16. Abilitare l'accesso di test nella macchina virtuale se i driver non sono firmati da Microsoft. Nella finestra di amministrazione cmd eseguire il comando seguente:

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

    Smontare il VHDX della macchina virtuale.

  17. Avviare la macchina virtuale.

  18. Connettersi alla macchina virtuale usando l'opzione Connect di Hyper-V manager.

ALL'INTERNO DELLA MACCHINA VIRTUALE

Verificare che sia presente un dispositivo di rendering virtuale nella gestione dispositivi della macchina virtuale. Tutto il rendering all'interno della macchina virtuale passa attraverso la GPU virtuale.

Script di PowerShell per configurare una macchina virtuale

Lo script di PowerShell seguente è un esempio di come configurare una macchina virtuale da zero. Modificarlo in base alle proprie esigenze.


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
}

Debug della macchina virtuale

Configurare il debugger della macchina virtuale allo stesso modo del debug di rete in un computer client normale.

Se la macchina virtuale non viene avviata o viene visualizzata una schermata nera:

  • Disattivare la macchina virtuale e rimuovere la GPU virtuale da essa usando i comandi seguenti:

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

    Per esempio:

    remove-VMGpuPartitionAdapter  -VMName $vm -AdapterId “Microsoft:9ABB95E2-D12D-43C3-B840-6F4A9CFB217B\929890BC-BB33-4687-BC1A-F72A4F1B3B3F”
    
  • Avviare la macchina virtuale. Se viene avviato correttamente, assicurarsi che i file del driver vengano copiati correttamente in HostDriverStore nella macchina virtuale.

  • Aggiungere vGPU alla macchina virtuale usando il comando Add-VMGpuPartitionAdapter.

  • Avviare di nuovo la macchina virtuale.

Per altre informazioni, vedere Risoluzione dei problemi.

Configurazione del contenitore

La differenza tra i contenitori (denominati anche vm del sistema di calcolo host (HCS) e la macchina virtuale completa è che i file binari del sistema operativo e i file di archivio driver vengono mappati al contenitore. Non è quindi necessario copiare i file del driver nel contenitore, a meno che non siano necessari nella directory windows\system32.

Per i contenitori sicuri:

  • I escape del driver sono disabilitati.
  • Il driver deve supportare l'isolamento IOMMU per essere attivato all'interno di un contenitore sicuro.

Quando si aggiorna il driver nell'host e si avvia o arresta la GPU host, le modifiche vengono riflesse nel contenitore.

Windows Sandbox

Questo tipo di contenitore viene usato per provare applicazioni rischiose. L'immagine del desktop completa è trasmessa all'host. Il driver di visualizzazione indiretto viene usato per l'accesso remoto. La grafica VAIL non viene utilizzata, quindi il trasferimento dell'immagine del desktop all'host è lento.

La GPU virtuale è disabilitata per impostazione predefinita in Windows Sandbox. Per abilitarla, creare un file di configurazione WSB (ad esempio, config.wsb) e impostare l'opzione della GPU virtuale. Avviare Sandbox facendo clic sul file di configurazione.

Esempio di file di configurazione:

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

Per impostazione predefinita, la vGPU nel contenitore ha le escape driver disabilitate. È disponibile un'opzione di configurazione per abilitare i escape del driver. L'esempio di file WSB seguente abilita sia le vGPU in Sandbox che le funzionalità di escape del driver.

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

Windows Sandbox supporta l'hot plug dell'adattatore GPU.

Contenitore VAIL (Applicazione Virtuale Integrata Localmente)

Usare questo tipo di contenitore per eseguire applicazioni Win32 all'interno di un host basato su WCOS (Windows Core Operated System). L'immagine di ogni applicazione nel contenitore viene trasferita all'host. Graphics VAIL è abilitato per gestire da remoto ciascuna swapchain delle applicazioni. Le fughe del driver sono abilitate.

Requisiti comuni dei contenitori

I requisiti del computer sono:

  • Sia Vtx che Vtd devono essere abilitati nel BIOS (o i relativi equivalenti: AMD-V, AMD-IOMMU).
  • Almeno 8 GB di RAM.
  • Più di 5 GB di spazio su disco di sistema.

Configurazione del debugger del kernel per Windows Sandbox

Uso di CMDIAG

Un servizio Gestione contenitori (cmservice) controlla Hyper-V contenitori isolati. CMDIAG.EXE è un'applicazione disponibile quando si installano le funzionalità di Hyper-V e contenitori. Abilita il debug in modalità kernel per i contenitori, abilita la firma di test e altro ancora.

Il gestore dei contenitori supporta il debug in serie e NET.

Eseguire cmdiag.exe Debug per visualizzare le opzioni.

CMDIAG modifica le impostazioni del debugger nell'immagine di base del contenitore. Quando il debugger del kernel è abilitato, deve essere in esecuzione una sola istanza di un contenitore.

Arrestare il servizio HVSICS prima di modificare le impostazioni del debugger.


# 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

Esecuzione del debugger in un computer diverso

Quando si usa il debugger seriale, è possibile eseguirlo in un computer diverso. Usare kdsrv.exe per eseguire il debugger in un computer diverso. Per altre informazioni, vedere KD Connection Servers.

Per disabilitare i timeout durante il debug del kernel, impostare le chiavi del Registro di sistema seguenti:

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

Configurazione del debugger del kernel per il contenitore VAIL

  • Connettersi all'host usando telnet. È possibile ottenere l'indirizzo IP dell'host da Impostazioni di rete nel sistema operativo host.
  • Usare cmdiag.exe per configurare il debugger.

Configurazione del debugger 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

Risoluzione dei problemi

Questa sezione fornisce informazioni su come risolvere i problemi relativi a GPU-PV.

Get-VMHostPartitionableGpu

Chiamare Get-VMHostPartitionableGpu per verificare se è presente una GPU virtualizzata. Se l'output è vuoto, si verifica un errore in un punto qualsiasi (il driver non ha impostato il limite di virtualizzazione, la virtualizzazione non è abilitata e così via).

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

Uso degli eventi ETW

Dxgkrnl dispone di canali di amministrazione e operativi per gli eventi ETW. Gli eventi vengono visualizzati nel Visualizzatore eventi di Windows: Registro applicazioni e servizi - Microsoft - Windows - Dxgkrnl.

Il Visualizzatore eventi include eventi di altri componenti che partecipano alla creazione di una macchina virtuale con GPU-PV (Hyper-V-Compute, Hyper-V-Worker, Hyper-V-VID e così via).

Uso di Add-VMGpuPartitionAdapter

Quando usi Add-VMGpuPartitionAdapter, non specificare una funzionalità (ad esempio, decodifica) se non è necessaria. Non usare 0 per questa funzionalità.

Uso di Remove-VMGpuPartitionAdapter

Se una macchina virtuale non viene avviata o presenta problemi di rendering, provare a rimuovere la GPU virtuale dalla macchina virtuale usando Remove-VMGpuPartitionAdapter.

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

Impedire l'avvio della macchina virtuale durante l'avvio

set-vm -AutomaticStartAction Nothing -VmName TEST

Eventi del Visualizzatore eventi

Aggiungere eventi al canale del Visualizzatore eventi per identificare i problemi relativi all'avvio della vGPU. È possibile trovare gli eventi in "Registri applicazioni e servizi\Microsoft\Windows\Dxgkrnl". I canali di evento sono Admin e Operational.

Gli eventi vengono generati quando:

  • Viene creata la vGPU
  • La vGPU viene eliminata definitivamente
  • Il guest apre un adattatore virtuale

I file di evento si trovano in:

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

Controllare se è stata creata una vGPU ed eventuali errori.

Impostazioni del Registro di sistema

GpuVirtualizationFlags

La chiave del Registro di sistema GpuVirtualizationFlags viene usata per impostare il comportamento delle GPU paravirtualizzate. La chiave si trova in:

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

Sono definiti i bit seguenti:

Pezzo Descrizione
0x1 Forzare la limitazione ParavirtualizationSupported per tutte le schede hardware. Utilizzare questo bit nel server.
0x2 Impostare il limite ParavirtualizationSupported per BasicRender. Usare questo bit sull'host.
0x4 Forzare la modalità di macchina virtuale sicura, in cui tutte le macchine virtuali verranno considerate sicure. In questa modalità sono previste restrizioni per il driver in modalità utente. Ad esempio, il driver non può usare chiamate di escape, quindi falliranno. Usare questo bit sull'host.
0x8 Abilitare l'associazione di adattatori paravirtualizzati con la scheda di sola visualizzazione. Usare questo bit nella macchina virtuale ospite. L'abbinamento è abilitato per impostazione predefinita.

GuestIoSpaceSizeInMb

La chiave del Registro di sistema GuestIoSpaceSizeInMb viene usata per impostare le dimensioni dello spazio di I/O guest per le GPU virtuali, in megabyte. Il valore predefinito è 1.000 MB (1 GB). La chiave si trova in:

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

Lo spazio I/O guest attualmente implementa allocazioni visibili alla CPU. Un archivio di backup dell'allocazione visibile alla CPU nell'host viene aggiunto in memoria ed è mappato allo spazio di I/O guest. Nel guest l'indirizzo virtuale in modalità utente di allocazione viene ruotato nell'area dello spazio di I/O. In alcuni sistemi Haswell la CPU ha indirizzi fisici a 36 bit. Hyper-V su tali sistemi ha dimensioni limitate dello spazio di I/O.

Disabilitare l'isolamento IOMMU per le macchine virtuali sicure

Se un driver non supporta l'isolamento IoMmu, usare l'impostazione del Registro di sistema seguente durante lo sviluppo per disabilitare l'isolamento IoMmu.

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

Limitare il numero di funzioni virtuali

Per impostazione predefinita, il numero di funzioni virtuali esposte da un adattatore che supporta la paravirtualizzazione GPU è 32. Questo numero indica che l'adattatore può essere aggiunto a 32 macchine virtuali, presupponendo che ogni macchina virtuale abbia una scheda.

È possibile usare l'impostazione del Registro di sistema seguente per limitare il numero di funzioni virtuali esposte.

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

Ad esempio, se si imposta NumVirtualFunctions su 1, la scheda può essere aggiunta a una sola GPU una volta. Questa impostazione è utile quando un computer dispone di più schede GPU che supportano GPU-PV e si vuole assegnare ogni scheda a una macchina virtuale. Add-VMGpuPartitionAdapter non consente di specificare l'adattatore da aggiungere. Pertanto, se due adattatori vengono aggiunti a una macchina virtuale, entrambi potrebbero ottenere lo stesso adattatore GPU-PV dall'host.

Aggiornamenti DDI di WDDM 2.4

Gli aggiornamenti DDI seguenti vengono eseguiti per supportare la paravirtualizzazione GPU in WDDM 2.4.

Aggiunta capacità DXGK_VIDMMCAPS

La funzionalità ParavirtualizationSupported viene aggiunta alla struttura DXGK_VIDMMCAPS. Il KMD host imposta questo limite se implementa tutte le DDI descritte in questa sezione.

Dati privati del driver passati tramite DDI

Il UMD usa varie DDI per scambiare informazioni private con il relativo KMD corrispondente. Quando l'UMD viene eseguito nella macchina virtuale guest, la chiamata DDI KMD corrispondente si verifica nella partizione host. Di conseguenza, l'UMD:

  1. Non è possibile passare puntatori nei dati privati.
  2. Non è possibile passare handle nei dati privati.
  3. Non deve indicare al KmD di apportare modifiche globali dello stato della GPU, perché questa modifica potrebbe influire su altre macchine virtuali in esecuzione.

Aggiunta del flag VirtualMachineProcess per DxgkDdiCreateProcess

Il sistema operativo crea un processo di lavoro della macchina virtuale per ogni macchina virtuale in esecuzione. Dxgkrnl crea un DXGPROCESS corrispondente e chiama DxgkDdiCreateProcess con il flag VirtualMachineWorkerProcess impostato. In questo contesto di processo non è presente alcuna creazione delle risorse di rendering o dei driver. Il driver potrebbe quindi ignorare l'allocazione di determinate risorse.

Il sistema operativo crea un DXGPROCESS nell'host per ogni processo in una macchina virtuale guest che usa una GPU. Dxgkrnl chiama DxgkDdiCreateProcess con il flag VirtualMachineProcess impostato. Ogni processo DXG della macchina virtuale appartiene allo stesso processo EPROCESS del processo di lavoro della macchina virtuale.

Aggiornamenti di DxgkDdiQueryAdapterInfo

La struttura DXGKARG_QUERYADAPTERINFO viene aggiornata per includere i campi seguenti per il supporto della paravirtualizzazione:

  • Il membro Flags viene aggiunto, il che consente a Dxgkrnl di indicare quanto segue:

    • Imposta VirtualMachineData per indicare che la chiamata proviene da una macchina virtuale.
    • Imposta SecureVirtualMachine per indicare che la macchina virtuale viene eseguita in modalità protetta.
  • viene aggiunto il hKmdProcessHandle, che consente al driver di identificare e usare il contesto di processo corretto sul lato host quando si gestiscono query provenienti da una macchina virtuale guest.

Aggiornamenti di DxgkDdiEscape

Il membro hKmdProcessHandle viene aggiunto alla struttura DXGKARG_ESCAPE per consentire al driver di identificare e usare il contesto di processo corretto sul lato host quando si gestiscono escape provenienti da una macchina virtuale guest.

Il flag VirtualMachineData viene aggiunto alla struttura di D3DDDI_ESCAPEFLAGS per indicare che dxgkDdiEscape viene chiamato da una macchina virtuale.

Accesso fisico alle allocazioni GPU

Attualmente, il driver non implementa l'accesso fisico alle allocazioni. Il driver deve supportare GpuMmu.

Aggiornamenti DDI di WDDM 2.5

Per WDDM 2.5, per il supporto della paravirtualizzazione sono necessarie anche le modifiche DDI seguenti.

Segnalazione di eventi ospite da parte dell'host KMD

Esistono scenari senza virtualizzazione quando il KmD deve segnalare un evento creato da un UMD. Per gestire questi scenari quando viene usata la paravirtualizzazione, il KMD nell'host deve segnalare un evento creato nel guest. Il callback DxgkCbSignalEvent viene aggiunto a questo scopo. KmD può anche usare questo callback per segnalare gli eventi dei processi host.

Supporto per gli handle forniti da UMD in una VM

Alcuni callback del driver accettano un'allocazione o un handle di risorsa Dxgkrnl che l'UMD passa, ad esempio:

Le chiamate sull'host devono trovarsi nel contesto dello stesso thread che ha chiamato una funzione DxgkDdiXxx.

Si supponga, ad esempio, che senza virtualizzazione, il KMD chiami DxgkCbAcquireHandleData nel contesto del thread in modalità utente che chiama D3DKMTEscape, che chiama DxgkDdiEscape.

Quando UMD viene eseguito in una macchina virtuale, conosce solo gli handle di allocazione guest e non può passare tali handle al KMD perché KMD viene eseguito nell'host. Il UMD nel guest chiama D3DKMTEscape e il KMD nell'host riceve la chiamata DxgkDdiEscape corrispondente. Il KMD deve chiamare DxgkCbAcquireHandleData nel contesto di questo thread.

Per poter convertire l'handle di allocazione/risorsa guest nell'handle host corrispondente, viene aggiunto il flag di escape del driver D3DDDI_ESCAPEFLAGS::DriverKnownEscape driver.

Quando si chiama D3DKMTEscape con il flag DriverKnownEscape impostato:

  • Impostare D3DKMT_ESCAPE::Type su D3DKMT_ESCAPE_DRIVERPRIVATE.

  • Impostare D3DKMT_ESCAPE::p PrivateDriverData in modo che punti a una struttura di escape driver nota, definita nella sezione seguente. Ogni struttura inizia con un valore D3DDDI_DRIVERESCAPETYPE.

Quando la virtualizzazione non viene usata, l'handle tradotto è uguale all'handle di input.

Vengono definiti i seguenti escape noti del driver.

Il seguente frammento di codice mostra come utilizzare il flag 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);

Aggiornamenti DDI di WDDM 2.6

A partire da WDDM 2.6 (Windows 10, versione 1903), sono stati eseguiti gli aggiornamenti seguenti per il supporto della paravirtualizzazione:

  • Il driver può usare il flag DXGK_ALLOCATIONINFOFLAGS::ACCESSEDPHYSICALLY in una macchina virtuale. Prima di WDDM 2.6, il driver non è riuscito a usare questo flag in una macchina virtuale e la creazione dell'allocazione con questo flag non è riuscita.

  • UMD può usare pfnd3dkmtUpdateallocationproperty in una macchina virtuale. Prima di WDDM 2.6, questa chiamata avrà esito negativo.