Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
In diesem Artikel wird die GPU-Paravirtualisierung in WDDM beschrieben. Dieses Feature ist ab Windows 10, Version 1803 (WDDM 2.4) verfügbar.
Informationen zur GPU-Virtualisierung
GPU-Virtualisierung ist ein wichtiges Feature für Windows Client und Windows Server. Es gibt viele Szenarien, die eine effektive Verwendung von GPU-Ressourcen auf einem virtuellen Computer erfordern.
Serverszenarien (in denen das Hostbetriebssystem keine Benutzeranwendungen ausführt) umfassen:
- Desktopvirtualisierung
- Compute (KI, ML usw.)
Clientszenarien (in denen das Hostbetriebssystem die GPU zwischen VMs und Benutzeranwendungen gemeinsam verwendet) umfassen:
- Entwickeln und Testen von Grafikanwendungen (bei denen Tests auf einem virtuellen Computer ausgeführt werden)
- Ausführen von Anwendungen in einem virtuellen Computer für Sicherheitszwecke
- Ausführen von Linux in einer VM mit GPU-Beschleunigung
GPU-Paravirtualisierung in WDDM
Paravirtualization (PV) stellt eine Schnittstelle zu virtuellen Computern (VMs) bereit, die ihrer zugrunde liegenden Hardware ähneln. In PV portieren Sie das Gastbetriebssystem explizit, bevor Sie einen virtuellen Computer installieren, da ein nicht maßgeschneidertes Gastbetriebssystem nicht über einem virtuellen Computermonitor (VMM) ausgeführt werden kann.
Vorteile:
- Mehrere VMs teilen die Hardwareressourcen.
- Im Treibercode müssen nur wenige Änderungen vorgenommen werden.
Die folgende Abbildung zeigt verschiedene Komponenten, die am paravirtualisierten Design von WDDM beteiligt sind.
Die D3D-Laufzeiten in der Gast-VM werden nicht geändert. Die Schnittstellen mit der Runtime im Benutzermodus und mit KMT-Kernel-Thunks bleiben gleich.
Für die Treiberkomponenten sind nicht viele Änderungen erforderlich:
Die UMD in der Gast-VM muss folgendes ausführen:
- Beachten Sie, dass die Kommunikation mit dem Host kernelmodustreiber (KMD) über die VM-Grenze hinweg erfolgt.
- Verwenden Sie die hinzugefügten Dxgkrnl--Dienste, um auf Registrierungseinstellungen zuzugreifen.
Im Gast ist kein KMD vorhanden, nur UMD. Der KMD (Virtual Render Device, VRD) ersetzt den KMD. Der Zweck des VRD besteht darin, das Laden von Dxgkrnl zu erleichtern.
Im Gast in kein Videospeicher-Manager (VidMm) oder Scheduler (VidSch) vorhanden.
Dxgkrnl in einer VM erhält Thunk-Aufrufe und leitet sie über VM-Bus-Kanäle an die Hostpartition weiter. Dxgkrnl im Gast erstellt auch lokale Objekte für Zuteilungen, Prozesse, Geräte und andere Ressourcen, wodurch der Datenverkehr mit dem Host reduziert wird.
Virtuelles Rendergerät (VIRTUAL Render Device, VRD)
Wenn eine paravirtualisierte GPU nicht in einer VM vorhanden ist, zeigt der Geräte-Manager des virtuellen Computers den Adapter "Microsoft Hyper-V Video" an. Dieser Anzeigeadapter ist standardmäßig mit dem BasicRender-Adapter zum Rendern verbunden.
Wenn Sie einer VM eine paravirtualisierte GPU hinzufügen, zeigt der Geräte-Manager des virtuellen Computers zwei Adapter an:
- Microsoft Hyper-V-Grafikkarte oder Microsoft-Remoteanzeigeadapter
- Microsoft Virtual Render Driver (Der tatsächliche Name ist der Name des GPU-Adapters auf dem Host)
Standardmäßig wird die VRD mit dem Hyper-V Videoadapter gekoppelt, sodass alle UI-Renderings mit dem VRD-Adapter erfolgen.
Wenn Beim Rendern Probleme auftreten, können Sie diese Kopplung mithilfe der GpuVirtualizationFlags Registrierungseinstellung deaktivieren. In diesem Fall wird der Render-Only-Adapter (VRD) verwendet, wenn eine Anwendung ihn speziell auswählt. In einigen DirectX-Beispielen können Sie beispielsweise das Renderinggerät ändern. Die Direct3D-Laufzeiten fügen der VRD eine logische Anzeigeausgabe hinzu, wenn eine Anwendung entscheidet, sie zu verwenden.
Wenn Sie der VM mehrere virtuelle GPUs hinzufügen, können mehrere VRD-Adapter im Gast vorhanden sein. Allerdings kann nur einer davon mit dem Hyper-V-Videoadapter verwendet werden. Es gibt keine Möglichkeit, anzugeben, welche; das Betriebssystem auswäht.
Container und VMs
GPU-Virtualisierung wird für VMs und Container unterstützt. Container sind einfache virtuelle Computer, bei denen die Hostbetriebssystem-Binärdateien der Container-VM zugeordnet sind.
Weitere Informationen zu Containern finden Sie unter Windows und Container.
Sichere virtuelle Computer
Für einen sicheren virtuellen Computer gelten die folgenden Einschränkungen:
- Treiberescapeaufrufe sind nicht zulässig, mit Ausnahme bekannter Escapes, die mit dem Flag DriverKnownEscape verwendet werden.
- Die IoMmu-Isolation ist aktiviert. Die VM-Erstellung schlägt fehl, wenn der Treiber die IoMmu-Isolation nicht unterstützt.
Wenn der sichere Modus aktiviert ist:
- Für DxgkDdiSetVirtualMachineData ist das Flag SecureVirtualMachine festgelegt.
- Für DxgkDdiQueryAdapterInfo ist das Flag SecureVirtualMachine festgelegt.
Es gibt Registrierungseinstellungen, um den sicheren Modus zu erzwingen oder die IoMmu-Isolation während der Entwicklung zu deaktivieren. Weitere Informationen finden Sie unter Registrierungseinstellungen.
Remoting des VM-/Container-Desktops
Sie können den Inhalt eines Desktops auf einem virtuellen Computer (VM) mithilfe von zwei Methoden an den Host remoten:
- Hyper-V Anzeigeadapter
- Remoting von Terminalsitzungen
Wenn RDP (Remotedesktop) zum Herstellen einer Verbindung mit einer VM verwendet wird, wird Remoting von Terminalsitzungen verwendet.
Der Hyper-V-Manager verwendet die VMConnect--Anwendung, um einen VM-Desktop anzuzeigen. VMConnect funktioniert in zwei Modi:
- Erweiterter Modus, der Remoting von Terminalsitzungen verwendet
- Standardmodus, der den Hyper-V Display-Adapter verwendet.
VM-Arbeitsprozess und VM-Arbeitsspeicher
Wenn Sie einen virtuellen Computer oder Container starten, erstellt das Betriebssystem die folgenden Prozesse auf dem Host:
- VM-Workerprozess (vmwp.exe)
- VM-Speicherprozess (vmmem.exe)
VMWP- enthält verschiedene virtuelle Treiber, einschließlich vrdumed.dll, den Treiber für paravirtualisierte Grafikadapter.
Der virtuelle Adressraum des vmmem-Prozesses dient als Unterstützung für den E/A-Bereich der vGPU im Gast. Wenn der Gast auf den E/A-Bereich zugreift, ist die resultierende physische Adresse der Eintrag in die Übersetzung der zweiten Ebene, die die Seitentabellen des vmmem-Prozesses verwendet.
In einer virtualisierten Umgebung werden verschiedene KMD DDI-Aufrufe, die in der Regel im Kontext eines Benutzerprozesses auf dem Host ausgeführt werden, stattdessen im Kontext des vmmem- Prozesses ausgeführt, wenn ein virtueller Computer ausgeführt wird.
Dxgkrnl- erstellt ein einzelnes DXGPROCESS (und das entsprechende KMD-Prozessobjekt) für diese Prozesse, das in diesem Artikel als VM-Arbeitsprozess bezeichnet wird. Der mit dem DXG-VM-Workerprozess verbundene EPROCESS ist vmmem.
VM-Prozesse
Wenn ein DXGPROCESS in der Gast-VM erstellt wird, erstellt Dxgkrnl ein entsprechendes DXGPROCESS-Objekt auf dem Host. Dieser Prozess wird in diesem Artikel als VM-Prozess bezeichnet. Der dem DXGPROCESS zugeordnete EPROCESS ist "vmmem".
Alle Rendering-Vorgänge, die bei der Erstellung einer VM oder einer VM-Zuordnung ausgeführt werden, erfolgen im Kontext des DXGPROCESS des virtuellen Computers.
Zu Debuggingzwecken benachrichtigt Dxgkrnl KMD darüber, welcher Prozess ein VM-Workerprozess oder ein VM-Prozess in DxgkDdiCreateProcess ist. Mithilfe dieser Informationen kann der Treiber einen VM-Prozess mit dem VM-Arbeitsprozess verknüpfen. Diese Informationen helfen beim Debuggen in Szenarien, in denen mehr als eine VM ausgeführt wird.
Treiberanforderungen
Eine KMD, die GPU-Paravirtualisierung unterstützt, muss die Funktion DXGK_VIDMMCAPS::ParavirtualizationSupported festlegen.
Der Benutzermodustreiber (USER-Mode Driver, UMD) sollte keine prozesskontextbezogenen Daten in den privaten Treiberdaten (Zeiger, Handle usw.) verwenden. Stattdessen ruft die KMD die privaten Daten im Host in einem anderen Prozesskontext ab.
Die UMD im Gast kann den Arbeitsspeicher nicht mit der KMD im Host teilen. Sie muss die in Registrierungszugriff von UMD beschriebenen Funktionen verwenden, um auf die Registrierung zuzugreifen.
Die aktuelle Paravirtualisierungsimplementierung verwendet den VM-Bus, um zwischen dem Gast und dem Host zu kommunizieren. Die maximale Nachrichtengröße beträgt 128 KB. Derzeit teilt Dxgkrnl Nachrichten nicht auf, um sie in Blöcken zu senden. Daher muss der Treiber die Größe privater Daten einschränken, die mit der Objekterstellung übergeben werden. Wenn z. B. Pfnd3dddiAllocatecb verwendet wird, um viele Zuordnungen zu erstellen, enthält die Gesamtnachrichtengröße eine Kopfzeile, globale private Daten sowie die Größe der pro Zuordnung privaten Daten multipliziert mit der Anzahl der Zuordnungen. Diese Informationen müssen alle in eine einzelne Nachricht passen.
Ausführen von Anwendungen im emulierten Vollbildmodus
Der Adapter für indirekte Anzeige muss für Remoting aktiviert sein (ist standardmäßig aktiviert). Führen Sie zum Deaktivieren die folgenden Schritte aus.
- Starten Sie die Bearbeitung der Gruppenrichtlinie.
- Navigieren Sie zu Computerkonfiguration–>Administrative Vorlagen->Windows-Komponenten->Remotedesktopdienste->Remotedesktopsitzungshost->Remotesitzungsumgebung
- Öffnen Sie das Element „WDDM-Grafikanzeigetreiber für Remotedesktopverbindungen verwenden“.
- Wählen Sie "Deaktivieren" und dann "OK" aus.
- Neustart
Die DXGI-Unterstützung für Vollbildanwendungen in VMs ist standardmäßig aktiviert. Verwenden Sie StagingTool.exe /disable 19316777
, um sie zu deaktivieren.
Vollbildanwendungen müssen im emulierten Vollbildmodus ausgeführt werden.
Aktivieren Sie eFSE für alle DXGI-Anwendungen, und legen Sie die mindeste WDDM-Version für den Swapeffektübergang auf WDDM 2.0 fest:
D3DEnableFeature.exe /enable DXGI_eFSE_Enablement_Policy
D3DEnableFeature.exe /setvariant DXGI_eFSE_Enablement_Policy 7
eFSE ist für D3D9-Anwendungen standardmäßig aktiviert.
DriverStore im virtuellen Computer
Treiberbinärdateien auf dem Host befinden sich in einem Treiberspeicher %windir%\system32\drivers\DriverStore\FileRepository<DriverDirectory>.
Für die Paravirtualisierung wird erwartet, dass die BIN-Dateien von UMD in einer VM in %windir%\system32\drivers\HostDriverStore\FileRepository<DriverDirectory>liegen.
Der Host-KMD meldet die Namen der UMD-DLLs, die den vollständigen Pfad zum Treiberspeicher enthalten. Beispiel: c:\windows\system32\DriverStore\FileRepository\DriverSpecificDirectory\d3dumd.dll.
Wenn der virtuelle Computer einen UMD-Namen anfragt, wird der Name in <VmSystemDrive>:\windows\system32\HostDriverStore\FileRepository\DriverSpecificDirectory\d3dumd.dllübersetzt.
Hosten von „DriverStore“ für Container
Für Container ordnet Hyper-V das vollständige Verzeichnis des Hosttreiberspeichers im Host dem Verzeichnis <%windir%\HostDriverStore im Container zu.
Host DriverStore für vollständige VMs
Die Treiberspeicherdateien werden auf den virtuellen Computer kopiert, wenn der virtuelle GPU-Adapter im virtuellen Computer gestartet wird. Dieses Feature ist in der veröffentlichten Version des Betriebssystems deaktiviert.
Der folgende Registrierungsschlüssel und mögliche Werte steuern den Kopiervorgang. Der Schlüssel ist standardmäßig nicht vorhanden.
DWORD RTL_REGISTRY_CONTROL\GraphicsDrivers\DriverStoreCopyMode
Wert | Beschreibung |
---|---|
0 | Kopieren des Treiberspeichers deaktivieren |
1 | Normaler Vorgang (Kopieren der Treiberspeicherdateien aktivieren und vorhandene Dateien nicht überschreiben). |
2 | Aktivieren Sie das Kopieren des Treiberspeichers und überschreiben Sie vorhandene Dateien. |
Zugriff auf die Registrierung über UMD
Die KMD-Registrierungsschlüssel sind auf dem Host vorhanden und werden nicht auf die VM übertragen. Daher kann die UMD diese Treiberregistrierungsschlüssel nicht direkt lesen. Der pfnQueryAdapterInfoCb2-Rückruf wird der D3DDDI_ADAPTERCALLBACKS-Struktur der D3D-Runtime hinzugefügt. UMD kann pfnQueryAdapterInfoCb2 mit folgender Festlegung von D3DDDICB_QUERYADAPTERINFO2 aufrufen, um bestimmte Registrierungsschlüssel zu lesen:
- D3DDDICB_QUERYADAPTERINFO2::QueryType auf D3DDDI_QUERYADAPTERTYPE_QUERYREGISTRY festgelegt.
- pPrivateDriverData- verweist auf einen Puffer mit einer D3DDDI_QUERYREGISTRY_INFO Struktur, in der die Registrierungsinformationen zurückgegeben werden sollen. UMD besetzt die folgenden Mitglieder:
- D3DDDI_QUERYREGISTRY_INFO::QueryType gibt den Typ des Registrierungszugriffs an; Beispiel: Dienstschlüssel, Adapterschlüssel oder Treiberspeicherpfad.
- D3DDDI_QUERYREGISTRY_FLAGS::QueryFlags gibt die Flags für die Abfrage an.
- ValueName gibt den Namen des zu lesenden Werts an.
- ValueType- gibt den Typ des zu lesenden Werts an.
- PrivateDriverDataSize ist
sizeof(D3DDDI_QUERYREGISTRY_INFO)
plus die Größe des Puffers für den Ausgabewert mit dynamischer Größe.
UMD kann D3DKMTQueryAdapterInfo auch direkt aufrufen. Dieser Aufruf ist für UMD im Gast nützlich, da er an den Host gemarshallt wird und eine Möglichkeit bietet, bestimmte Namen in den Gastnamensraum zu übersetzen.
D3DKMTQueryAdapterInfo wird aufgerufen, wobei D3DKMT_QUERYADAPTERINFO wie folgt festgelegt wird, um bestimmte Registrierungsschlüssel zu lesen:
- Typ ist auf KMTQAITYPE_QUERYREGISTRY festgelegt.
- pPrivateDriverData verweist auf eine D3DKMT_ADAPTERREGISTRYINFO Struktur
- PrivateDriverDataSize ist
sizeof(D3DKMT_ADAPTERREGISTRYINFO)
plus die Größe des Puffers für den Ausgabewert mit dynamischer Größe.
Beispiel 1: Lesen eines Werts aus dem Dienstschlüssel
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");
}
}
Beispiel 2: Lesen des Treiberspeicherpfads
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
}
Kopieren von Dateien in %windir%\system32 und %windir%\syswow64- auf dem virtuellen Computer
In einigen Fällen müssen die Treiberbenutzermodus-DLLs in den Verzeichnissen %windir%\system32 und %windir%\syswow64 vorhanden sein.
Das Betriebssystem bietet dem Treiber eine Möglichkeit, Dateien anzugeben, die aus dem Treiberspeicher auf dem Host in %windir%\system32 oder %windir%\syswow64 im Gast kopiert werden sollen.
In der Installation inF kann der Treiber mehrere Werte in den folgenden Unterschlüsseln im Registrierungsschlüssel des Grafikadapters definieren:
- CopyToVmOverwrite
- CopyToVmWhenNewer
- CopyToVmOverwriteWow64
- CopyToVmWhenNewerWow64
Die CopyToVmOverwrite und CopyToVmWhenNewer Unterschlüssel werden verwendet, um Dateien in das %windir%\system32 Verzeichnis zu kopieren.
Die CopyToVmOverwriteWow64 und CopyToVmWhenNewerWow64 Unterschlüssel werden verwendet, um Dateien in das %windir%\syswow64 Verzeichnis zu kopieren.
Die Dateien unter CopyToVmOverwrite und CopyToVmOverwriteWow64 überschreiben immer die Dateien am Zielort.
Die Dateien unter CopyToVmWhenNewer und CopyToVmWhenNewerWow64 überschreiben die Dateien im Ziel nur, wenn das Änderungsdatum einer Datei neuer ist. Die "neueren" Kriterien vergleichen zwei Informationsabschnitte:
- FileVersion
- Letzte Schreibzeit
Wenn die Zieldatei mit dem .dll- oder .exe-Suffix endet, wird fileVersion als der wichtigste Vergleichswert verwendet, bei dem die größte Version als "neuer" gilt. Wenn die Zieldatei nicht mit dem .dll oder .exe Suffix endet oder die beiden FileVersion gleich sind, wird LastWriteTime als die am wenigsten signifikanten Vergleichswerte verwendet, bei denen das spätere Datum/die spätere Uhrzeit als "neuer" gilt.
Jeder Werttyp unter einem Unterschlüssel muss REG_MULTI_SZ oder REG_SZ sein. Wenn der Werttyp REG_MULTI_SZ ist, sollte der Wert maximal zwei Zeichenfolgen enthalten. Diese Anforderung bedeutet, dass jeder Wert eine einzelne Zeichenfolge oder ein Paar Zeichenfolgen definiert, wobei die zweite Zeichenfolge leer sein könnte.
Der Vorname in einem Paar ist ein Pfad zu einer Datei im Treiberspeicher. Der Pfad ist relativ zum Stamm des Treiberspeichers und kann Unterverzeichnisse enthalten.
Der zweite Name in einem Paar ist der Name der Datei, wie sie im verzeichnis %windir%\system32
oder %windir%\syswow64
angezeigt werden soll. Der zweite Name sollte nur der Dateiname sein, nicht einschließlich Pfad.
Wenn der zweite Name leer ist, entspricht der Dateiname dem im Treiberspeicher (mit Ausnahme von Unterverzeichnissen).
Dieser Ansatz ermöglicht es dem Treiber, im Hosttreiberspeicher und im Gast unterschiedliche Namen zu haben.
Beispiel 1
Das folgende Beispiel zeigt, wie man das Betriebssystem dazu bringt, <DriverStorePath>\CopyToVm\softgpu1.dll
nach %windir%\system32\softgpu2.dll
zu kopieren.
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"
Beispiel 2
Das folgende Beispiel zeigt, wie Sie das Betriebssystem dazu bringen, <DriverStorePath>\softgpu1.dll
nach %windir%\system32\softgpu.dll
und <DriverStorePath>\softgpu2.dll
nach %windir%\system32\softgpu2.dll
zu kopieren.
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””
Beispiel 3
Das folgende Beispiel zeigt, wie Sie das Betriebssystem dazu bringen, <DriverStorePath>\Subdir1\Subdir2\softgpu2wow64.dll
in %windir%\syswow64\softgpu.dll
und <DriverStorePath>\softgpu.dll
zu %windir%\syswow64\softgpu2wow64.dll
zu kopieren.
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
Änderungen an DxgkDdiCreateProcess
Die DxgkDdiCreateProcess--Funktion von KMD muss aktualisiert werden, um VM-Arbeitsprozesse und VM-Prozesse zu unterstützen. Die folgenden Felder werden der DXGKARG_CREATEPROCESS Struktur hinzugefügt:
- hKmdVmWorkerProcess
- ProcessNameLength
- pProcessName
Die folgenden Flags werden DXGK_CREATEPROCESSFLAGS hinzugefügt, um VM-Workerprozesse und VM-Prozesse zu unterstützen:
- VirtualMachineProcess
- VirtualMachineWorkerProcess
DxgkDdiSetVirtualMachineData
DxgkDdiSetVirtualMachineData wird für Dxgkrnl hinzugefügt, um Informationen über einen virtuellen Computer an den KMD zu übergeben.
Asynchrone VM-Busnachrichten an den Host
Einige Nachrichten von Dxgkrnl im Gastbetriebssystem zur Host-Maschine sind asynchron. Dieser Ansatz verbessert die Leistung sehr häufiger Dxgkrnl-API-Aufrufe im Gast. Der Aufwand jeder synchronen VM-Busnachricht an den Host kann hoch sein.
Zu den asynchronen Nachrichten gehören:
- D3DKMTSubmitCommand
- D3DKMTSubmitCommandToHardwareQueue
- D3DKMTSignalSynchronizationObjectFromGpu
- D3DKMTWaitForSynchronizationObjectFromGpu
LDA-Unterstützung in GPU-PV
Verknüpfte Grafikkarten (Linked Display Adapter, LDA) werden in GPU-PV unterstützt. Um eine konsistente Implementierung und die Unterstützung möglicher zukünftiger Rückportierungen der LDA-Unterstützung auf ältere Windows-Versionen sicherzustellen, muss die KMD die LDA-Unterstützung in GPU-PV überprüfen, indem sie DxgkCbIsFeatureEnabled(DXGK_FEATURE_LDA_GPUPV)aufruft. Die Unterstützung ist aktiviert, wenn die Funktion erfolgreich ist und Enabledzurückgibt. Wenn der KMD diesen Rückruf nicht aufruft, geht Dxgkrnl davon aus, dass der KMD LDA in GPU-PV nicht unterstützt.
Wenn das Betriebssystem das Feature unterstützt, liegt es bei dem Treiber, LDA im Benutzermodus zu aktivieren. Wenn der Treiber LDA im Benutzermodus aktiviert, sollte dies wie folgt ausgeführt werden.
Laufzeit | LDA state |
---|---|
Laufzeit vor D3D12 | Aktivieren, wenn DXGK_FEATURE_LDA_GPUPV unterstützt wird und das Gastbetriebssystem Windows 11, Version 22H2 (WDDM 3.1) oder höher ist. |
Nicht-DX-Runtimes (Windows) | Aktivieren, wenn DXGK_FEATURE_LDA_GPUPV unterstützt wird und das Gastbetriebssystem Windows 11, Version 22H2 (WDDM 3.1) oder höher ist. Anstatt die Betriebssystemversion zu überprüfen, konnte die UMD D3DKMTQueryAdapterInfo(KMTQAITYPE_PHYSICALADAPTERCOUNT) aufrufen und LDA aktivieren, wenn sie die Anzahl der physischen Adapter zurückgibt, die größer als 1 sind. |
D3D12-Runtime (Windows) | Aktivieren Siehe Festlegen des LDA-Status für die D3D12-Runtime. |
Linux (d3d12 und Nicht-DX-Runtime) | Aktivieren, wenn DXGK_FEATURE_LDA_GPUPV unterstützt wird. |
Treiber, die mit einer Schnittstellenversion unter DXGKDDI_INTERFACE_VERSION_WDDM3_0 kompiliert wurden, überprüfen DXGK_FEATURE_LDA_GPUPV nicht. Diese Treiber können weiterhin LDA für Linux-Runtimes aktivieren.
Festlegen des LDA-Status für die D3D12-Runtime
Wenn LDA für die D3D12-Laufzeitumgebung ein- oder ausgeschaltet wird, muss die UMD die korrekten Stufen- und Knotenzuordnungsinformationen an die Laufzeitumgebung zurückgeben. Der Codefluss lautet wie folgt:
D3D12 ruft die D3D12_CROSS_NODE_SHARING_TIER-Obergrenze von UMD ab.
D3D12 ruft D3DKMTQueryAdapterInfo(KMTQAITYPE_PHYSICALADAPTERCOUNT) auf, um die Anzahl der physischen Adapter von Dxgkrnl zu ermitteln.
D3D12 ruft pfnQueryNodeMap(PhysicalAdapterCount, &map) auf, um die Zuordnung logischer Knotenindizes zu physischen Knoten abzurufen. Mit Knoten ist in diesem Fall ein physischer Adapter gemeint. Der UMD muss den tatsächlichen physischen Adapterindex in der Zuordnung oder D3D12DDI_NODE_MAP_HIDE_NODE festlegen, um einen Knoten zu deaktivieren.
Basierend auf den pfnQueryNodeMap- Ergebnissen berechnet D3D12 die effektive physische Adapteranzahl, indem die ausgeblendeten Knoten nicht gezählt werden.
Wenn der Status der Ebene und die tatsächliche Anzahl der physischen Adapter nicht übereinstimmen, schlägt die Geräteerstellung in D3D12 fehl. In folgenden Fällen tritt ein Konflikt auf:
- Die Ebene ist D3D12DDI_CROSS_NODE_SHARING_TIER_NOT_SUPPORTED, und die Adapteranzahl ist größer als 1.
- Die Ebene ist nicht D3D12DDI_CROSS_NODE_SHARING_TIER_NOT_SUPPORTED, und die Adapteranzahl ist 1.
Um LDA zu deaktivieren, muss der UMD die Ebene D3D12DDI_CROSS_NODE_SHARING_TIER_NOT_SUPPORTED zurückgeben und nur einen physischen Adapter in der Knotenzuordnung aktiviert lassen.
D3DKMTQueryAdapterInfo(KMTQAITYPE_PHYSICALADAPTERCOUNT)
Eine KMTQAITYPE_PHYSICALADAPTERCOUNT-Abfrage für die Anzahl der physischen Adapter gibt dem Gast immer die korrekte Anzahl der physischen Adapter zurück:
- Bei Gästen vor Windows 11 Version 22H2 wird 1 zurückgegeben. Dieser Wert ist im Gastcode hartcodiert. Es könnte sich in Zukunft ändern, wenn die LDA-Unterstützung zu älteren Betriebssystemversionen portiert wird.
- Unter Windows 11, Version 22H2 und höher, wird Folgendes zurückgegeben:
- Die tatsächliche Anzahl der physischen Adapter, wenn DXGK_FEATURE_LDA_GPUPV aktiviert ist.
- Andernfalls 1.
Aktivieren der Paravirtualisierung
Aktivieren Sie die Virtualisierungsunterstützung im BIOS (VT-d oder ähnlich). GPU-PV Setup unterscheidet sich für virtuelle VMMS-Computer und die Container.
Aktivieren Sie in PowerShell (als Administrator ausgeführt) die Skriptausführung auf dem Server:
set-executionpolicy unrestricted
Einrichtung des virtuellen VMMS-Computers
Einrichten des Hosts und der VM
Der Betriebssystembuild auf dem virtuellen Computer kann älter oder neuer sein als der Betriebssystembuild auf dem Host.
Aktivieren Sie die Hyper-V-Funktion in den Serverrollen oder das feature Hyper-V auf dem Client. Wenn Sie dieses Feature auf dem Server aktivieren, wählen Sie die Option aus, um den Netzwerkadapter als externen Switch zu verwenden.
(optional) Aktivieren Sie die Testsignierung (bcdedit -set TESTSIGNING ON).
Neustart.
Installieren Sie einen GPU-Treiber, der die Paravirtualisierung unterstützt.
(optional) Einige Treiber setzen die legen die ParavirtualizationSupported-Obergrenze nicht fest. Fügen Sie in diesem Fall den folgenden Registry-Eintrag hinzu, bevor Sie den Treiber installieren, oder deaktivieren und aktivieren Sie das Gerät erneut, nachdem das Flag gesetzt wurde.
DWORD HKLM\System\CurrentControlSet\Control\GraphicsDrivers\GpuVirtualizationFlags = 1
Um zu überprüfen, ob das Betriebssystem die paravirtualisierte GPU erkennt, führen Sie den folgenden PowerShell-Befehl aus:
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
Führen Sie die folgenden Befehle in PowerShell aus, um einen virtuellen Computer mit GPU zu erstellen. Eine VM namens TEST wird erstellt.
$vm = “TEST“ New-VM -VMName $vm -Generation 2 Set-VM -GuestControlledCacheTypes $true -VMName $vm
Legen Sie den E/A-Speicherplatz für den virtuellen Computer fest. GPU-PV verwendet E/A-Speicherplatz, um CPU-sichtbare Zuweisungen zu verarbeiten. Mindestens 8 GB E/A-Speicherplatz sind erforderlich.
Set-VM -LowMemoryMappedIoSpace 1GB -VMName $vm Set-VM -HighMemoryMappedIoSpace 16GB -VMName $vm
[optional] Standardmäßig ist die Basisadresse für den E/A-Speicherplatz mit hohem Arbeitsspeicher auf (64 GB - 512 MB) festgelegt. Auf Haswell-Chipsatzen mit 36-Bit-Physischer Speicheradressierung muss die Endadresse der E/A-Raumregion unter 64 GB liegen, sodass die Startadresse entsprechend festgelegt werden muss. Das folgende Skript mit dem Namen SetHighMmioBase.ps1legt die Startadresse bei ausführung mit den folgenden Parametern auf 47 GB fest:
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" }
Fügen Sie der VM eine virtuelle GPU hinzu, und deaktivieren Sie Prüfpunkte.
Add-VMGpuPartitionAdapter -VMName $vm Set-VM -CheckpointType Disabled -VMName $vm
Führen Sie den folgenden Befehl aus, um zu überprüfen, ob der virtuelle Computer über eine paravirtualisierte GPU verfügt:
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 :
Kopieren Sie das VHDX-Image desselben Clientbuilds, den Sie in der VM verwenden, auf ein Hostverzeichnis. Beispiel:
d:\VM\os.vhdx
.Öffnen Sie Hyper-V Manager, und ändern Sie VM-Parameter (wählen Sie "VM" und dann "Einstellungen" aus):
- Sicherheit: Deaktivieren Sie Sicheren Start aktivieren.
- Arbeitsspeicher: Aktivieren Sie Dynamischen Arbeitsspeicher aktivieren. Legen Sie die Arbeitsspeichermenge auf 1.024 MB oder mehr fest.
- Prozessor – Legen Sie Anzahl virtueller Prozessoren auf 2 oder 4 fest.
- Netzwerkadapter – Wählen Sie den Netzwerkadapter aus, der im Dropdownfeld mit dem virtuellen Computer verwendet werden soll. Wenn das Netzwerkdebugging aktiviert ist, stellen Sie sicher, dass Sie den Microsoft Debugging NET-Adapter auswählen.
- SCSI-Controller - Festplatte - Hinzufügen – virtuelle Festplatte – Durchsuchen –
d:\VM\os.vhdx
auswählen
Das Betriebssystem kopiert die Dateien aus dem Hosttreiberspeicher in das HostDriverStore-Verzeichnis im Gast, wenn der Adapter im Gast initialisiert wird.
- Binden Sie die VHDX der VM ein. Zum Beispiel auf der Festplatte f:.
- Erstellen Sie auf der bereitgestellten VM ein Verzeichnis namens f:\%windir%\system32\HostDriverStore\FileRepository.
- Replizieren Sie Treiberdateien aus %windir%\system32\DriverStore- im Host auf die VM. Es sollte f:\%windir%\system32\HostDriverStore\FileRepository\YourDriverDirectory\* auf dem virtuellen Computer vorhanden sein.
Wenn der Treiber von
%windir%\system32
oder%windir%\syswow64
auf Dateien zugreifen muss, kopieren Sie die Dateien manuell auf den virtuellen Computer.Aktivieren Sie die Testanmeldung auf dem virtuellen Computer, wenn die Treiber nicht von Microsoft signiert sind. Führen Sie im CMD-Administratorfenster den folgenden Befehl aus:
bcdedit /store <VM drive>:\EFI\Microsoft\Boot\BCD -set {bootmgr} testsigning on
Heben Sie die Einbindung der VHDX der VM auf.
Starten Sie den virtuellen Computer.
Stellen Sie eine Verbindung mit dem virtuellen Computer mithilfe der Option Hyper-V Manager Connect her.
INNERHALB DER VM
Überprüfen Sie, ob ein virtuelles Rendergerät im Geräte-Manager des virtuellen Computers vorhanden ist. Das gesamte Rendering innerhalb des virtuellen Computers durchläuft virtuelle GPU.
PowerShell-Skript zum Einrichten einer VM
Das folgende PowerShell-Skript ist ein Beispiel für das Einrichten eines virtuellen Computers von Grund auf. Ändern Sie sie entsprechend Ihren Anforderungen.
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
}
Debuggen des virtuellen Computers
Konfigurieren Sie den VM-Debugger auf dieselbe Weise wie das Netzwerkdebugging auf einem normalen Clientcomputer.
Wenn der virtuelle Computer nicht gestartet wird oder ein schwarzer Bildschirm angezeigt wird:
Deaktivieren Sie den virtuellen Computer, und entfernen Sie die virtuelle GPU mit den folgenden Befehlen:
$vm = “TEST“ remove-VMGpuPartitionAdapter -VMName $vm -AdapterId “<Id from Get-VMGpuPartitionAdapter>”
Zum Beispiel:
remove-VMGpuPartitionAdapter -VMName $vm -AdapterId “Microsoft:9ABB95E2-D12D-43C3-B840-6F4A9CFB217B\929890BC-BB33-4687-BC1A-F72A4F1B3B3F”
Starten Sie den virtuellen Computer. Wenn sie erfolgreich gestartet wird, stellen Sie sicher, dass die Treiberdateien ordnungsgemäß in den HostDriverStore auf dem virtuellen Computer kopiert werden.
Fügen Sie der VM mithilfe des Befehls
Add-VMGpuPartitionAdapter
vGPU hinzu.Starten Sie den virtuellen Computer erneut.
Weitere Informationen finden Sie unter Problembehandlung.
Containereinrichtung
Der Unterschied zwischen Containern (auch als Host Compute System (HCS)-VMs bezeichnet) und dem vollständigen virtuellen Computer besteht darin, dass die Binärdateien des Betriebssystems und treiberspeicherdateien dem Container zugeordnet werden. Es ist also nicht erforderlich, die Treiberdateien in den Container zu kopieren, es sei denn, sie sind im windows\system32
Verzeichnis erforderlich.
Für sichere Container:
- Treiberescapes sind deaktiviert.
- Der Treiber muss die IOMMU-Isolation unterstützen, um in einem sicheren Container aktiviert zu werden.
Wenn Sie den Treiber auf dem Host aktualisieren und die Host-GPU starten oder beenden, werden die Änderungen im Container wiedergegeben.
Windows-Sandkasten
Dieser Containertyp wird verwendet, um riskante Anwendungen auszuprobieren. Das vollständige Desktopimage wird per Remoting an den Host übertragen. Zum Remoting wir der Treiber für indirekte Anzeige verwendet. Grafik-VAIL wird nicht verwendet, sodass das Desktopimage langsam auf den Host übertragen wird.
Virtuelle GPU ist in der Windows-Sandbox standardmäßig deaktiviert. Erstellen Sie zum Aktivieren eine WSB-Konfigurationsdatei (z. B. config.wsb), und legen Sie die virtuelle GPU-Option fest. Starten Sie den Sandkasten, indem Sie auf die Konfigurationsdatei klicken.
Beispiel für eine Konfigurationsdatei:
<Configuration>
<VGpu>Enable</VGpu>
</Configuration>
Standardmäßig sind die Treiberescapes für die vGPU im Container deaktiviert. Es gibt eine Konfigurationsoption, um Treiberescapes zu aktivieren. Mit dem folgenden Beispiel für eine WSB-Datei werden sowohl vGPU in der Sandbox als auch Treiberescapes aktiviert:
<Configuration>
<VGpu>EnableVendorExtensions</VGpu>
</Configuration>
Die Windows-Sandbox unterstützt den GPU-Adapter "Hot Plug".
VAIL-Container (Virtual Application Integrated Locally)
Verwenden Sie diesen Containertyp, um Win32-Anwendungen innerhalb eines WCOS-basierten Hosts (Windows Core Operated System) auszuführen. Das Image jeder Anwendung im Container wird per Remoting an den Host übertragen. Grafik-VAIL ist aktiviert, um jede Anwendungs-Swapchain fernzusteuern. Treiberescapes sind aktiviert.
Allgemeine Containeranforderungen
Computeranforderungen sind:
- Sowohl Vtx als auch Vtd müssen im BIOS (oder deren Entsprechungen: AMD-V, AMD-IOMMU) aktiviert sein.
- Mindestens 8 GB RAM.
- Mehr als 5 GB Systemspeicherplatz.
Einrichten des Kerneldebuggers für Windows-Sandbox
Verwenden von CMDIAG
Ein Container-Manager-Dienst (cmservice) steuert Hyper-V isolierte Container. CMDIAG.EXE ist eine Anwendung, die verfügbar ist, wenn Sie die Hyper-V- und Container-Features installieren. Es ermöglicht das Debuggen im Kernelmodus für Container, ermöglicht die Testsignierung und vieles mehr.
Der Container-Manager unterstützt das serielle und NET-Debugging.
Führen Sie cmdiag.exe Debug
aus, um die Optionen anzuzeigen.
CMDIAG ändert Debuggereinstellungen im Containerbasisimage. Es sollte nur eine Instanz eines Containers vorhanden sein, der ausgeführt wird, wenn der Kerneldebugger aktiviert ist.
Beenden Sie den HVSICS-Dienst, bevor Sie die Debuggereinstellungen ändern.
# 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
Ausführen des Debuggers auf einem anderen Computer
Wenn Sie den seriellen Debugger verwenden, sollten Sie ihn auf einem anderen Computer ausführen. Verwenden Sie kdsrv.exe
, um den Debugger auf einem anderen Computer auszuführen. Weitere Informationen finden Sie unter KD-Verbindungsserver.
Um Timeouts während des Kerneldebuggings zu deaktivieren, legen Sie die folgenden Registrierungsschlüssel fest:
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
Einrichten des Kerneldebuggers für VAIL-Container
- Stellen Sie mithilfe von Telnet eine Verbindung mit dem Host her. Sie können die IP-Adresse des Hosts aus den Netzwerkeinstellungen im Hostbetriebssystem abrufen.
- Verwenden Sie
cmdiag.exe
, um den Debugger zu konfigurieren.
Einrichten des Hypervisor-Debuggers
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
Fehlerbehebung
Dieser Abschnitt enthält Informationen zum Behandeln von Problemen mit GPU-PV.
Get-VMHostPartitionableGpu
Rufen Sie Get-VMHostPartitionableGpu auf, um festzustellen, ob eine virtualisierte GPU vorhanden ist. Wenn die Ausgabe leer ist, gibt es irgendwo einen Fehler (Treiber hat die Virtualisierungscap nicht festgelegt, Virtualisierung ist nicht aktiviert usw.).
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
Verwenden von ETW-Ereignissen
Dxgkrnl verfügt über Administrator- und Betriebskanäle für ETW-Ereignisse. Die Ereignisse werden in der Windows-Ereignisanzeige angezeigt: Anwendungs- und Dienstprotokoll - Microsoft - Windows - Dxgkrnl.
Die Ereignisanzeige verfügt über Ereignisse aus anderen Komponenten, die an der Erstellung eines virtuellen Computers mit GPU-PV teilnehmen (Hyper-V-Compute, Hyper-V-Worker, Hyper-V-VID usw.).
Verwenden von Add-VMGpuPartitionAdapter
Bei Verwendung von Add-VMGpuPartitionAdapter geben Sie eine Fähigkeit (z. B. Dekodieren) nicht an, wenn diese nicht benötigt wird. Verwenden Sie 0 nicht für diese Funktion.
Verwenden von Remove-VMGpuPartitionAdapter
Wenn ein virtueller Computer Fehler beim Starten oder Rendering-Probleme hat, versuchen Sie, die virtuelle GPU mithilfe von Remove-VMGpuPartitionAdapteraus dem virtuellen Computer zu entfernen.
remove-VMGpuPartitionAdapter -VMName $vm -AdapterId "Microsoft:9ABB95E2-D12D-43C3-B840-6F4A9CFB217B\929890BC-BB33-4687-BC1A-F72A4F1B3B3F"
Verhindern des Startens des virtuellen Computers während des Starts
set-vm -AutomaticStartAction Nothing -VmName TEST
Ereignisse der Ereignisanzeige
Fügen Sie dem Ereignisanzeigekanal Ereignisse hinzu, um Probleme beim vGPU-Start zu identifizieren. Die Ereignisse finden Sie unter "Anwendungs- und Dienstprotokolle\Microsoft\Windows\Dxgkrnl". Die Ereigniskanäle sind "Admin" und "Operational".
Ereignisse werden ausgegeben, wenn:
- vGPU erstellt wird
- vGPU wird zerstört
- Der Gast öffnet einen virtuellen Adapter.
Die Ereignisdateien sind in:
- c:\Windows\System32\winevt\Logs\Microsoft-Windows-DxgKrnl-Admin.evtx
- c:\Windows\System32\winevt\Logs\Microsoft-Windows-DxgKrnl-Operational.evtx
Überprüfen Sie, ob eine vGPU erstellt wurde und ob Fehler vorhanden sind.
Registrierungseinstellungen
GpuVirtualizationFlags
Der GpuVirtualizationFlags-Registrierungsschlüssel wird verwendet, um das Verhalten von paravirtualisierten GPUs festzulegen. Der Schlüssel befindet sich in:
DWORD HKLM\System\CurrentControlSet\Control\GraphicsDrivers\GpuVirtualizationFlags
Die folgenden Bits sind definiert:
Bit | Beschreibung |
---|---|
0x1 | Erzwingen Sie die ParavirtualizationSupported-Obergrenze für alle Hardwareadapter. Verwenden Sie dieses Bit im Host. |
0x2 | Erzwingen Sie die ParavirtualizationSupported-Obergrenze für BasicRender. Verwenden Sie dieses Bit im Host. |
0x4 | Erzwingen Sie den modus "Sicherer virtueller Computer", in dem alle virtuellen Computer als sicher behandelt werden. In diesem Modus gibt es Einschränkungen für den Benutzermodustreiber. Beispielsweise kann der Treiber keine Escapeaufrufe verwenden, sodass diese fehlschlagen. Verwenden Sie dieses Bit im Host. |
0x8 | Aktivieren Sie die Kopplung von paravirtualisierten Adaptern mit dem ausschließlich für die Anzeige vorgesehenen Adapter. Verwenden Sie dieses Bit in der Gast-VM. Die Kopplung ist standardmäßig aktiviert. |
GuestIoSpaceSizeInMb
Der Registrierungsschlüssel "GuestIoSpaceSizeInMb" wird verwendet, um die Größe des Gast-E/A-Raums für virtuelle GPUs in Megabyte festzulegen. Der Standardwert ist 1.000 MB (1 GB). Der Schlüssel befindet sich unter:
DWORD HKLM\System\CurrentControlSet\Control\GraphicsDrivers\Paravirtualization\GuestIoSpaceSizeInMb
Der Gast-E/A-Bereich führt derzeit CPU-sichtbare Zuweisungen durch. Ein CPU-sichtbarer Zuweisungssicherungsspeicher im Host wird im Speicher angeheftet und dem Gast-E/A-Bereich zugeordnet. Im Gast wird die virtuelle Adresse der Zuweisung im Benutzermodus in den E/A-Bereich rotiert. Auf einigen Haswell-Systemen verfügt die CPU über 36-Bit-physische Adressen. Hyper-V in solchen Systemen hat eine begrenzte E/A-Bereichsgröße.
Deaktivieren der IOMMU-Isolierung für sichere virtuelle Computer
Wenn ein Treiber die IoMmu-Isolation nicht unterstützt, verwenden Sie während der Entwicklung die folgende Registrierungseinstellung, um die IoMmu-Isolation zu deaktivieren.
`DWORD HKLM\SYSTEM\CurrentControlSet\Control\GraphicsDrivers\IoMmuFlags = 8`
Begrenzen Sie die Anzahl der virtuellen Funktionen
Standardmäßig ist die Anzahl der virtuellen Funktionen, die von einem Adapter verfügbar gemacht werden, der GPU-Paravirtualisierung unterstützt, 32. Diese Zahl bedeutet, dass der Adapter zu 32 virtuellen Computern hinzugefügt werden kann, vorausgesetzt, jede VM verfügt über einen Adapter.
Sie können die folgende Registrierungseinstellung verwenden, um die Anzahl der verfügbar gemachten virtuellen Funktionen einzuschränken.
DWORD HKLM\SYSTEM\CurrentControlSet\Control\GraphicsDrivers\NumVirtualFunctions
Wenn Sie z. B. NumVirtualFunctions
auf 1 festlegen, kann der Adapter nur einmal einer GPU hinzugefügt werden. Diese Einstellung ist nützlich, wenn ein Computer über mehrere GPU-Adapter verfügt, die GPU-PV unterstützen, und Sie jeden Adapter einem virtuellen Computer zuweisen möchten. Add-VMGpuPartitionAdapter
lässt nicht zu, dass Sie angeben, welcher Adapter hinzugefügt werden soll. Wenn also zwei Adapter zu einem virtuellen Computer hinzugefügt werden, könnten beide den gleichen GPU-PV Adapter vom Host abrufen.
WDDM 2.4 DDI-Updates
Die folgenden DDI-Updates werden zur Unterstützung der GPU-Paravirtualisierung in WDDM 2.4 vorgenommen.
DXGK_VIDMMCAPS-Obergrenze hinzugefügt
Die ParavirtualizationSupported-Funktion wird der DXGK_VIDMMCAPS-Struktur hinzugefügt. Der Host-KMD legt diese Obergrenze fest, wenn alle in diesem Abschnitt beschriebenen DDIs implementiert werden.
Private Treiberdaten, die über DDI übergeben werden
Die UMD verwendet verschiedene DDIs, um private Informationen mit dem entsprechenden KMD auszutauschen. Wenn die UMD auf der Gast-VM ausgeführt wird, erfolgt der entsprechende KMD DDI-Aufruf in der Hostpartition. Daher gilt für den UMD Folgendes:
- Es können keine Zeiger in den privaten Daten übergeben werden.
- Es können keine Handles in den privaten Daten übergeben werden.
- Sollte die KMD nicht anweisen, globale Änderungen des GPU-Zustands vorzunehmen, da sich diese Änderung auf andere ausgeführte VMs auswirken könnte.
VirtualMachineProcess-Flag für DxgkDdiCreateProcess hinzugefügt
Das Betriebssystem erstellt einen VM-Arbeitsprozess für jeden ausgeführten virtuellen Computer. Dxgkrnl erstellt einen entsprechenden DXGPROCESS und ruft DxgkDdiCreateProcess auf, wobei das VirtualMachineWorkerProcess-Flag festgelegt ist. In diesem Prozesskontext gibt es keine Rendering- oder Treiberressourcenerstellung. Der Treiber kann also die Zuordnung bestimmter Ressourcen überspringen.
Das Betriebssystem erstellt einen DXGPROCESS im Host für jeden Prozess in einem Gastcomputer, der eine GPU verwendet. Dxgkrnl ruft DxgkDdiCreateProcess auf, wobei das VirtualMachineProcess-Flag festgelegt ist. Jeder VM DXG-Prozess gehört zum gleichen EPROCESS-Prozess wie der VM-Arbeitsprozess.
DxgkDdiQueryAdapterInfo-Updates
Die DXGKARG_QUERYADAPTERINFO Struktur wird aktualisiert, um die folgenden Felder für die Unterstützung der Paravirtualisierung einzuschließen:
Das Flags-Element wird hinzugefügt, wodurch Dxgkrnl Folgendes angeben kann:
- Es legt VirtualMachineData- fest, um anzugeben, dass der Aufruf von einer VM stammt.
- Es legt SecureVirtualMachine fest, um anzugeben, dass der virtuelle Computer im abgesicherten Modus ausgeführt wird.
hKmdProcessHandle hinzugefügt wird, wodurch der Treiber den richtigen Prozesskontext auf der Hostseite identifizieren und verwenden kann, wenn es um Abfragen geht, die von einer Gast-VM stammen.
DxgkDdiEscape-Aktualisierungen
Das hKmdProcessHandle-Element wird der DXGKARG_ESCAPE-Struktur hinzugefügt, damit der Treiber den korrekten Prozesskontext auf der Hostseite identifizieren und verwenden kann, wenn es um Escapesequenzen geht, die von einer Gast-VM stammen.
Das VirtualMachineData-Flag wird der D3DDDI_ESCAPEFLAGS-Struktur hinzugefügt, um anzugeben, dass DxgkDdiEscape von einem virtuellen Computer aufgerufen wird.
Physischer Zugriff auf GPU-Zuordnungen
Derzeit implementiert der Treiber keinen physischen Zugriff auf die Zuordnungen. Der Treiber muss GpuMmu unterstützen.
WDDM 2.5 DDI-Updates
Für WDDM 2.5 sind auch die folgenden DDI-Änderungen für die Unterstützung der Paravirtualisierung erforderlich.
Signalisierung von Gastveranstaltungen durch den Host-KMD
Es gibt Szenarien, die ohne Virtualisierung vorhanden sind, wenn die KMD ein ereignis signalisieren muss, das von einer UMD erstellt wurde. Um solche Szenarien zu verarbeiten, wenn Paravirtualisierung verwendet wird, muss der KMD auf dem Host ein im Gast erstelltes Ereignis signalisieren. Der DxgkCbSignalEvent-Rückruf wird zu diesem Zweck hinzugefügt. KMD kann diesen Rückruf auch verwenden, um Ereignisse der Hostprozesse zu signalisieren.
Unterstützung für UMD-bereitgestellte Handles in einer VM
Bestimmte Treiberrückrufe akzeptieren eine Dxgkrnl-Zuweisung oder ein Ressourcenhandle, das der UMD übergibt, wie zum Beispiel:
Die Aufrufe des Hosts müssen sich im Kontext desselben Threads befinden, der eine DxgkDdi-Xxx--Funktion aufgerufen hat.
Beispiel: Angenommen, ohne Virtualisierung ruft der KMD DxgkCbAcquireHandleData im Kontext des Benutzermodusthreads auf, der D3DKMTEscape aufruft, das wiederum DxgkDdiEscape aufruft.
Wenn UMD auf einem virtuellen Computer ausgeführt wird, kennt sie nur die Gastzuweisungshandles und kann solche Handles nicht an die KMD übergeben, da KMD auf dem Host ausgeführt wird. Der UMD im Gast ruft D3DKMTEscape auf, und der KMD im Host empfängt den entsprechenden DxgkDdiEscape-Aufruf. Der KMD muss DxgkCbAcquireHandleData im Kontext dieses Threads aufrufen.
Um die Gastzuweisung/das Ressourcenhandle in das entsprechende Hosthandle übersetzen zu können, wird das Treiberescapeflag D3DDDI_ESCAPEFLAGS::DriverKnownEscape hinzugefügt.
Wenn Sie D3DKMTEscape mit festgelegtem DriverKnownEscape-Flag aufrufen:
Legen Sie D3DKMT_ESCAPE::Type auf D3DKMT_ESCAPE_DRIVERPRIVATEfest.
Legen Sie D3DKMT_ESCAPE::pPrivateDriverData so fest, dass es auf eine bekannte Treiberescapestruktur verweist, die im folgenden Abschnitt definiert ist. Jede Struktur beginnt mit einem D3DDDI_DRIVERESCAPETYPE Wert.
Wenn die Virtualisierung nicht verwendet wird, entspricht das übersetzte Handle dem Eingabehandle.
Die folgenden bekannten Treiberescapes sind definiert.
Der folgende Codeausschnitt veranschaulicht die Verwendung des DriverKnownEscape- Flags.
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);
WDDM 2.6 DDI-Updates
Ab WDDM 2.6 (Windows 10, Version 1903) wurden die folgenden Updates für die Unterstützung der Paravirtualisierung vorgenommen:
Der Treiber kann das DXGK_ALLOCATIONINFOFLAGS::ACCESSEDPHYSICALLY-Flag auf einem virtuellen Computer verwenden. Vor WDDM 2.6 konnte der Treiber dieses Kennzeichen nicht in einem virtuellen Computer verwenden, und die Zuordnungserstellung mit diesem Flag ist fehlgeschlagen.
UMD kann Pfnd3dkmtUpdateallocationproperty in einem virtuellen Computer verwenden. Vor WDDM 2.6 schlägt dieser Aufruf fehl.