Created
June 4, 2021 05:04
-
-
Save Riebart/0b6ff09f66e9d4120b56ba61e990b41d to your computer and use it in GitHub Desktop.
Borrowed from https://community.spiceworks.com/topic/2262892-how-to-make-hyper-v-passthrough-gpu-in-winodws-10-pro
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# | |
# These variables are device properties. For people who are very | |
# curious about this, you can download the Windows Driver Kit headers and | |
# look for pciprop.h. All of these are contained in that file. | |
# | |
$devpkey_PciDevice_DeviceType = "{3AB22E31-8264-4b4e-9AF5-A8D2D8E33E62} 1" | |
$devpkey_PciDevice_RequiresReservedMemoryRegion = "{3AB22E31-8264-4b4e-9AF5-A8D2D8E33E62} 34" | |
$devpkey_PciDevice_AcsCompatibleUpHierarchy = "{3AB22E31-8264-4b4e-9AF5-A8D2D8E33E62} 31" | |
$devprop_PciDevice_DeviceType_PciConventional = 0 | |
$devprop_PciDevice_DeviceType_PciX = 1 | |
$devprop_PciDevice_DeviceType_PciExpressEndpoint = 2 | |
$devprop_PciDevice_DeviceType_PciExpressLegacyEndpoint = 3 | |
$devprop_PciDevice_DeviceType_PciExpressRootComplexIntegratedEndpoint= 4 | |
$devprop_PciDevice_DeviceType_PciExpressTreatedAsPci = 5 | |
$devprop_PciDevice_BridgeType_PciConventional = 6 | |
$devprop_PciDevice_BridgeType_PciX = 7 | |
$devprop_PciDevice_BridgeType_PciExpressRootPort = 8 | |
$devprop_PciDevice_BridgeType_PciExpressUpstreamSwitchPort = 9 | |
$devprop_PciDevice_BridgeType_PciExpressDownstreamSwitchPort = 10 | |
$devprop_PciDevice_BridgeType_PciExpressToPciXBridge = 11 | |
$devprop_PciDevice_BridgeType_PciXToExpressBridge = 12 | |
$devprop_PciDevice_BridgeType_PciExpressTreatedAsPci = 13 | |
$devprop_PciDevice_BridgeType_PciExpressEventCollector = 14 | |
$devprop_PciDevice_AcsCompatibleUpHierarchy_NotSupported = 0 | |
$devprop_PciDevice_AcsCompatibleUpHierarchy_SingleFunctionSupported = 1 | |
$devprop_PciDevice_AcsCompatibleUpHierarchy_NoP2PSupported = 2 | |
$devprop_PciDevice_AcsCompatibleUpHierarchy_Supported = 3 | |
write-host "Generating a list of PCI Express endpoint devices" | |
$pnpdevs = Get-PnpDevice -PresentOnly | |
$pcidevs = $pnpdevs | Where-Object {$_.InstanceId -like "PCI*"} | |
foreach ($pcidev in $pcidevs) { | |
Write-Host "" | |
Write-Host "" | |
Write-Host -ForegroundColor White -BackgroundColor Black $pcidev.FriendlyName | |
$rmrr = ($pcidev | Get-PnpDeviceProperty $devpkey_PciDevice_RequiresReservedMemoryRegion).Data | |
if ($rmrr -ne 0) { | |
write-host -ForegroundColor Red -BackgroundColor Black "BIOS requires that this device remain attached to BIOS-owned memory. Not assignable." | |
continue | |
} | |
$acsUp = ($pcidev | Get-PnpDeviceProperty $devpkey_PciDevice_AcsCompatibleUpHierarchy).Data | |
if ($acsUp -eq $devprop_PciDevice_AcsCompatibleUpHierarchy_NotSupported) { | |
write-host -ForegroundColor Red -BackgroundColor Black "Traffic from this device may be redirected to other devices in the system. Not assignable." | |
continue | |
} | |
$devtype = ($pcidev | Get-PnpDeviceProperty $devpkey_PciDevice_DeviceType).Data | |
if ($devtype -eq $devprop_PciDevice_DeviceType_PciExpressEndpoint) { | |
Write-Host "Express Endpoint -- more secure." | |
} else { | |
if ($devtype -eq $devprop_PciDevice_DeviceType_PciExpressRootComplexIntegratedEndpoint) { | |
Write-Host "Embedded Endpoint -- less secure." | |
} else { | |
if ($devtype -eq $devprop_PciDevice_DeviceType_PciExpressTreatedAsPci) { | |
Write-Host -ForegroundColor Red -BackgroundColor Black "BIOS kept control of PCI Express for this device. Not assignable." | |
} else { | |
Write-Host -ForegroundColor Red -BackgroundColor Black "Old-style PCI device, switch port, etc. Not assignable." | |
} | |
continue | |
} | |
} | |
$locationpath = ($pcidev | get-pnpdeviceproperty DEVPKEY_Device_LocationPaths).data[0] | |
# | |
# If the device is disabled, we can't check the resources, report a warning and continue on. | |
# | |
# | |
if ($pcidev.ConfigManagerErrorCode -eq "CM_PROB_DISABLED") | |
{ | |
Write-Host -ForegroundColor Yellow -BackgroundColor Black "Device is Disabled, unable to check resource requirements, it may be assignable." | |
Write-Host -ForegroundColor Yellow -BackgroundColor Black "Enable the device and rerun this script to confirm." | |
$locationpath | |
continue | |
} | |
# | |
# Now do a check for the interrupts that the device uses. Line-based interrupts | |
# aren't assignable. | |
# | |
$doubleslashDevId = "*" + $pcidev.PNPDeviceID.Replace("\","\\") + "*" | |
$irqAssignments = gwmi -query "select * from Win32_PnPAllocatedResource" | Where-Object {$_.__RELPATH -like "*Win32_IRQResource*"} | Where-Object {$_.Dependent -like $doubleslashDevId} | |
#$irqAssignments | Format-Table -Property __RELPATH | |
if ($irqAssignments.length -eq 0) { | |
Write-Host -ForegroundColor Green -BackgroundColor Black " And it has no interrupts at all -- assignment can work." | |
} else { | |
# | |
# Find the message-signaled interrupts. They are reported with a really big number in | |
# decimal, one which always happens to start with "42949...". | |
# | |
$msiAssignments = $irqAssignments | Where-Object {$_.Antecedent -like "*IRQNumber=42949*"} | |
#$msiAssignments | Format-Table -Property __RELPATH | |
if ($msiAssignments.length -eq 0) { | |
Write-Host -ForegroundColor Red -BackgroundColor Black "All of the interrupts are line-based, no assignment can work." | |
continue | |
} else { | |
Write-Host -ForegroundColor Green -BackgroundColor Black " And its interrupts are message-based, assignment can work." | |
} | |
} | |
# | |
# Check how much MMIO space the device needs | |
# not strictly an issue devices, but very useful when you want to set MMIO gap sizes | |
# | |
$mmioAssignments = gwmi -query "select * from Win32_PnPAllocatedResource" | Where-Object {$_.__RELPATH -like "*Win32_DeviceMemoryAddress*"} | Where-Object {$_.Dependent -like $doubleslashDevId} | |
$mmioTotal = 0 | |
foreach ($mem in $mmioAssignments) | |
{ | |
$baseAdd =$mem.Antecedent.SubString($mem.Antecedent.IndexOf("""")+1) | |
$baseAdd=$baseAdd.SubString(0,$baseAdd.IndexOf("""")) | |
$mmioRange = gwmi -query "select * from Win32_DeviceMemoryAddress" | Where-Object{$_.StartingAddress -like $baseAdd} | |
$mmioTotal = $mmioTotal + $mmioRange.EndingAddress - $mmioRange.StartingAddress | |
} | |
if ($mmioTotal -eq 0) | |
{ | |
Write-Host -ForegroundColor Green -BackgroundColor Black " And it has no MMIO space" | |
} else { | |
[int]$mmioMB = [math]::ceiling($mmioTotal / 1MB) | |
Write-Host -ForegroundColor Green -BackgroundColor Black " And it requires at least:" $mmioMB "MB of MMIO gap space" | |
} | |
# | |
# Print out the location path, as that's the way to refer to this device that won't | |
# change even if you add or remove devices from the machine or change the way that | |
# the BIOS is configured. | |
# | |
$locationpath | |
} | |
# | |
# Now look at the host as a whole. Asking whether the host supports SR-IOV | |
# is mostly equivalent to asking whether it supports Discrete Device | |
# Assignment. | |
# | |
if ((Get-VMHost).IovSupport -eq $false) { | |
Write-Host "" | |
write-host "Unfortunately, this machine doesn't support using them in a VM." | |
Write-Host "" | |
(Get-VMHost).IovSupportReasons | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment