June 6, 2020 · Windows Hardware Virtualization

How To: Get Consumer GPUs Working In Hyper-V Virtual Machines

Changelog

06/06/2020 - Initial publish. (⚠ AMD GPU support is not ready yet.)

Hat tip

Thanks to Tomas N. for testing and being extremely patient while I wrote this all up.

You will need

Check for IOMMU support

The following tests on the host machine will provide hints to whether or not an IOMMU is present and available.

  1. Execute the following PowerShell command on the host machine:

    (Get-VMHost).IovSupport; (Get-VMHost).IovSupportReasons
    

    This cmdlet will return True or False if Single-Root Input/Output Virtualization (SR-IOV) is supported. This is not required but tends to be supported on hardware that also hosts an IOMMU.

  2. Use Read & Write Utility to check ACPI structures for IOMMU related tables.

    • AMD: I/O Virtualization Reporting Structure (IVRS) table
    • Intel: DMA Remapping Table (DMAR) table

    In the Read & Write Utility, click the ACPI button then check for an IVRS/DMAR tab. It should appear to contain data, if present, and not be zeroed out.

Set up Hyper-V Discrete Device Assignment (DDA)

Installation and general configuration of Hyper-V is out of scope. The following steps will configure DDA for selected GPUs and should all be executed on the host machine. A virtual machine with the name "vm-aa2baf5d3ccbe840" is assumed. Change as needed.

  1. Shutdown the virtual machine.

  2. Execute the following PowerShell command to prepare the virtual machine for DDA:

    Set-VM -VMName "vm-aa2baf5d3ccbe840" -LowMemoryMappedIoSpace 3Gb -HighMemoryMappedIoSpace 33280Mb -GuestControlledCacheTypes $true -AutomaticStopAction TurnOff
    
  3. Execute the following PowerShell command to retrieve all GPU locations in the device tree:

    Get-PnpDevice -Class Display | ForEach-Object { Write-Output "$($_.FriendlyName) has a device id of $($_.DeviceId) and is located at $($_ | Get-PnpDeviceProperty DEVPKEY_Device_LocationPaths | Select-Object -ExpandProperty Data | Where-Object { $_ -like "PCIROOT*" })"; }
    

    Example output:

    NVIDIA GeForce GTX 980 has a device id of PCI\VEN_10DE&DEV_13C0&SUBSYS_85181043&REV_A1\4&1C3D25BB&0&0019 and is located at PCIROOT(0)#PCI(0301)#PCI(0000)
    
  4. Disable and dismount the GPU that will be assigned to the virtual machine by executing the following PowerShell commands (using information from the earlier steps):

    Disable-PnpDevice "PCI\VEN_10DE&DEV_13C0&SUBSYS_85181043&REV_A1\4&1C3D25BB&0&0019"
    
    Dismount-VMHostAssignableDevice -LocationPath "PCIROOT(0)#PCI(0301)#PCI(0000)" -Force
    
  5. Assign the GPU (and related audio device) to the virtual machine by executing the following PowerShell command:

    Add-VMAssignableDevice -LocationPath "PCIROOT(0)#PCI(0301)#PCI(0000)" -VmName "vm-aa2baf5d3ccbe840"
    
    Add-VMAssignableDevice -LocationPath "PCIROOT(0)#PCI(0301)#PCI(0001)" -VmName "vm-aa2baf5d3ccbe840"
    
  6. Start the virtual machine.

Disable Access Control Services (ACS) and unique RID checks (optional)

If a particular GPU doesn't advertise support for unique requestor IDs or ACS, GPU assignment will fail. Execute the following commands (in an elevated PowerShell instance) on the host machine to disable these checks:

Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\HyperV" -Name "RequireSecureDeviceAssignment" -Type DWORD -Value 0 -Force

Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\HyperV" -Name "RequireSupportedDeviceAssignment" -Type DWORD -Value 0 -Force

Patch graphic card drivers

The following steps will patch your graphic card drivers, removing hypervisor checks.

  1. Mount the Enterprise WDK (EWDK) for Windows 10 ISO.

  2. Execute [mount]:\LaunchBuildEnv.cmd, then execute the powershell command.

  3. Navigate to the location containing the Remove-HypervisorChecks.ps1 script and execute the following PowerShell commands:

    ./Remove-HypervisorChecks.ps1 -Nvidia -DriverPath "path\to\driver\package.exe"
    

    Tip: Replace -Nvidia with -Amd if using an AMD GPU.

  4. Wait for script completion.

  5. Copy the patched driver (patched-driver.zip) to the guest virtual machine and install.