qshinoの日記

Powershell関係と徒然なこと

Powershell GPU DDA/Discreet Device Assignment

DDA

Microsoft Discreet Device Assignment/DDAでGPUVMにパススルー。

全体の流れはdda-sample関数参照。エラー処理なしの一方通行。VM設定→デバイスのロケーションパス取得→VMにデバイスアサイン。

Sample code

Parameter

  • VM MMIO space for low and High
  • DDA Device Class and Vender.
  • VM name

Sample

# 
# DDA sample
# 
#     Assign device to vm
#
# Parameters
#
Param(
$vm       = "foo" , 
$mmio_low  = 3Gb, 
$mmio_high = 33280Mb, 
$cls      = "display", 
$vender   = "NVIDIA"
)
#
# prepare-vm 
#
#     Configure the VM before Assignment
#
function prepare-vm($vm, $low, $high){
   #Set automatic stop action to TurnOff
   Set-VM -Name $vm -AutomaticStopAction TurnOff 

   #Enable Write-Combining on the CPU
   Set-VM -GuestControlledCacheTypes $true -VMName $vm 

   #Configure 32 bit MMIO space 
    Set-VM -LowMemoryMappedIoSpace  $low -VMName $vm 

    #Configure Greater than 32 bit MMIO space 
    Set-VM -HighMemoryMappedIoSpace $high  -VMName $vm 
}

#
# get-location
# 
#   Find the device Location Path
#
function get-devices ($cls, $vender){
    #Enumerate all PNP Devices on the system 
    $devs = Get-PnpDevice -presentOnly 

    #Select only those devices that are Display devices manufactured by NVIDIA 
    $gpus = $devs |? {$_.Class -like $cls -and $_.Manufacturer -like $vender} 

    return $gpus
}


function get-locationpath($devs){
    #Select the location path of the first device that's available to be dismounted by the host. 
    $lp = ($devs | Get-PnpDeviceProperty DEVPKEY_Device_LocationPaths).data[0] 

    return $lp
}

# 
# Assign device
#
# 1. Disable device
# 2. Dismount device
# 3. Assign device
#
function assign-dev($vm, $lp, $dev){

  #Disable the PNP Device 
  Disable-PnpDevice -InstanceId $dev.InstanceId 

  #Dismount the Device from the Host
  Dismount-VMHostAssignableDevice -force -LocationPath $lp

  #Assign the device to the guest VM.
  Add-VMAssignableDevice -LocationPath $lp -VMName $vm
}

function dda-sample($vm, $low, $high, $cls, $vender){
    prepare-vm $vm $low $high
    $devs = get-devices $cls $vender #return  array
    $lp = get-locationpath $devs # return one
    assign-dev $vm $lp devs[0]
}

#
# recover-dev
#
#   1. remove-device
#   2. mount dev
#
function recover-dev($vm, $lp){
    #Remove the device from the VM
    Remove-VMAssignableDevice -LocationPath $lp -VMName $vm

    #Mount the device back in the host
    Mount-VMHostAssignableDevice -LocationPath $lp
}

dda-sample $vm $mmio_low $mmio_high $cls $vender

ref

https://docs.microsoft.com/en-us/windows-server/virtualization/hyper-v/deploy/deploying-graphics-devices-using-dda