Paravirtualización de GPU
En este artículo se describe la paravirtualización de GPU en WDDM. Esta característica está disponible a partir de Windows 10, versión 1803 (WDDM 2.4).
Acerca de la virtualización de GPU
La virtualización de GPU es una característica importante para windows Client y Windows Server. Hay muchos escenarios que requieren un uso eficaz de los recursos de GPU en una máquina virtual.
Los escenarios de servidor (donde el sistema operativo host no ejecuta aplicaciones de usuario) incluyen:
- Virtualización de escritorio
- Proceso (IA, ML, etc.)
Los escenarios de cliente (donde el sistema operativo host comparte la GPU entre máquinas virtuales y aplicaciones de usuario) incluyen:
- Desarrollo y prueba de aplicaciones gráficas (donde las pruebas se ejecutan en una máquina virtual)
- Ejecución de aplicaciones en una máquina virtual con fines de seguridad
- Ejecución de Linux en una máquina virtual con aceleración de GPU
Paravirtualización de GPU en WDDM
La paravirtualización (PV) proporciona una interfaz a las máquinas virtuales (VM) que son similares a su hardware subyacente. En PV, debe portar explícitamente el SO invitado antes de instalar una VM, ya que un SO invitado no adaptado no puede ejecutarse sobre un monitor de máquina virtual (VMM).
Ventajas:
- Varias máquinas virtuales comparten los recursos de hardware.
- Es necesario realizar algunos cambios en el código del controlador.
En la ilustración siguiente se muestran varios componentes implicados en el diseño paravirtualizado de WDDM.
Los runtimes de D3D en la máquina virtual invitada no se cambian. Las interfaces con el runtime en modo usuario y con los thunks del kernel KMT siguen siendo las mismas.
Los componentes del controlador no requieren muchos cambios:
El UMD de la máquina virtual invitada debe:
- Tenga en cuenta que las comunicaciones con el controlador del modo kernel (KMD) del host se producen a través del límite de la máquina virtual.
- Utilice los servicios agregados de dxgkrnl para acceder a la configuración del Registro de Windows.
No hay KMD en el invitado, solo UMD. El KMD Virtual Render Device (VRD) sustituye al KMD. El propósito de VRD es facilitar la carga de Dxgkrnl.
No hay ningún administrador de memoria de vídeo (VidMm) ni programador (VidSch) en el sistema huésped.
Dxgkrnl en una VM recibe llamadas thunk y las marshalls a la partición host a través de canales de bus VM. Dxgkrnl en el invitado también crea objetos locales para asignaciones, procesos, dispositivos y otros recursos, lo que reduce el tráfico con el host.
Dispositivo de representación virtual (VRD)
Cuando una GPU paravirtualizada no está presente en una máquina virtual, el Administrador de dispositivos de la máquina virtual muestra el adaptador "Microsoft Hyper-V Video". Este adaptador de solo pantalla se empareja de forma predeterminada con el adaptador BasicRender para la representación.
Al agregar una GPU paravirtualizada a una máquina virtual, el Administrador de dispositivos de la máquina virtual muestra dos adaptadores:
- Adaptador de vídeo de Microsoft Hyper-V o adaptador de pantalla remota de Microsoft
- Controlador de representación virtual de Microsoft (el nombre real es el nombre del adaptador de GPU en el host)
De forma predeterminada, VRD se empareja con el adaptador de vídeo de Hyper-V, por lo que toda la representación de la interfaz de usuario se produce con el adaptador VRD.
Si encuentra problemas de renderizado, puede deshabilitar este emparejamiento utilizando la configuración de registro GpuVirtualizationFlags. En este caso, el adaptador de solo renderizado (VRD) se utiliza cuando una aplicación lo elige específicamente. Por ejemplo, algunos ejemplos de DirectX permiten cambiar el dispositivo de representación. Los entornos de ejecución de Direct3D agregan una salida de pantalla lógica al VRD cuando una aplicación decide usarla.
Al agregar varias GPU virtuales a la máquina virtual, puede haber varios adaptadores VRD en el sistema operativo invitado. Sin embargo, solo se puede emparejar uno de ellos con el adaptador de vídeo Hyper-V. No hay forma de especificar cuál; el sistema operativo elige.
Contenedores y máquinas virtuales
La virtualización de GPU es compatible con máquinas virtuales y contenedores. Los contenedores son máquinas virtuales ligeras, donde los archivos binarios del sistema operativo host se asignan a la máquina virtual contenedora.
Para más información sobre contenedores, ver Windows y contenedores.
Protección de máquinas virtuales
Existen las siguientes limitaciones para una máquina virtual segura:
- Las llamadas a escapes del controlador no están permitidas, excepto los escapes conocidos, que se utilizan con la marca DriverKnownEscape.
- El aislamiento de IoMmu está habilitado. Se produce un error en la creación de máquinas virtuales si el controlador no admite el aislamiento de IoMmu.
Cuando el modo seguro está habilitado:
- DxgkDdiSetVirtualMachineData tiene la marca SecureVirtualMachine activada.
- DxgkDdiQueryAdapterInfo tiene la marca SecureVirtualMachine activada.
Hay configuraciones del Registro para forzar el modo seguro o deshabilitar el aislamiento de IoMmu durante el desarrollo. Para más información, consulte la sección Configuración del Registro.
Acceso remoto del escritorio de la VM/contenedor
Puede acceder remotamente al contenido de un escritorio en una máquina virtual (VM) al host mediante dos métodos:
- adaptador Hyper-V de pantalla
- Acceso remoto a la sesión de terminal
Cuando se utiliza RDP (escritorio remoto) para conectarse a una VM, se utiliza la remoción de sesión de terminal.
El administrador de Hyper-V usa la aplicación de VMConnect para mostrar un escritorio de máquina virtual. VMConnect funciona en dos modos:
- Modo mejorado, que utiliza acceso remoto de sesión de terminal.
- Modo básico, que usa el adaptador de pantalla Hyper-V.
Proceso de trabajo de máquina virtual y memoria de máquina virtual
Al iniciar una máquina virtual o un contenedor, el sistema operativo crea los siguientes procesos en el host:
- Proceso de trabajo de máquina virtual (vmwp.exe)
- Proceso de memoria de máquina virtual (vmmem.exe)
Vmwp contiene varios controladores de dispositivos virtuales, incluyendo vrdumed.dll, el controlador para adaptadores gráficos paravirtualizados.
El espacio de direcciones virtuales del proceso vmmem sirve como respaldo para el espacio IO de la vGPU en el invitado. Cuando el invitado accede al espacio IO, la dirección física resultante es la entrada a la traducción de segundo nivel, que utiliza las tablas de páginas del proceso vmmem.
En un entorno virtualizado, varias llamadas DDI de KMD que normalmente se ejecutan dentro del contexto de un proceso de usuario en el host se ejecutan en su lugar dentro del contexto de la vmmem proceso cuando se ejecuta una máquina virtual.
Dxgkrnl crea un único DXGPROCESS (y el correspondiente objeto de proceso KMD) para estos procesos, que en este artículo se denomina proceso de trabajo VM. El EPROCESS asociado con el proceso de trabajo DXG VM es vmmem.
Procesos de máquina virtual
Cuando se crea un DXGPROCESS en la máquina virtual invitada, Dxgkrnl crea un objeto DXGPROCESS correspondiente en el host. En este artículo, este proceso se denomina proceso de máquina virtual . El EPROCESS asociado con el DXGPROCESS es vmmem.
Todas las operaciones de representación de una máquina virtual o la creación de asignación de máquinas virtuales se realizan en el contexto del DXGPROCESS de la máquina virtual.
Para fines de depuración, Dxgkrnl notifica a KMD sobre qué proceso es un proceso de trabajo VM o proceso VM en DxgkDdiCreateProcess. Con esta información, el controlador puede vincular un proceso de máquina virtual al proceso de trabajo de la máquina virtual. Esta información ayuda a depurar en escenarios en los que se ejecuta más de una máquina virtual.
Requisitos para controladores
Un KMD que soporta paravirtualización GPU necesita establecer la capacidad DXGK_VIDMMCAPS::ParavirtualizationSupported.
El controlador en modo de usuario (UMD) no debe usar ningún dato relacionado con el contexto del proceso en los datos del controlador privado (punteros, identificador, etc.). En su lugar, el KMD obtiene los datos privados en el host en un contexto de proceso diferente.
El UMD en el invitado no puede compartir memoria con el KMD en el host. Debe utilizar las funciones descritas en Acceso al registro desde la UMD para acceder al registro.
La implementación actual de paravirtualización usa el bus de máquina virtual para comunicarse entre el invitado y el host. El tamaño máximo del mensaje es de 128 KB. Actualmente, Dxgkrnl no divide los mensajes para enviarlos en fragmentos. Por lo tanto, el controlador debe limitar el tamaño de los datos privados pasados con la creación de objetos. Por ejemplo, cuando se usa Pfnd3dddiAllocatecb para crear muchas asignaciones, el tamaño total del mensaje incluye un encabezado, datos privados globales, además del tamaño de los datos privados por asignación multiplicados por el número de asignaciones. Esta información debe caber en un solo mensaje.
Ejecución de aplicaciones en modo emulado en pantalla completa
El adaptador de pantalla indirecta debe estar habilitado para la comunicación remota (está habilitado de forma predeterminada). Para deshabilitarlo, realice los pasos siguientes.
- Inicie Editar directiva de grupo
- Vaya a Configuración del equipo->Plantillas administrativas->Componentes de Windows->Servicios de escritorio remoto->Host de sesión de escritorio remoto->Entorno de sesión remoto
- Abra el elemento "Usar controlador de visualización de gráficos WDDM para conexión a Escritorio remoto"
- Seleccione Deshabilitar y seleccione Aceptar.
- Reiniciar
La compatibilidad de DXGI con aplicaciones de pantalla completa en máquinas virtuales está habilitada de forma predeterminada. Para deshabilitarlo, use StagingTool.exe /disable 19316777
.
Las aplicaciones de pantalla completa deben ejecutarse en el modo de pantalla completa emulada.
Habilite eFSE para todas las aplicaciones DXGI y establezca la versión mínima de WDDM para la transición del efecto de intercambio a WDDM 2.0:
D3DEnableFeature.exe /enable DXGI_eFSE_Enablement_Policy
D3DEnableFeature.exe /setvariant DXGI_eFSE_Enablement_Policy 7
eFSE está habilitado de forma predeterminada para las aplicaciones D3D9.
DriverStore en la máquina virtual
Los archivos binarios de controladores del host se encuentran en un almacén de controladores %windir%\system32\drivers\DriverStore\FileRepository<DriverDirectory>.
Para la paravirtualización, se espera que los archivos binarios de UMD de una máquina virtual estén en %windir%\system32\drivers\HostDriverStore\FileRepository<DriverDirectory>.
El KMD del host informa de los nombres de DLL UMD que tienen la ruta completa al almacén de controladores. Por ejemplo, c:\windows\system32\DriverStore\FileRepository\DriverSpecificDirectory\d3dumd.dll.
Cuando la máquina virtual solicita un nombre de UMD, el nombre se traduce a <VmSystemDrive>:\windows\system32\HostDriverStore\FileRepository\DriverSpecificDirectory\d3dumd.dll.
Host DriverStore para contenedores
Para contenedores, Hyper-V mapea el directorio completo del almacén de controladores en el host a <%windir%\HostDriverStore en el contenedor.
Host DriverStore para máquinas virtuales completas
Los archivos del almacén de controladores se copian en la máquina virtual cuando el adaptador de GPU virtual se inicia en la máquina virtual. Esta característica está deshabilitada en la versión publicada del sistema operativo.
La siguiente clave del Registro y los valores posibles controlan la operación de copia. La clave no existe de forma predeterminada.
DWORD RTL_REGISTRY_CONTROL\GraphicsDrivers\DriverStoreCopyMode
Valor | Descripción |
---|---|
0 | Desactivar la copia del almacén de controladores |
1 | Operación normal (habilite la copia de los archivos del almacén de controladores y no sobrescriba los archivos existentes). |
2 | Habilitar la copia del almacén de controladores y sobrescribir los archivos existentes. |
Acceso al registro desde UMD
Las claves del Registro de KMD existen en el host y no se reflejan en la máquina virtual. Por lo tanto, el UMD no puede leer estas claves del Registro del controlador directamente. La llamada de retorno pfnQueryAdapterInfoCb2 se añade a la estructura D3DDDI_ADAPTERCALLBACKS del tiempo de ejecución D3D. UMD puede llamar a pfnQueryAdapterInfoCb2 con D3DDDICB_QUERYADAPTERINFO2 configurado como sigue para leer ciertas claves del registro:
- D3DDDICB_QUERYADAPTERINFO2::QueryType establecido en D3DDDI_QUERYADAPTERTYPE_QUERYREGISTRY.
- pPrivateDriverData apunta a un buffer con una estructura D3DDDI_QUERYREGISTRY_INFO en la que devolver la información del registro. UMD rellena los siguientes miembros:
- D3DDDI_QUERYREGISTRY_INFO::QueryType especifica el tipo de acceso al registro; por ejemplo, clave de servicio, clave de adaptador o ruta del almacén de controladores.
- D3DDDI_QUERYREGISTRY_FLAGS::QueryFlags especifica las marcas de la consulta.
- ValueName identifica el nombre del valor que se va a leer.
- ValueType especifica el tipo del valor que se va a leer.
- PrivateDriverDataSize es
sizeof(D3DDDI_QUERYREGISTRY_INFO)
más el tamaño del búfer para el valor de salida de tamaño dinámico.
UMD también puede llamar a D3DKMTQueryAdapterInfo directamente. Esta llamada es útil para UMD en el invitado porque es marshalled al host y proporciona una forma de traducir ciertos nombres al espacio de nombres del invitado.
D3DKMTQueryAdapterInfo se llama con D3DKMT_QUERYADAPTERINFO configurado como sigue para leer ciertas claves del registro:
- Tipo está establecido en KMTQAITYPE_QUERYREGISTRY
- pPrivateDriverData apunta a una estructura D3DKMT_ADAPTERREGISTRYINFO
- PrivateDriverDataSize es
sizeof(D3DKMT_ADAPTERREGISTRYINFO)
más el tamaño del búfer para el valor de salida de tamaño dinámico.
Ejemplo 1: Lectura de un valor de la clave de servicio
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");
}
}
Ejemplo 2: Lectura de la ruta del almacén de controladores
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
}
Copiar archivos en %windir%\system32 y %windir%\syswow64 en la máquina virtual
En algunos casos, los archivos DLL del modo de usuario del controlador deben estar presentes en los directorios de %windir%\system32 y %windir%\syswow64.
El sistema operativo proporciona una manera de que el controlador especifique los archivos que se deben copiar del almacén de controladores del host a %windir%\system32 o %windir%\syswow64 en el invitado.
En el INF de instalación, el controlador puede definir varios valores en las subclaves siguientes en la clave del Registro del adaptador de gráficos:
- CopyToVmOverwrite
- CopyToVmWhenNewer
- CopyToVmOverwriteWow64
- CopyToVmWhenNewerWow64
Las subclaves CopyToVmOverwrite y CopyToVmWhenNewer se usan para copiar archivos al directorio %windir%\system32.
Las subclaves CopyToVmOverwriteWow64 y CopyToVmWhenNewerWow64 se utilizan para copiar archivos en el directorio %windir%\syswow64.
Los archivos bajo CopyToVmOverwrite y CopyToVmOverwriteWow64 siempre sobrescriben los archivos en el destino.
Los archivos en CopyToVmWhenNewer y CopyToVmWhenNewerWow64 sobrescriben los archivos en el destino solo si la fecha de cambio del archivo es más reciente. Los criterios "más recientes" comparan dos fragmentos de información:
- FileVersion
- LastWriteTime
Cuando el archivo de destino termina con el sufijo .dll o .exe, FileVersion se usa como el valor de comparación más significativo donde la versión más grande se considera "más reciente". Cuando el archivo de destino no termina con el .dll o .exe sufijo o los dos FileVersion son iguales, lastWriteTime se usa como los valores de comparación menos significativos en los que la fecha y hora posteriores se consideran "más recientes".
Cada tipo de valor de una subclave debe ser REG_MULTI_SZ o REG_SZ. Si el tipo de valor es REG_MULTI_SZ, debe haber un máximo de dos cadenas en el valor. Este requisito significa que cada valor define una sola cadena o un par de cadenas, donde la segunda cadena podría estar vacía.
El primer nombre de un par es una ruta a un archivo del almacén de controladores. La ruta es relativa a la raíz del almacén de controladores y puede contener subdirectorios.
El segundo nombre de un par es el nombre del archivo tal como debería aparecer en el directorio %windir%\system32
o %windir%\syswow64
. El segundo nombre debe ser solo el nombre de archivo, no incluida la ruta de acceso.
Si el segundo nombre está vacío, el nombre de archivo es el mismo que en el repositorio de controladores (excepto los subdirectorios).
Este enfoque permite que el controlador tenga nombres diferentes en el almacén de controladores del host y en el invitado.
Ejemplo 1
En el siguiente ejemplo se muestra cómo hacer que el sistema operativo copie <DriverStorePath>\CopyToVm\softgpu1.dll
en %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"
Ejemplo 2
En el ejemplo siguiente se muestra cómo obtener el sistema operativo para copiar <DriverStorePath>\softgpu1.dll
en %windir%\system32\softgpu.dll
y <DriverStorePath>\softgpu2.dll
en %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””
Ejemplo 3
En el ejemplo siguiente se muestra cómo obtener el sistema operativo para copiar <DriverStorePath>\Subdir1\Subdir2\softgpu2wow64.dll
en %windir%\syswow64\softgpu.dll
y <DriverStorePath>\softgpu.dll
en %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
Cambios en DxgkDdiCreateProcess
La función DxgkDdiCreateProcess de KMD debe actualizarse para admitir procesos de trabajo de máquina virtual y procesos de máquina virtual. Los campos siguientes se agregan a la estructura DXGKARG_CREATEPROCESS:
- hKmdVmWorkerProcess
- ProcessNameLength
- pProcessName
Los siguientes indicadores se añaden a DXGK_CREATEPROCESSFLAGS para soportar procesos de trabajo VM y procesos VM:
- VirtualMachineProcess
- VirtualMachineWorkerProcess
DxgkDdiSetVirtualMachineData
DxgkDdiSetVirtualMachineData se añade para que Dxgkrnl pase información sobre una máquina virtual al KMD.
Mensajes asincrónicos de bus de máquina virtual al host
Algunos mensajes de Dxgkrnl en el SO invitado al host son asíncronos. Este enfoque mejora el rendimiento de las llamadas a la API Dxgkrnl de alta frecuencia en el invitado. La sobrecarga de cada mensaje de bus de máquina virtual sincrónica al host puede ser alta.
Los mensajes asincrónicos incluyen:
- D3DKMTSubmitCommand
- D3DKMTSubmitCommandToHardwareQueue
- D3DKMTSignalSynchronizationObjectFromGpu
- D3DKMTWaitForSynchronizationObjectFromGpu
Soporte de LDA en GPU-PV
El adaptador de pantalla vinculado (LDA) se admite en GPU-PV. Para garantizar una implementación coherente y soportar la posible retrocompatibilidad futura del soporte de LDA a versiones anteriores de Windows, el KMD debe comprobar el soporte de LDA en GPU-PV llamando a DxgkCbIsFeatureEnabled(DXGK_FEATURE_LDA_GPUPV). El soporte está habilitado si la función tiene éxito y devuelve Habilitado. Si el KMD no llama a este callback, Dxgkrnl asume que el KMD no soporta LDA en GPU-PV.
Si el sistema operativo admite la característica, es necesario que el controlador habilite LDA en modo de usuario. Si el controlador habilita LDA en modo de usuario, debe hacerlo de la siguiente manera.
Tiempo de ejecución | Estado de LDA |
---|---|
Tiempo de ejecución anterior a D3D12 | Habilitar si se admite DXGK_FEATURE_LDA_GPUPV y el sistema operativo invitado es Windows 11, versión 22H2 (WDDM 3.1) o posterior. |
Runtimes que no son DX (Windows) | Habilitar si se admite DXGK_FEATURE_LDA_GPUPV y el sistema operativo invitado es Windows 11, versión 22H2 (WDDM 3.1) o posterior. En lugar de comprobar la versión del sistema operativo, el UMD podría llamar a D3DKMTQueryAdapterInfo(KMTQAITYPE_PHYSICALADAPTERCOUNT) y habilitar LDA cuando devuelva un número de adaptadores físicos mayor que uno. |
Tiempo de ejecución D3D12 (Windows) | Habilitar. Consulte Configuración del estado LDA para el runtime D3D12. |
Linux (entorno de ejecución de d3d12 y sin DirectX) | Habilitar si DXGK_FEATURE_LDA_GPUPV es compatible. |
Los controladores compilados con una versión de interfaz inferior a DXGKDDI_INTERFACE_VERSION_WDDM3_0 no comprueban DXGK_FEATURE_LDA_GPUPV. Estos controladores todavía pueden habilitar LDA para entornos de ejecución de Linux.
Establecimiento del estado LDA para el entorno de ejecución D3D12
Al habilitar o deshabilitar LDA para el entorno de ejecución D3D12, el UMD debe devolver la información correcta de asignación de niveles y nodos al entorno de ejecución. El flujo de código es el siguiente:
D3D12 obtiene el límite D3D12_CROSS_NODE_SHARING_TIER de UMD.
D3D12 obtiene el número de adaptadores físicos de Dxgkrnl llamando a D3DKMTQueryAdapterInfo(KMTQAITYPE_PHYSICALADAPTERCOUNT).
D3D12 llama a pfnQueryNodeMap(PhysicalAdapterCount, &map) para obtener la asignación de índices de nodos lógicos a nodos físicos. El nodo en este caso significa adaptador físico. La UMD necesita establecer el índice del adaptador físico real en el mapa o D3D12DDI_NODE_MAP_HIDE_NODE para deshabilitar un nodo.
En función de los resultados de pfnQueryNodeMap, D3D12 calcula el recuento efectivo de adaptadores físicos sin contar los nodos ocultos.
Si el estado del tier y el recuento del adaptador físico efectivo no coinciden, D3D12 falla la creación del dispositivo. La falta de coincidencia se produce cuando:
- El nivel es D3D12DDI_CROSS_NODE_SHARING_TIER_NOT_SUPPORTED y el número de adaptadores es mayor que 1.
- El nivel no es D3D12DDI_CROSS_NODE_SHARING_TIER_NOT_SUPPORTED y el número de adaptadores es 1.
Para deshabilitar LDA, el UMD necesita devolver el nivel D3D12DDI_CROSS_NODE_SHARING_TIER_NOT_SUPPORTED y mantener solo un adaptador físico habilitado en el mapa de nodos.
D3DKMTQueryAdapterInfo(KMTQAITYPE_PHYSICALADAPTERCOUNT)
Una consulta KMTQAITYPE_PHYSICALADAPTERCOUNT para el recuento de adaptadores físicos siempre devuelve el recuento de adaptadores físicos correcto al invitado:
- En invitados pre-Windows 11 versión 22H2, devuelve 1. Este valor está codificado de forma rígida en el código de invitado. Podría cambiar en el futuro si la compatibilidad con LDA se traslada a versiones anteriores del sistema operativo.
- En Windows 11, versión 22H2 y sistemas posteriores, devuelve:
- El número real de adaptadores físicos cuando DXGK_FEATURE_LDA_GPUPV está habilitado.
- De lo contrario, es 1.
Paravirtualización
Habilite la compatibilidad con la virtualización en el BIOS (VT-d o similar). La configuración de GPU-PV es diferente para las máquinas virtuales VMMS y los contenedores.
En PowerShell (ejecutándose como administrador), habilite la ejecución de scripts en el servidor:
set-executionpolicy unrestricted
Configuración de la máquina virtual VMMS
Configuración del host y la máquina virtual
La compilación del sistema operativo en la máquina virtual puede ser anterior o más reciente que la compilación del sistema operativo en el host.
Habilite la característica Hyper-V en los roles de servidor o la característica Hyper-V en el cliente. Al habilitar esta característica en el servidor, seleccione la opción para usar el adaptador de red como conmutador externo.
(opcional) Habilite la firma de prueba (bcdedit -set TESTSIGNING ON)
Reiniciar.
Instale un controlador de GPU que admita la para-virtualización.
(opcional) Algunos controladores no establecen el cap ParavirtualizationSupported. En este caso, agregue el siguiente registro antes de instalar el controlador o desactive y vuelva a activar el dispositivo después de que se haya establecido el indicador.
DWORD HKLM\System\CurrentControlSet\Control\GraphicsDrivers\GpuVirtualizationFlags = 1
Para comprobar si el sistema operativo reconoce la GPU paravirtualizada, ejecute el siguiente comando de PowerShell:
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
Ejecute los siguientes comandos en PowerShell para crear una máquina virtual con GPU. Se crea una máquina virtual denominada TEST.
$vm = “TEST“ New-VM -VMName $vm -Generation 2 Set-VM -GuestControlledCacheTypes $true -VMName $vm
Establece el espacio IO para la VM. GPU-PV utiliza el espacio IO para administrar las asignaciones visibles para la CPU. Se necesitan al menos 8 GB de espacio de E/S.
Set-VM -LowMemoryMappedIoSpace 1GB -VMName $vm Set-VM -HighMemoryMappedIoSpace 16GB -VMName $vm
[opcional] De forma predeterminada, la dirección base del espacio de E/S de memoria alta se establece en (64 GB - 512 MB). En los conjuntos de chips Haswell con direccionamiento de memoria física de 36 bits, la dirección final de la región del espacio de E/S debe estar por debajo de 64 GB, por lo que la dirección inicial debe establecerse en consecuencia. El siguiente script, denominado SetHighMmioBase.ps1, establece la dirección de inicio en 47 GB cuando se ejecuta con los parámetros siguientes:
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" }
Agregue una GPU virtual a la máquina virtual y deshabilite los puntos de control.
Add-VMGpuPartitionAdapter -VMName $vm Set-VM -CheckpointType Disabled -VMName $vm
Para comprobar que la máquina virtual tiene una GPU paravirtualizada, ejecute el siguiente comando:
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 :
Copie el VHDX de la misma compilación de cliente que utiliza en la VM a un directorio del host. Por ejemplo,
d:\VM\os.vhdx
.Abra Hyper-V administrador y modifique los parámetros de máquina virtual (seleccione VM y seleccione Configuración):
- Seguridad - Desmarque Habilitar arranque seguro.
- Memoria: compruebe y habilite la memoria dinámica. Establezca la cantidad de memoria en 1024 MB o más.
- Procesador: establezca número de procesadores virtuales en 2 o 4.
- Adaptador de red: seleccione el adaptador de red que se va a usar con la máquina virtual en el cuadro desplegable. Si la depuración de red está activada, asegúrese de elegir el adaptador Microsoft Debugging NET.
- Controlador SCSI - Disco Duro - Agregar - Disco Duro Virtual - Examinar - Seleccionar
d:\VM\os.vhdx
El sistema operativo copia los archivos del almacén del controlador del host en el directorio HostDriverStore del invitado cuando el adaptador se inicializa en el sistema del invitado.
- Monte el VHDX de la VM. Por ejemplo, en el disco f:.
- En la máquina virtual montada, cree un directorio denominado f:\%windir%\system32\HostDriverStore\FileRepository.
- Replique los archivos de controlador desde %windir%\system32\DriverStore en el host a la máquina virtual. Debe haber f:\%windir%\system32\HostDriverStore\FileRepository\YourDriverDirectory\* en la máquina virtual.
Si el controlador necesita acceder a archivos desde
%windir%\system32
o%windir%\syswow64
, copie manualmente los archivos en la máquina virtual.Habilite el inicio de sesión de prueba en la máquina virtual si los controladores no están firmados por Microsoft. En la ventana administrador de CMD, ejecute el siguiente comando:
bcdedit /store <VM drive>:\EFI\Microsoft\Boot\BCD -set {bootmgr} testsigning on
Desmontar el VHDX de la VM.
Inicie la máquina virtual.
Conéctese a la máquina virtual mediante la opción Hyper-V manager Connect.
DENTRO DE LA MÁQUINA VIRTUAL
Compruebe que hay un dispositivo de representación virtual en el administrador de dispositivos de la máquina virtual. Toda la representación dentro de la máquina virtual pasa por gpu virtual.
Script de PowerShell para configurar una máquina virtual
El siguiente script de PowerShell es un ejemplo de cómo configurar una máquina virtual desde cero. Modifíquelo para adaptarlo a sus necesidades.
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
}
Depurando la VM
Configure el depurador de máquinas virtuales de la misma manera que la depuración de red en una máquina cliente normal.
Si la máquina virtual no se inicia o ve una pantalla negra:
Desactive la máquina virtual y quite la GPU virtual de ella mediante los siguientes comandos:
$vm = “TEST“ remove-VMGpuPartitionAdapter -VMName $vm -AdapterId “<Id from Get-VMGpuPartitionAdapter>”
Por ejemplo:
remove-VMGpuPartitionAdapter -VMName $vm -AdapterId “Microsoft:9ABB95E2-D12D-43C3-B840-6F4A9CFB217B\929890BC-BB33-4687-BC1A-F72A4F1B3B3F”
Inicie la máquina virtual. Si se inicia correctamente, asegúrese de que los archivos del controlador se copian correctamente en hostDriverStore en la máquina virtual.
Agregue vGPU a la máquina virtual mediante el comando
Add-VMGpuPartitionAdapter
.Vuelva a iniciar la máquina virtual.
Consulte solución de problemas para obtener información adicional.
Configuración del contenedor
La diferencia entre los contenedores (también denominados máquinas virtuales del Host Compute System (HCS)) y la máquina virtual completa es que los archivos binarios del sistema operativo y los archivos de almacenamiento de controladores se asignan al contenedor. Por lo tanto, no es necesario copiar los archivos de controlador en el contenedor, a menos que sean necesarios en el directorio windows\system32
.
Para contenedores seguros:
- Los escapes del driver están deshabilitados.
- El controlador debe soportar aislamiento IOMMU para ser habilitado dentro de un contenedor seguro.
Al actualizar el controlador en el host e iniciar o detener la GPU del host, los cambios se reflejan en el contenedor.
Sandbox de Windows
Este tipo de contenedor se usa para probar aplicaciones de riesgo. La imagen de escritorio completa se envía remotamente al host. El controlador de pantalla indirecta se utiliza para el control remoto. No se usa VAIL de gráficos, por lo que llevar la imagen de escritorio al host es lenta.
La GPU virtual está deshabilitada de forma predeterminada en el espacio aislado de Windows. Para habilitarlo, cree un archivo de configuración WSB (por ejemplo, config.wsb) y establezca la opción de GPU virtual. Inicie Sandbox haciendo clic en el archivo de configuración.
Ejemplo de archivo de configuración:
<Configuration>
<VGpu>Enable</VGpu>
</Configuration>
De forma predeterminada, la vGPU del contenedor tiene las opciones de escape del controlador deshabilitadas. Hay una opción de configuración para habilitar los escapes del controlador. El siguiente ejemplo de archivo WSB habilita tanto vGPU en Sandbox como los escapes de controladores:
<Configuration>
<VGpu>EnableVendorExtensions</VGpu>
</Configuration>
Windows Sandbox soporta el adaptador GPU "hot plug".
Contenedor de aplicación virtual integrado localmente (VAIL)
Use este tipo de contenedor para ejecutar aplicaciones Win32 dentro de un host basado en WCOS (sistema operativo Windows Core). La imagen de cada aplicación en el contenedor es remota al host. Gráficos VAIL está habilitado a distancia cada aplicación swapchain. Los escapes de controladores están habilitados.
Requisitos comunes del contenedor
Los requisitos de la máquina son:
- Tanto Vtx como Vtd deben estar habilitados en BIOS (o sus equivalentes: AMD-V, AMD-IOMMU).
- Al menos 8 GB de RAM.
- Más de 5 GB de espacio en disco del sistema.
Configuración del depurador del kernel para Windows Sandbox
Uso de CMDIAG
Un servicio Container Manager (cmservice) controla los contenedores aislados Hyper-V. CMDIAG.EXE es una aplicación que está disponible cuando instalas las características de Hyper-V y los Contenedores. Habilita la depuración en modo kernel para contenedores, habilita la firma de prueba y más.
El Administrador de Contenedores soporta depuración Serial y NET.
Ejecute cmdiag.exe Debug
para ver las opciones.
CMDIAG modifica la configuración del depurador en la imagen base del contenedor. Solo debe haber una instancia de un contenedor que se ejecute cuando el depurador de kernel esté habilitado.
Detenga el servicio HVSICS antes de cambiar la configuración del depurador.
# 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
Ejecutar el depurador en una máquina diferente
Cuando utilice el depurador en serie, es posible que desee ejecutarlo en una máquina diferente. Use kdsrv.exe
para ejecutar el depurador en otra máquina. Para obtener más información, consulte Servidores de conexión KD.
Para desactivar los tiempos de espera durante la depuración del kernel, configure las siguientes claves de registro:
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
Configuración del depurador del kernel para el contenedor VAIL
- Conéctese al host mediante telnet. Puede obtener la dirección IP del host desde Configuración de red en el sistema operativo host.
- Utilice
cmdiag.exe
para configurar el depurador.
Configuración del depurador de Hipervisor
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
Solución de problemas
En esta sección se proporciona información sobre cómo solucionar problemas con GPU-PV.
Get-VMHostPartitionableGpu
Llame a Get-VMHostPartitionableGpu para ver si hay una GPU virtualizada. Si la salida está vacía, hay un error en algún lugar (el controlador no estableció el límite de virtualización, la virtualización no está habilitada, etc.).
Get-VMHostPartitionableGpu
# Example output from running the command
Name : \\?\PCI#VEN_10DE&DEV_1188&SUBSYS_095B10DE&REV_A1#6&cfd27c8&0&00400008#{064092b3-625e-43bf-9eb5-dc845897dd59}\PARAV
ValidPartitionCounts : {32, 4}
PartitionCount : 32
TotalVRAM : 2,000,000
AvailableVRAM : 1,800,000
MinPartitionVRAM : 100,000
MaxPartitionVRAM : 1,000,000
OptimalPartitionVRAM : 1,000,000
TotalEncode : 20
AvailableEncode : 20
MinPartitionEncode : 1
MaxPartitionEncode : 5
OptimalPartitionEncode : 4
TotalDecode : 40
AvailableDecode : 30
MinPartitionDecode : 2
MaxPartitionDecode : 20
OptimalPartitionDecode : 15
TotalCompute : 100
AvailableCompute : 100
MinPartitionCompute : 1
MaxPartitionCompute : 50
OptimalPartitionCompute : 30
CimSession : CimSession: .
ComputerName : WIN-T3H0LVHJJ59
IsDeleted : False
Uso de eventos ETW
Dxgkrnl tiene canales de administración y de operaciones para eventos ETW. Los eventos se muestran en el Visor de eventos de Windows: Registro de aplicaciones y servicios - Microsoft - Windows - Dxgkrnl.
El Visor de eventos tiene eventos de otros componentes que participan en la creación de una máquina virtual con GPU-PV (Hyper-V-Compute, Hyper-V-Worker, Hyper-V-VID, etc.).
Usando Add-VMGpuPartitionAdapter
Al usar Add-VMGpuPartitionAdapter, no especifique una funcionalidad (por ejemplo, descodificar) si no es necesaria. No use 0 para esta funcionalidad.
Usando Remove-VMGpuPartitionAdapter
Si una máquina virtual no se inicia o tiene problemas de representación, intente quitar la GPU virtual de la máquina virtual mediante Remove-VMGpuPartitionAdapter.
remove-VMGpuPartitionAdapter -VMName $vm -AdapterId "Microsoft:9ABB95E2-D12D-43C3-B840-6F4A9CFB217B\929890BC-BB33-4687-BC1A-F72A4F1B3B3F"
Impedir el inicio de la máquina virtual durante el arranque
set-vm -AutomaticStartAction Nothing -VmName TEST
Eventos del visor de eventos
Agregue eventos al canal del visor de eventos para ayudar a identificar problemas con el inicio de vGPU. Puede encontrar los eventos en "Registros de aplicaciones y servicios\Microsoft\Windows\Dxgkrnl". Los canales de eventos son Admin y Operational.
Los eventos se emiten cuando:
- Se crea vGPU
- vGPU se destruye
- El invitado abre un adaptador virtual.
Los archivos de eventos están en:
- c:\Windows\System32\winevt\Logs\Microsoft-Windows-DxgKrnl-Admin.evtx
- c:\Windows\System32\winevt\Logs\Microsoft-Windows-DxgKrnl-Operational.evtx
Compruebe si se creó una vGPU y si hay algún error.
Configuración del Registro
GpuVirtualizationFlags
La clave del Registro GpuVirtualizationFlags se usa para establecer el comportamiento de las GPU paravirtualizadas. La clave se encuentra en:
DWORD HKLM\System\CurrentControlSet\Control\GraphicsDrivers\GpuVirtualizationFlags
Se definen los siguientes bits:
bit | Descripción |
---|---|
0x1 | Fuerza el tope ParavirtualizationSupported para todos los adaptadores de hardware. Utilice este bit en el host. |
0x2 | Fuerza el cap ParavirtualizationSupported para BásicoRender. Utilice este bit en el host. |
0x4 | Forzar el modo de máquina virtual segura, donde todas las máquinas virtuales se tratarán como seguras. En este modo, hay restricciones en el controlador en modo de usuario. Por ejemplo, el controlador no puede usar llamadas Escape, por lo que fallarán. Utilice este bit en el host. |
0x8 | Habilite el emparejamiento de adaptadores paravirtualizados con el adaptador de solo pantalla. Use este bit en la máquina virtual invitada. El emparejamiento está habilitado de forma predeterminada. |
GuestIoSpaceSizeInMb
La clave del Registro GuestIoSpaceSizeInMb se usa para establecer el tamaño del espacio de E/S invitado para las GPU virtuales, en megabytes. El valor predeterminado es 1000 MB (1 GB). La clave se encuentra en:
DWORD HKLM\System\CurrentControlSet\Control\GraphicsDrivers\Paravirtualization\GuestIoSpaceSizeInMb
El espacio de E/S del invitado actualmente implementa asignaciones visibles para el CPU. Una asignación visible para la CPU que se almacena en el host se fija en la memoria y se asigna al espacio de E/S del invitado. En el invitado, la dirección virtual del modo de usuario de la asignación se rota a la región del espacio IO. En algunos sistemas Haswell, la CPU tiene direcciones físicas de 36 bits. Hyper-V en estos sistemas tiene un tamaño de espacio de E/S limitado.
Deshabilitación del aislamiento de IOMMU para máquinas virtuales seguras
Si un controlador no admite el aislamiento de IoMmu, use la siguiente configuración del Registro durante el desarrollo para deshabilitar el aislamiento de IoMmu.
`DWORD HKLM\SYSTEM\CurrentControlSet\Control\GraphicsDrivers\IoMmuFlags = 8`
Limitar el número de funciones virtuales
De forma predeterminada, el número de funciones virtuales expuestas por un adaptador que admite la paravirtualización de GPU es 32. Este número significa que el adaptador se puede agregar a 32 máquinas virtuales, suponiendo que cada máquina virtual tenga un adaptador.
Puede usar la siguiente configuración del Registro para limitar el número de funciones virtuales expuestas.
DWORD HKLM\SYSTEM\CurrentControlSet\Control\GraphicsDrivers\NumVirtualFunctions
Por ejemplo, si establece NumVirtualFunctions
en 1, el adaptador solo se puede agregar a una GPU una vez. Esta configuración es útil cuando un equipo tiene varios adaptadores de GPU que admiten GPU-PV y desea asignar cada adaptador a una máquina virtual. Add-VMGpuPartitionAdapter
no permite especificar qué adaptador se va a agregar. Por lo tanto, si se agregan dos adaptadores a una máquina virtual, ambos podrían obtener el mismo adaptador GPU-PV del host.
Actualizaciones de DDI de WDDM 2.4
Las siguientes actualizaciones de DDI se realizan para admitir la paravirtualización de GPU en WDDM 2.4.
Añadido el cap DXGK_VIDMMCAPS
La capacidad ParavirtualizationSupported se añade a la estructura DXGK_VIDMMCAPS. El KMD de host establece este límite si implementa todas las DDIs descritas en esta sección.
Datos privados del controlador transmitidos a través de DDI
El UMD usa varias DDIs para intercambiar información privada con su KMD correspondiente. Cuando el UMD se ejecuta en la máquina virtual invitada, la llamada de KMD DDI correspondiente se produce en la partición del host. Por lo tanto, el UMD:
- No puede pasar ningún puntero en los datos privados.
- No puede pasar ningún identificador en los datos privados.
- No debe indicar al KMD que realice cambios globales en el estado de la GPU, ya que este cambio podría afectar a otras máquinas virtuales en ejecución.
Se ha agregado la marca VirtualMachineProcess para DxgkDdiCreateProcess.
El sistema operativo crea un proceso de trabajo de máquina virtual para cada máquina virtual en ejecución. Dxgkrnl crea un DXGPROCESS correspondiente y llama a DxgkDdiCreateProcess con la marca VirtualMachineWorkerProcess activada. No hay creación de recursos de renderizado o controladores en este contexto de proceso. Por lo tanto, el controlador podría omitir la asignación de determinados recursos.
El sistema operativo crea un DXGPROCESS en el host para cada proceso de una máquina virtual invitada que usa una GPU. Dxgkrnl llama a DxgkDdiCreateProcess con la marca VirtualMachineProcess activada. Cada proceso DXG VM pertenece al mismo EPROCESS que el proceso de trabajo VM.
Actualizaciones de DxgkDdiQueryAdapterInfo
La estructura DXGKARG_QUERYADAPTERINFO se actualiza para incluir los siguientes campos para admitir la paravirtualización:
Se ha añadido el miembro Flags, lo cual permite que Dxgkrnl indique lo siguiente:
- Establece virtualMachineData para indicar que la llamada procede de una máquina virtual.
- Establece SecureVirtualMachine para indicar que la máquina virtual se ejecuta en modo seguro.
Se añade hKmdProcessHandle, que permite al controlador identificar y utilizar el contexto de proceso correcto en el lado del host cuando se trata de consultas originadas en una VM invitado.
Actualizaciones de DxgkDdiEscape
El miembro hKmdProcessHandle se agrega a la estructura DXGKARG_ESCAPE para permitir que el controlador identifique y use el contexto de proceso correcto en el lado host al tratar con escapes que se originan en una máquina virtual invitada.
La marca VirtualMachineData se añade a la estructura D3DDDI_ESCAPEFLAGS para indicar que DxgkDdiEscape se llama desde una máquina virtual.
Acceso físico a asignaciones de GPU
Actualmente, el controlador no implementa el acceso físico a las asignaciones. El controlador debe soportar GpuMmu.
Actualizaciones de DDI de WDDM 2.5
Para WDDM 2.5, también se requieren los siguientes cambios de DDI para la compatibilidad con la paravirtualización.
Señalización de eventos del invitado por el KMD del host
Hay escenarios que existen sin virtualización cuando el KMD necesita indicar un evento creado por un UMD. Para controlar estos escenarios cuando se usa la paravirtualización, el KMD del host debe señalar un evento creado en la máquina virtual invitada. El callback DxgkCbSignalEvent se añade para este propósito. KMD también puede utilizar este callback para señalar eventos de los procesos del host.
Soporte para handles proporcionados por UMD en una VM
Ciertos callbacks del driver aceptan un Dxgkrnl handle de asignación o recurso que la UMD pasa, como por ejemplo:
Las llamadas en el host deben estar en el contexto del mismo hilo que llamó a una función DxgkDdiXxx.
Por ejemplo, supongamos que sin virtualización, el KMD llama a DxgkCbAcquireHandleData en el contexto del hilo en modo usuario que llama a D3DKMTEscape, que llama a DxgkDdiEscape.
Cuando UMD se ejecuta en una máquina virtual, solo conoce los identificadores de asignación de invitados y no puede pasar dichos identificadores al KMD porque KMD se ejecuta en el host. El UMD en el invitado llama a D3DKMTEscape y el KMD en el host recibe la correspondiente llamada DxgkDdiEscape. El KMD necesita llamar a DxgkCbAcquireHandleData en el contexto de este hilo.
Con el fin de ser capaz de traducir la asignación invitado/identificador de recursos a la correspondiente manija de acogida, la marca de escape D3DDDI_ESCAPEFLAGS::DriverKnownEscape del controlador se añade.
Cuando se llama a D3DKMTEscape con la marca DriverKnownEscape activada:
Establezca D3DKMT_ESCAPE::Type en D3DKMT_ESCAPE_DRIVERPRIVATE.
Establezca D3DKMT_ESCAPE::pPrivateDriverData para que apunte a una estructura de escape de controlador conocida, definida en la siguiente sección. Cada estructura comienza con un valor de D3DDDI_DRIVERESCAPETYPE.
Cuando no se usa la virtualización, el identificador traducido es el mismo que el identificador de entrada.
Se definen los siguientes escapes de controlador conocidos.
En el fragmento de código siguiente se muestra cómo usar el indicador 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);
Actualizaciones de DDI de WDDM 2.6
A partir de WDDM 2.6 (Windows 10, versión 1903), se realizaron las siguientes actualizaciones para la compatibilidad con la paravirtualización:
El controlador puede usar el indicador DXGK_ALLOCATIONINFOFLAGS::ACCESSEDPHYSICALLY en una máquina virtual. Antes de WDDM 2.6, el controlador no pudo usar esta marca en una máquina virtual y se produjo un error en la creación de la asignación con esta marca.
UMD puede usar pfnd3dkmtUpdateallocationproperty en una máquina virtual. Antes de WDDM 2.6, se produciría un error en esta llamada.