Паравиртуализация GPU
В этой статье описывается паравиртуализация GPU в WDDM. Эта функция доступна начиная с Windows 10 версии 1803 (WDDM 2.4).
Сведения о виртуализации GPU
Виртуализация GPU является важной функцией для клиента Windows и Windows Server. Существует множество сценариев, требующих эффективного использования ресурсов GPU на виртуальной машине.
Сценарии сервера (где операционная система узла не запускает пользовательские приложения) включают:
- Виртуализация рабочих столов
- Вычисления (ИИ, МАШИНное обучение и т. д.)
Клиентские сценарии (где операционная система узла делит GPU между виртуальными машинами и пользовательскими приложениями) включают в себя:
- Разработка и тестирование графических приложений (где выполняется тестирование на виртуальной машине)
- Выполнение приложений в виртуальной машине в целях безопасности
- Запуск Linux на виртуальной машине с ускорением GPU
Паравиртуализация GPU в WDDM
Paravirtualization (PV) предоставляет интерфейс для виртуальных машин, которые похожи на базовое оборудование. В PV перед установкой виртуальной машины непосредственно переносите гостевую операционную систему, так как не настраиваемая гостевая операционная система не может выполняться на основе монитора виртуальной машины (VMM).
Преимущества:
- Несколько виртуальных машин совместно используют аппаратные ресурсы.
- В коде драйвера необходимо вносить несколько изменений.
На следующем рисунке показаны различные компоненты, участвующие в паравиртуализированном дизайне WDDM.
Средства выполнения D3D на гостевой виртуальной машине не изменяются. Интерфейсы среды выполнения пользовательского режима и с KMT ядра остаются неизменными.
Для компонентов драйвера не требуется много изменений:
UMD в гостевой виртуальной машине должен:
- Помните, что связь с драйвером режима ядра узла (KMD) происходит через границу виртуальной машины.
- Используйте добавленные службы Dxgkrnl для доступа к параметрам реестра.
В составе гостей нет KMD, только UMD. Виртуальное устройство отрисовки (VRD) заменяет KMD. Цель VRD — упростить загрузку Dxgkrnl.
В госте нет диспетчера видеопамяти (VidMm) или планировщика (VidSch).
Dxgkrnl на виртуальной машине получает thunk-вызовы и передает их в основной раздел узла через каналы шины виртуальной машины. Dxgkrnl в гостевом компьютере также создает локальные объекты для выделения памяти, процессов, устройств и других ресурсов, что снижает трафик с хостом.
Виртуальное устройство отрисовки (VRD)
Если паравиртуализированный GPU отсутствует в виртуальной машине, диспетчер устройств виртуальной машины отображает адаптер Microsoft Hyper-V Video. Этот адаптер, предназначенный только для отображения, по умолчанию связан с адаптером BasicRender для отрисовки.
При добавлении паравиртуализированного GPU на виртуальную машину диспетчер устройств виртуальной машины отображает два адаптера:
- Видеоадаптер Майкрософт Hyper-V или адаптер удаленного дисплея Майкрософт
- Microsoft Virtual Render Driver (Фактическое имя — имя адаптера GPU на узле)
По умолчанию VRD связан с адаптером видео Hyper-V, поэтому все отрисовки пользовательского интерфейса выполняются с адаптером VRD.
При возникновении проблем с отрисовкой можно отключить это сочетание с помощью параметра реестра GpuVirtualizationFlags. В этом случае адаптер только для рендеринга используется, когда приложение специально его выбирает. Например, некоторые примеры DirectX позволяют изменить устройство отрисовки. Среда выполнения Direct3D добавляет логический вывод отображения в VRD, когда приложение решает его использовать.
При добавлении нескольких виртуальных GPU на виртуальную машину может быть несколько адаптеров VRD в гостевой машине. Однако только один из них можно связать с адаптером видео Hyper-V. Нет способа указать, какой из них; ВЫБИРАЕТ ОС.
Контейнеры и виртуальные машины
Виртуализация GPU поддерживается для виртуальных машин и контейнеров. Контейнеры — это упрощенные виртуальные машины, в которых двоичные файлы ОС узла сопоставляются с виртуальной машиной контейнера.
Дополнительные сведения о контейнерах см. в разделе Windows и контейнеры.
Безопасные виртуальные машины
Для безопасной виртуальной машины существуют следующие ограничения:
- Вызовы escape драйвера не допускаются, кроме известных escape-вызовов, которые используются с флагом DriverKnownEscape.
- Изоляция IoMmu включена. Создание виртуальной машины завершается ошибкой, если драйвер не поддерживает изоляцию IoMmu.
Если включен безопасный режим:
- DxgkDdiSetVirtualMachineData имеет набор флагов SecureVirtualMachine.
- DxgkDdiQueryAdapterInfo имеет набор флагов SecureVirtualMachine.
Существуют параметры реестра для принудительной защиты режима или отключения изоляции IoMmu во время разработки. Дополнительные сведения см. в параметрах реестра.
Удаленный доступ к рабочему столу виртуальной машины или контейнера
Подключение к содержимому рабочего стола виртуальной машины на хосте можно выполнить двумя способами.
- адаптер отображения Hyper-V
- Удаленное подключение сеанса терминала
Если для подключения к виртуальной машине используется RDP (удаленный рабочий стол), выполняется удалённое управление сеансом терминала.
Диспетчер Hyper-V использует приложение VMConnect для отображения рабочего стола виртуальной машины. VMConnect работает в двух режимах:
- Расширенный режим, использующий удаленное управление сеансом терминала.
- Базовый режим, использующий адаптер отображения Hyper-V.
Рабочий процесс виртуальной машины и память виртуальной машины
При запуске виртуальной машины или контейнера операционная система создает следующие процессы на узле:
- Рабочий процесс виртуальной машины (vmwp.exe)
- Процесс памяти виртуальной машины (vmmem.exe)
Vmwp содержит различные драйверы виртуальных устройств, включая vrdumed.dll, драйвер для паравиртуализированных графических адаптеров.
vmmem процесс виртуального адресного пространства служит резервной копией пространства ввода-вывода виртуального ЦП в гостевой машине. Когда гость обращается к пространству ввода-вывода, полученный физический адрес является записью на второй уровень перевода, которая использует таблицы страниц процесса vmmem.
В виртуализированной среде, когда выполняется виртуальная машина, различные вызовы KMD DDI, которые обычно запускаются в контексте пользовательского процесса на хосте, выполняются в контексте процесса vmmem.
Dxgkrnl создает один объект DXGPROCESS (и соответствующий объект процесса KMD) для этих процессов, который называется рабочий процесс виртуальной машины в этой статье. EPROCESS, связанный с рабочим процессом виртуальной машины DXG, vmmem.
Процессы виртуальных машин
При создании DXGPROCESS на гостевой виртуальной машине Dxgkrnl создает соответствующий объект DXGPROCESS на хосте. Этот процесс называется процессом виртуальной машины в этой статье. EPROCESS, связанный с DXGPROCESS, — vmmem.
Все операции отрисовки из виртуальной машины или создания выделения для виртуальной машины выполняются в контексте DXGPROCESS виртуальной машины.
В целях отладки Dxgkrnl уведомляет KMD о том, какой процесс является рабочим процессом виртуальной машины или процессом виртуальной машины в DxgkDdiCreateProcess. С помощью этих сведений драйвер может связать процесс виртуальной машины с рабочим процессом виртуальной машины. Эта информация помогает отладке в сценариях, когда используется более одной виртуальной машины.
Требования к драйверу
KMD, поддерживающему паравиртуализацию GPU, необходимо установить возможность DXGK_VIDMMCAPS::ParavirtualizationSupported.
Драйвер пользовательского режима (UMD) не должен использовать данные, связанные с контекстом процесса, в данных частного драйвера (указатели, дескриптор и т. д.). Вместо этого KMD получает частные данные в узле в другом контексте процесса.
UMD в гостевой системе не может совместно использовать память с KMD в хостовой системе. Он должен использовать функции, описанные в доступе к реестру из UMD для доступа к реестру.
Текущая реализация паравиртуализации использует шину виртуальной машины для обмена данными между гостевой системой и хостом. Максимальный размер сообщения — 128 КБ. В настоящее время Dxgkrnl не разбивает сообщения на части для отправки. Поэтому драйверу необходимо ограничить размер частных данных, передаваемых с помощью создания объекта. Например, если Pfnd3dddiAllocatecb используется для создания множества выделений, общий размер сообщения включает заголовок, глобальные частные данные, а также размер частных данных выделения, умноженных на количество выделений. Все эти сведения должны соответствовать одному сообщению.
Выполнение приложений в полноэкранном эмулированном режиме
Адаптер непрямого отображения должен быть включен для удаленного управления (по умолчанию он включен). Чтобы отключить его, выполните следующие действия.
- Запуск редактирования групповой политики
- Перейдите в раздел "Конфигурация компьютера" ->"Административные шаблоны" ->"Компоненты Windows" ->"Службы удаленных рабочих столов" ->"Узел сеанса удаленного рабочего стола" ->"Среда удаленного сеанса"
- Откройте элемент "Использование драйвера графического отображения WDDM для подключения к удаленному рабочему столу"
- Выберите "Отключить" и нажмите кнопку "ОК"
- Перезагрузить
Поддержка DXGI для полноэкранных приложений на виртуальных машинах включена по умолчанию. Чтобы отключить его, используйте StagingTool.exe /disable 19316777
.
Полноэкранные приложения должны работать в эмулированном режиме полноэкранного режима.
Включите eFSE для всех приложений DXGI и задайте минимальную версию WDDM для перехода эффекта переключения на WDDM 2.0:
D3DEnableFeature.exe /enable DXGI_eFSE_Enablement_Policy
D3DEnableFeature.exe /setvariant DXGI_eFSE_Enablement_Policy 7
EFSE включен по умолчанию для приложений D3D9.
DriverStore на виртуальной машине
Двоичные файлы драйверов на узле находятся в хранилище драйверов %windir%\system32\drivers\DriverStore\FileRepository<DriverDirectory>.
Для паравиртуализации двоичные файлы UMD на виртуальной машине должны находиться в %windir%\system32\drivers\HostDriverStore\FileRepository<DriverDirectory>.
Хост KMD сообщает об именах библиотек UMD DLL, которые содержат полный путь к хранилищу драйверов. Например, c:\windows\system32\DriverStore\FileRepository\DriverSpecificDirectory\d3dumd.dll.
Когда виртуальная машина запрашивает имя UMD, имя преобразуется в <VmSystemDrive>:\windows\system32\HostDriverStore\FileRepository\DriverSpecificDirectory\d3dumd.dll.
Host DriverStore для контейнеров
Для контейнеров Hyper-V отображает полный каталог хранилища драйверов на узле как <%windir%\HostDriverStore в контейнере.
Host DriverStore для полных виртуальных машин
Файлы хранилища драйверов копируются на виртуальную машину при запуске адаптера виртуального GPU на виртуальной машине. Эта функция отключена в выпущенной версии ОС.
Следующий раздел реестра и возможные значения управляют операцией копирования. Ключ не существует по умолчанию.
DWORD RTL_REGISTRY_CONTROL\GraphicsDrivers\DriverStoreCopyMode
Ценность | Описание |
---|---|
0 | Отключение копирования хранилища драйверов |
1 | Обычная операция (включение копирования файлов хранилища драйверов и не перезаписывание существующих файлов). |
2 | Включите копирование хранилища драйверов и перезапись существующих файлов. |
Доступ к реестру из UMD
Ключи реестра KMD существуют на узле и не отражаются на виртуальной машине. Поэтому UMD не может напрямую читать такие ключи реестра драйверов. Обратный вызов pfnQueryAdapterInfoCb2 добавляется в структуру D3DDDI_ADAPTERCALLBACKS среды выполнения D3D. UMD может вызвать pfnQueryAdapterInfoCb2 с установленным следующим образом D3DDDICB_QUERYADAPTERINFO2, чтобы прочитать определенные разделы реестра.
- D3DDDICB_QUERYADAPTERINFO2::QueryTypeD3DDDI_QUERYADAPTERTYPE_QUERYREGISTRY.
-
pPrivateDriverData указывает на буфер со структурой D3DDDI_QUERYREGISTRY_INFO, в которой возвращаются сведения о реестре. UMD заполняет следующие элементы:
- D3DDDI_QUERYREGISTRY_INFO::QueryType указывает тип доступа к реестру; Например, ключ службы, ключ адаптера или путь к хранилищу драйверов.
- D3DDDI_QUERYREGISTRY_FLAGS::QueryFlags задает флаги для запроса.
- ValueName определяет имя значения для чтения.
- ValueType указывает тип значения для чтения.
-
PrivateDriverDataSize равен
sizeof(D3DDDI_QUERYREGISTRY_INFO)
плюс размер буфера для динамически измеряемого выходного значения.
UMD также может вызывать D3DKMTQueryAdapterInfo напрямую. Этот вызов полезен для UMD в гостевой системе, так как он маршалируется хосту и предоставляет способ перевода конкретных имен в пространство имен гостя.
D3DKMTQueryAdapterInfo вызывается следующим образом: D3DKMT_QUERYADAPTERINFO, чтобы прочитать определенные разделы реестра.
- Тип установлен на KMTQAITYPE_QUERYREGISTRY
- pPrivateDriverData указывает на структуру D3DKMT_ADAPTERREGISTRYINFO
-
PrivateDriverDataSize - это
sizeof(D3DKMT_ADAPTERREGISTRYINFO)
, плюс размер буфера для значения выходных данных динамического размера.
Пример 1. Чтение значения из ключа службы
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");
}
}
Пример 2. Чтение пути к хранилищу драйверов
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
}
Копирование файлов в %windir%\system32 и %windir%\syswow64 на виртуальной машине
В некоторых случаях библиотеки DLL для драйвера в пользовательском режиме должны присутствовать в каталогах %windir%\system32 и %windir%\syswow64.
ОС предоставляет драйверу способ указания файлов, которые должны быть скопированы из хранилища драйверов в узле в %windir%\system32 или %windir%\syswow64 в гостевой системе.
В установочном INF драйвера можно задать несколько значений в следующих подразделах ключа реестра графического адаптера:
- CopyToVmOverwrite
- CopyToVmWhenNewer
- CopyToVmOverwriteWow64
- CopyToVmWhenNewerWow64
Вложенные ключи CopyToVmOverwrite и CopyToVmWhenNewer используются для копирования файлов в каталог %windir%\system32.
Вложенные ключи CopyToVmOverwriteWow64 и CopyToVmWhenNewerWow64 используются для копирования файлов в каталог %windir%\syswow64.
Файлы в разделе CopyToVmOverwrite и CopyToVmOverwriteWow64 всегда перезаписывают файлы в месте назначения.
Файлы под CopyToVmWhenNewer и CopyToVmWhenNewerWow64 перезаписывают файлы в папке назначения, только если дата изменения файла более поздняя. Критерии "новее" сравнивают два элемента информации.
- Версия файла
- Время последней записи
Когда целевой файл заканчивается .dll или .exe суффиксом, FileVersion используется в качестве наиболее важного значения сравнения, где самая большая версия считается "более новой". Если целевой файл не заканчивается суффиксом .dll или .exe, или если два FileVersion равны, то LastWriteTime используется в качестве наименьшего значения для сравнения, где более поздняя дата и время считаются "новыми".
Каждый тип значения в подразделе должен быть REG_MULTI_SZ или REG_SZ. Если тип значения REG_MULTI_SZ, в значении должно быть не более двух строк. Это требование означает, что каждое значение определяет одну строку или пару строк, где вторая строка может быть пустой.
Первое имя в паре — это путь к файлу в хранилище драйверов. Путь задается относительно корневого каталога хранилища драйверов и может включать подкаталоги.
Второе имя в паре — это имя файла, как оно должно отображаться в каталоге %windir%\system32
или %windir%\syswow64
. Второе имя должно быть только именем файла, не включая путь.
Если второе имя пусто, имя файла совпадает с именем в хранилище драйверов (за исключением подкаталогов).
Такой подход позволяет драйверу иметь разные имена в хранилище драйверов узлов и в гостевом приложении.
Пример 1
В следующем примере показано, как заставить ОС скопировать <DriverStorePath>\CopyToVm\softgpu1.dll
в %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"
Пример 2
В следующем примере показано, как заставить ОС скопировать <DriverStorePath>\softgpu1.dll
в %windir%\system32\softgpu.dll
и <DriverStorePath>\softgpu2.dll
в %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””
Пример 3
В следующем примере показано, как заставить ОС скопировать <DriverStorePath>\Subdir1\Subdir2\softgpu2wow64.dll
в %windir%\syswow64\softgpu.dll
и <DriverStorePath>\softgpu.dll
в %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
Изменения в DxgkDdiCreateProcess
Функцию DxgkDdiCreateProcess от KMD необходимо обновить для поддержки рабочих процессов и процессов виртуальных машин. В структуру DXGKARG_CREATEPROCESS добавляются следующие поля:
- hKmdVmWorkerProcess
- ProcessNameLength
- pProcessName
Были добавлены следующие флаги в DXGK_CREATEPROCESSFLAGS для поддержки рабочих процессов VM и VM-процессов:
- VirtualMachineProcess
- VirtualMachineWorkerProcess
DxgkDdiSetVirtualMachineData
DxgkDdiSetVirtualMachineData добавляется для Dxgkrnl передачи сведений о виртуальной машине в KMD.
Асинхронные сообщения шины виртуальной машины на сервер хоста
Некоторые сообщения из Dxgkrnl в гостевой операционной системе на хост асинхронны. Этот подход повышает производительность высокочастотных вызовов API Dxgkrnl в гостевой операционной системе. Затраты на каждое синхронное сообщение шины виртуальной машины к узлу могут быть высокими.
К асинхронным сообщениям относятся:
- D3DKMTSubmitCommand
- D3DKMTSubmitCommandToHardwareQueue
- D3DKMTSignalSynchronizationObjectFromGpu
- D3DKMTWaitForSynchronizationObjectFromGpu
Поддержка LDA в GPU-PV
Связанный адаптер отображения (LDA) поддерживается в GPU-PV. Чтобы обеспечить согласованную реализацию и поддержку возможного обратного порта поддержки LDA в старые выпуски Windows, KMD необходимо проверить поддержку LDA в GPU-PV путем вызова DxgkCbIsFeatureEnabled(DXGK_FEATURE_LDA_GPUPV). Поддержка включена, если функция завершается успешно и возвращает Включено. Если KMD не вызывает этот обратный вызов, Dxgkrnl предполагает, что KMD не поддерживает LDA в GPU-PV.
Если ОС поддерживает эту функцию, то ответственность за включение LDA в пользовательском режиме лежит на драйвере. Если драйвер включает LDA в пользовательском режиме, он должен сделать это следующим образом.
Время выполнения | Состояние LDA |
---|---|
Среда выполнения Pre-D3D12 | Включите, если DXGK_FEATURE_LDA_GPUPV поддерживается, а гостевая ОС — Windows 11 версии 22H2 (WDDM 3.1) или более поздней. |
Среды выполнения, отличные от DX (Windows) | Включите, если DXGK_FEATURE_LDA_GPUPV поддерживается, а гостевая ОС — Windows 11 версии 22H2 (WDDM 3.1) или более поздней. Вместо проверки версии ОС UMD может вызвать D3DKMTQueryAdapterInfo(KMTQAITYPE_PHYSICALADAPTERCOUNT) и включить LDA при возврате числа физических адаптеров больше 1. |
Среда выполнения D3D12 (Windows) | Включить. См. установку состояния LDA для среды выполнения D3D12. |
Linux (среда выполнения d3d12 и не DirectX) | Включите, если поддерживается DXGK_FEATURE_LDA_GPUPV. |
Драйверы, скомпилированные с версией интерфейса меньше DXGKDDI_INTERFACE_VERSION_WDDM3_0, не проверяют DXGK_FEATURE_LDA_GPUPV. Эти драйверы по-прежнему могут включать LDA для сред выполнения Linux.
Настройка состояния LDA для среды выполнения D3D12
При включении или отключении LDA для среды выполнения D3D12 UMD необходимо вернуть правильные сведения о уровне и сопоставлении узлов в среду выполнения. Поток кода выглядит следующим образом:
D3D12 получает доступ к способности D3D12_CROSS_NODE_SHARING_TIER из UMD.
D3D12 получает количество физических адаптеров из Dxgkrnl путем вызова D3DKMTQueryAdapterInfo(KMTQAITYPE_PHYSICALADAPTERCOUNT).
D3D12 вызывает pfnQueryNodeMap(PhysicalAdapterCount, &map) для получения сопоставления индексов логических узлов с физическими узлами. Узел в этом случае означает физический адаптер. UMD должен задать фактический индекс физического адаптера в карте или D3D12DDI_NODE_MAP_HIDE_NODE, чтобы отключить узел.
На основе результатов pfnQueryNodeMap D3D12 вычисляет эффективное число физических адаптеров, не подсчитывая скрытые узлы.
Если состояние уровня производительности и число эффективных физических адаптеров не совпадают, D3D12 не выполняет создание устройства. Несоответствие происходит, когда:
- Уровень равен D3D12DDI_CROSS_NODE_SHARING_TIER_NOT_SUPPORTED, а число адаптеров больше 1.
- Уровень не D3D12DDI_CROSS_NODE_SHARING_TIER_NOT_SUPPORTED, а число адаптеров равно 1.
Чтобы отключить LDA, UMD должно вернуть уровень D3D12DDI_CROSS_NODE_SHARING_TIER_NOT_SUPPORTED и оставить в карте узлов включенным только один физический адаптер.
D3DKMTQueryAdapterInfo(KMTQAITYPE_PHYSICALADAPTERCOUNT)
Запрос KMTQAITYPE_PHYSICALADAPTERCOUNT для числа физических адаптеров всегда возвращает правильное число физических адаптеров гостю.
- В предварительной версии 22H2 гости windows 11 возвращают 1. Это значение жестко закодировано в гостевом коде. Это может измениться в будущем, если поддержка LDA переносится в старые выпуски ОС.
- В Windows 11 версии 22H2 и более поздних системах возвращается:
- Фактическое количество физических адаптеров, когда включена функция DXGK_FEATURE_LDA_GPUPV.
- В противном случае — 1.
Запуск паравиртуализации
Включите поддержку виртуализации в BIOS (VT-d или аналогично). GPU-PV настройка отличается для виртуальных машин типа VMMS и контейнеров.
В PowerShell (работающем от имени администратора) включите выполнение скрипта на сервере:
set-executionpolicy unrestricted
Настройка виртуальной машины VMMS
Настройка узла и виртуальной машины
Сборка ОС на виртуальной машине может быть более старой или более новой, чем сборка ОС на узле.
Включите функцию Hyper-V в ролях сервера или Hyper-V на клиенте. При включении этой функции на сервере выберите параметр для использования сетевого адаптера в качестве внешнего коммутатора.
(необязательно) Включите тестовую подпись (bcdedit -set TESTSIGNING ON)
Перезагрузить.
Установите драйвер GPU, поддерживающий пара-виртуализацию.
(необязательно) Некоторые драйверы не задают ограничение ParavirtualizationSupported. В этом случае добавьте следующий реестр перед установкой драйвера или отключите или включите устройство после установки флага.
DWORD HKLM\System\CurrentControlSet\Control\GraphicsDrivers\GpuVirtualizationFlags = 1
Чтобы проверить, распознает ли ОС паравиртуализированный GPU, выполните следующую команду 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
Выполните следующие команды в PowerShell, чтобы создать виртуальную машину с GPU. Создается виртуальная машина с именем TEST.
$vm = “TEST“ New-VM -VMName $vm -Generation 2 Set-VM -GuestControlledCacheTypes $true -VMName $vm
Задайте пространство ввода-вывода для виртуальной машины. GPU-PV использует пространство ввода-вывода для обработки выделенных ресурсов ЦП. Требуется по крайней мере 8 ГБ пространства ввода-вывода.
Set-VM -LowMemoryMappedIoSpace 1GB -VMName $vm Set-VM -HighMemoryMappedIoSpace 16GB -VMName $vm
[необязательно] По умолчанию базовый адрес для пространства ввода-вывода с высокой памятью имеет значение (64 ГБ – 512 МБ). На микросхемах Haswell с 36-разрядной адресации физической памяти конечный адрес области ввода-вывода должен быть ниже 64 ГБ, поэтому начальный адрес должен быть задан соответствующим образом. Следующий скрипт с именем SetHighMmioBase.ps1задает начальный адрес на 47 ГБ при запуске с следующими параметрами:
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" }
Добавьте виртуальный GPU на виртуальную машину и отключите контрольные точки.
Add-VMGpuPartitionAdapter -VMName $vm Set-VM -CheckpointType Disabled -VMName $vm
Чтобы проверить, имеет ли виртуальная машина паравиртуализированный GPU, выполните следующую команду:
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 :
Скопируйте VHDX той же сборки клиента, которую вы используете в виртуальной машине, в каталог узла. Например,
d:\VM\os.vhdx
.Откройте диспетчер Hyper-V и измените параметры виртуальной машины (выберите виртуальную машину и выберите "Параметры").
- Во вкладке Безопасность уберите отметку Включить Безопасную загрузку.
- Память— проверка включения динамической памяти. Задайте объем памяти размером 1024 МБ или более.
- Процессор— задайте число виртуальных процессоров 2 или 4.
- Сетевой адаптер— выберите сетевой адаптер для использования с виртуальной машиной в раскрывающемся списке. Если включена отладка сети, выберите адаптер Microsoft Debugging NET.
- Контроллер SCSI — жесткий диск — добавление — виртуальный жесткий диск — обзор — выбор
d:\VM\os.vhdx
ОС копирует файлы из хранилища драйверов узла в каталог HostDriverStore в гостевой среде при инициализации адаптера в гостевой системе.
- Подключите VHDX виртуальной машины. Например, на диск f:.
- На подключенной виртуальной машине создайте каталог с именем f:\%windir%\system32\HostDriverStore\FileRepository.
- Репликация файлов драйверов из %windir%\system32\DriverStore на узле на виртуальную машину. На виртуальной машине должна быть f:\%windir%\system32\HostDriverStore\FileRepository\YourDriverDirectory\*.
Если драйверу необходимо получить доступ к файлам из
%windir%\system32
или%windir%\syswow64
, скопируйте файлы в виртуальную машину вручную.Включите тестовый вход на виртуальную машину, если драйверы не подписаны корпорацией Майкрософт. В окне администрирования CMD выполните следующую команду:
bcdedit /store <VM drive>:\EFI\Microsoft\Boot\BCD -set {bootmgr} testsigning on
Отключите VHDX виртуальной машины.
Запустите виртуальную машину.
Подключитесь к виртуальной машине, используя опцию подключения в диспетчере Hyper-V.
ВНУТРИ ВИРТУАЛЬНОЙ МАШИНЫ
Убедитесь, что в диспетчере устройств виртуальной машины есть виртуальное устройство рендеринга. Все отрисовки внутри виртуальной машины проходят через виртуальный графический процессор.
Сценарий PowerShell для настройки виртуальной машины
Следующий скрипт PowerShell — это пример настройки виртуальной машины с нуля. Измените его в соответствии с вашими потребностями.
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
}
Отладка виртуальной машины
Настройте отладчик виртуальной машины так же, как и отладку сети на обычном клиентском компьютере.
Если виртуальная машина не запускается или отображается черный экран:
Отключите виртуальную машину и удалите виртуальную gpu из нее с помощью следующих команд:
$vm = “TEST“ remove-VMGpuPartitionAdapter -VMName $vm -AdapterId “<Id from Get-VMGpuPartitionAdapter>”
Например:
remove-VMGpuPartitionAdapter -VMName $vm -AdapterId “Microsoft:9ABB95E2-D12D-43C3-B840-6F4A9CFB217B\929890BC-BB33-4687-BC1A-F72A4F1B3B3F”
Запустите виртуальную машину. Если он запускается успешно, убедитесь, что файлы драйверов копируются правильно в HostDriverStore на виртуальной машине.
Добавьте vGPU на виртуальную машину с помощью команды
Add-VMGpuPartitionAdapter
.Снова запустите виртуальную машину.
Дополнительные сведения см. в устранении неисправностей.
Настройка контейнера
Разница между контейнерами (также называемыми виртуальными машинами Host Compute System (HCS)) и полной виртуальной машиной заключается в том, что двоичные файлы ОС и файлы хранилища драйверов сопоставляются с контейнером. Таким образом, нет необходимости копировать файлы драйверов в контейнер, если они не нужны в каталоге windows\system32
.
Для безопасных контейнеров:
- Эвакуации драйверов отключены.
- Для того чтобы быть включённым в безопасном контейнере, драйвер должен поддерживать изоляцию IOMMU.
При обновлении драйвера на узле и запуске или остановке GPU узла изменения отражаются в контейнере.
Песочница Windows
Этот тип контейнера используется для использования рискованных приложений. Полный образ рабочего стола передан на хост. Драйвер косвенного отображения используется для удаленного доступа. Графические функции VAIL не используются, поэтому передача изображения рабочего стола на хост медленная.
По умолчанию виртуальный GPU отключен в Windows Sandbox. Чтобы включить его, создайте файл конфигурации WSB (например, config.wsb) и задайте параметр виртуального GPU. Запустите песочницу, щелкнув файл конфигурации.
Пример файла конфигурации:
<Configuration>
<VGpu>Enable</VGpu>
</Configuration>
По умолчанию в контейнере для vGPU отключены функции обхода драйвера. Существует параметр конфигурации для включения обходов драйверов. В следующем примере файла WSB включены поддержка vGPU в песочнице и вызовы драйвера.
<Configuration>
<VGpu>EnableVendorExtensions</VGpu>
</Configuration>
Песочница Windows поддерживает адаптер GPU с возможностью горячего подключения.
Контейнер виртуального приложения, интегрированный локально (VAIL)
Используйте этот тип контейнера для запуска приложений Win32 в узле на основе WCOS (Windows Core Operated System). Образ каждого приложения внутри контейнера передается на хост. Функция Graphics VAIL активирована для удаленного доступа к каждому цепочку буферов приложений. Побеги драйвера включены.
Общие требования к контейнеру
Требования к компьютеру:
- Vtx и Vtd должны быть включены в BIOS (или их эквиваленты: AMD-V, AMD-IOMMU).
- По крайней мере 8 ГБ ОЗУ.
- Более 5 ГБ дискового пространства системы.
Настройка отладчика ядра для песочницы Windows
Использование CMDIAG
Служба менеджера контейнеров (cmservice) управляет Hyper-V изолированными контейнерами. CMDIAG.EXE — это приложение, доступное при установке компонентов Hyper-V и контейнеров. Он включает отладку в режиме ядра для контейнеров, включает подписывание тестов и многое другое.
Диспетчер контейнеров поддерживает отладку по последовательному интерфейсу и NET.
Запустите cmdiag.exe Debug
, чтобы просмотреть параметры.
CMDIAG изменяет параметры отладчика в базовом образе контейнера. При включении отладчика ядра должен выполняться только один экземпляр контейнера.
Остановите службу HVSICS перед изменением параметров отладчика.
# 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
Запуск отладчика на другом компьютере
При использовании последовательного отладчика может потребоваться запустить его на другом компьютере. Используйте kdsrv.exe
для запуска отладчика на другом компьютере. Дополнительные сведения см. в серверах подключения KD .
Чтобы отключить время ожидания во время отладки ядра, установите следующие ключи реестра:
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
Настройка отладчика ядра для контейнера VAIL
- Подключитесь к узлу с помощью telnet. Ip-адрес узла можно получить из параметров сети в ОС узла.
- Используйте
cmdiag.exe
для настройки отладчика.
Настройка отладчика гипервизора
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
Устранение неполадок
В этом разделе содержатся сведения об устранении неполадок с GPU-PV.
Get-VMHostPartitionableGpu
Вызовите Get-VMHostPartitionableGpu, чтобы узнать, есть ли виртуализированный GPU. Если выходные данные пусты, в каком-то месте возникает ошибка (драйвер не задал ограничение виртуализации, виртуализация не включена и т. д.).
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
Использование событий ETW
Dxgkrnl содержит каналы администрирования и операционные каналы для событий ETW. События отображаются в средстве просмотра событий Windows: журнал приложений и служб — Microsoft — Windows — Dxgkrnl.
Средство просмотра событий содержит события из других компонентов, участвующих в создании виртуальной машины с GPU-PV (Hyper-V-Compute, Hyper-V-Worker, Hyper-V-VID и т. д.).
Использование Add-VMGpuPartitionAdapter
При использовании Add-VMGpuPartitionAdapterне указывайте возможность (например, декодирование), если она не требуется. Не используйте 0 для этой возможности.
Использование Remove-VMGpuPartitionAdapter
Если виртуальная машина не запускается или имеет проблемы с отрисовкой, попробуйте удалить виртуальный GPU с виртуальной машины с помощью Remove-VMGpuPartitionAdapter.
remove-VMGpuPartitionAdapter -VMName $vm -AdapterId "Microsoft:9ABB95E2-D12D-43C3-B840-6F4A9CFB217B\929890BC-BB33-4687-BC1A-F72A4F1B3B3F"
Предотвращение запуска виртуальной машины во время загрузки
set-vm -AutomaticStartAction Nothing -VmName TEST
События просмотра событий
Добавьте события в канал просмотра событий для выявления проблем при запуске vGPU. События можно найти в разделе "Журналы приложений и служб\Microsoft\Windows\Dxgkrnl". Каналы событий — административный и операционный.
События происходят, когда:
- vGPU создается
- VGPU уничтожен
- Гость открывает виртуальный адаптер
Файлы событий находятся в:
- c:\Windows\System32\winevt\Logs\Microsoft-Windows-DxgKrnl-Admin.evtx
- c:\Windows\System32\winevt\Logs\Microsoft-Windows-DxgKrnl-Operational.evtx
Проверьте, был ли создан виртуальный графический процессор и наличие ошибок.
Параметры реестра
GpuVirtualizationFlags (Флаги виртуализации GPU)
Раздел реестра GpuVirtualizationFlags используется для задания поведения паравиртуализированных GPU. Ключ находится в:
DWORD HKLM\System\CurrentControlSet\Control\GraphicsDrivers\GpuVirtualizationFlags
Определены следующие биты:
Бит | Описание |
---|---|
0x1 | Принудительно установить ограничение ParavirtualizationSupported для всех аппаратных адаптеров. Используйте этот бит в хосте. |
0x2 | Включить ограничение ParavirtualizationSupported для BasicRender. Используйте этот бит в хосте. |
0x4 | Режим безопасной виртуальной машины будет принудительно включён, в котором все виртуальные машины будут рассматриваться как безопасные. В этом режиме существуют ограничения на драйвер пользовательского режима. Например, драйвер не может использовать вызовы Escape, поэтому они завершаются ошибкой. Используйте этот бит на хосте. |
0x8 | Включите связывание паравиртуализированных адаптеров с адаптером только для отображения. Используйте этот бит в гостевой виртуальной машине. Спаривание включено по умолчанию. |
GuestIoSpaceSizeInMb
Раздел реестра GuestIoSpaceSizeInMb используется для задания размера гостевого пространства ввода-вывода для виртуальных GPU в мегабайтах. Значение по умолчанию — 1000 МБ (1 ГБ). Ключ находится по адресу:
DWORD HKLM\System\CurrentControlSet\Control\GraphicsDrivers\Paravirtualization\GuestIoSpaceSizeInMb
В настоящее время гостевое пространство ввода-вывода реализует видимые для ЦП выделения. Хранилище резервного копирования ЦП в узле закреплено в памяти и сопоставляется с гостевым пространством ввода-вывода. В гостевой системе виртуальный адрес, выделенный в пользовательском режиме, перенаправляется в область пространства ввода-вывода. В некоторых системах Haswell ЦП имеет 36-разрядные физические адреса. Hyper-V в таких системах имеет ограниченный размер пространства ввода-вывода.
Отключение изоляции IOMMU для защищенных виртуальных машин
Если драйвер не поддерживает изоляцию IoMmu, используйте следующий параметр реестра во время разработки, чтобы отключить изоляцию IoMmu.
`DWORD HKLM\SYSTEM\CurrentControlSet\Control\GraphicsDrivers\IoMmuFlags = 8`
Ограничение количества виртуальных функций
По умолчанию число виртуальных функций, предоставляемых адаптером, поддерживающим паравиртуализацию GPU, равно 32. Это означает, что адаптер можно добавить к 32 виртуальным машинам, при условии, что каждая виртуальная машина имеет один адаптер.
Чтобы ограничить количество предоставляемых виртуальных функций, можно использовать следующий параметр реестра.
DWORD HKLM\SYSTEM\CurrentControlSet\Control\GraphicsDrivers\NumVirtualFunctions
Например, если задать для NumVirtualFunctions
значение 1, адаптер можно добавить только к одному GPU один раз. Этот параметр полезен, если на компьютере есть несколько адаптеров GPU, поддерживающих GPU-PV, и вы хотите назначить каждому адаптеру виртуальную машину.
Add-VMGpuPartitionAdapter
не позволяет указать, какой адаптер нужно добавить. Таким образом, если два адаптера добавляются на виртуальную машину, оба могут получить один и тот же адаптер GPU-PV от хоста.
Обновления DDI WDDM 2.4
Следующие обновления DDI выполняются для поддержки паравиртуализации GPU в WDDM 2.4.
Добавлена возможность DXGK_VIDMMCAPS
Функция ParavirtualizationSupported добавляется в структуру DXGK_VIDMMCAPS. Хост KMD устанавливает этот лимит, если он реализует все DDIs, описанные в этом разделе.
Передача частных данных драйвера через DDI
UMD использует различные DDI для обмена частной информацией с соответствующим KMD. При запуске UMD на гостевой виртуальной машине соответствующий вызов KMD DDI происходит в разделе хоста. Поэтому UMD:
- Не удается передать указатели в частных данных.
- Невозможно передать ни один дескриптор в приватных данных.
- Не следует указать KMD внести глобальные изменения состояния GPU, так как это изменение может повлиять на другие запущенные виртуальные машины.
Добавлен флаг VirtualMachineProcess для DxgkDdiCreateProcess
ОС создает рабочий процесс виртуальной машины для каждой работающей виртуальной машины. Dxgkrnl создает соответствующий DXGPROCESS и вызывает DxgkDdiCreateProcess с установленным флагом VirtualMachineWorkerProcess. В этом контексте процесса не создаются ресурсы отрисовки или драйверов. Таким образом, драйвер может пропустить выделение определенных ресурсов.
ОС создает DXGPROCESS на узле для каждого процесса в гостевой виртуальной машине, использующем GPU. Dxgkrnl вызывает DxgkDdiCreateProcess с установленным флагом VirtualMachineProcess. Каждый процесс DXG виртуальной машины принадлежит тому же EPROCESS, что и рабочий процесс виртуальной машины.
Обновление функции DxgkDdiQueryAdapterInfo
Структура DXGKARG_QUERYADAPTERINFO обновляется, чтобы включить следующие поля для поддержки паравиртуализации:
Добавлен элемент Флаги , который позволяет Dxgkrnl указать следующее:
- Он задает VirtualMachineData, чтобы указать, что вызов поступает из виртуальной машины.
- Он задает SecureVirtualMachine, чтобы указать, что виртуальная машина выполняется в безопасном режиме.
добавляется hKmdProcessHandle, что позволяет драйверу определять и использовать правильный контекст процесса на стороне узла при работе с запросами, исходящими из гостевой виртуальной машины.
Обновления DxgkDdiEscape
Элемент hKmdProcessHandle добавляется в структуру DXGKARG_ESCAPE, чтобы разрешить драйверу определять и использовать правильный контекст процесса на стороне узла при работе с escape-файлами, исходящими из гостевой виртуальной машины.
Флаг VirtualMachineData добавляется в структуру D3DDDI_ESCAPEFLAGS, чтобы указать, что DxgkDdiEscape вызывается из виртуальной машины.
Физический доступ к выделениям GPU
В настоящее время драйвер не реализует физический доступ к выделениям. Драйвер должен поддерживать GpuMmu.
Обновления WDDM 2.5 DDI
Для WDDM 2.5 следующие изменения DDI также требуются для поддержки паравиртуализации.
Сигнализация гостевых событий со стороны хозяина KMD
Существуют сценарии, которые существуют без виртуализации, когда KMD должен сигнализировать о событии, созданном UMD. Для обработки таких сценариев при использовании паравиртуализации KMD на узле должен сигнализировать о событии, созданном в госте. Для этой цели добавляется функция обратного вызова DxgkCbSignalEvent. KMD также может использовать этот обратный вызов, чтобы сигнализировать о событиях процессов хоста.
Поддержка дескрипторов, предоставляемых UMD в виртуальной машине
Некоторые обратные вызовы драйвера принимают Dxgkrnl распределение или дескриптор ресурсов, переданные UMD, например:
Вызовы на узле должны осуществляться в контексте того же потока, который вызвал функцию DxgkDdiXxx.
Например, предположим, что без виртуализации KMD вызывает DxgkCbAcquireHandleData в контексте потока пользовательского режима, который вызывает D3DKMTEscape, что в свою очередь вызывает DxgkDdiEscape.
Когда UMD выполняется на виртуальной машине, он знает только дескрипторы выделения гостевой памяти и не может передавать такие дескрипторы в KMD, так как KMD выполняется на хосте. UMD в гостевой системе вызывает D3DKMTEscape, а KMD в хосте получает соответствующий вызов DxgkDdiEscape. KMD должен вызывать DxgkCbAcquireHandleData в контексте этого потока.
Чтобы иметь возможность переводить дескриптор выделения и ресурсов гостя в соответствующий дескриптор хоста, добавляется флаг ухода драйвера D3DDDI_ESCAPEFLAGS::DriverKnownEscape.
При вызове D3DKMTEscape с флагом DriverKnownEscape :
Задайте для D3DKMT_ESCAPE::Type значение D3DKMT_ESCAPE_DRIVERPRIVATE.
Задайте D3DKMT_ESCAPE::p PrivateDriverData указывать на известную структуру escape-драйвера, определенную в следующем разделе. Каждая структура начинается со значения D3DDDI_DRIVERESCAPETYPE.
Если виртуализация не используется, преобразованный дескриптор совпадает с дескриптором ввода.
Определены следующие известные экраны драйверов.
В следующем фрагменте кода показано, как использовать флаг 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);
Обновления DDI WDDM 2.6
Начиная с версии WDDM 2.6 (Windows 10 версии 1903), для поддержки паравиртуализации были сделаны следующие обновления:
Драйвер может использовать флаг DXGK_ALLOCATIONINFOFLAGS::ACCESSEDPHYSICALLY на виртуальной машине. До WDDM 2.6 драйвер не мог использовать этот флаг в виртуальной машине, и создание выделения с этим флагом завершалось неудачно.
UMD может использовать Pfnd3dkmtUpdateallocationproperty в виртуальной машине. Перед WDDM 2.6 этот вызов завершится ошибкой.