Discrete Device Assignment: Windows 2016 Servers.

With Windows Server 2016, there is new feature introduced, called Discrete Device Assignment, in Hyper-V. Users can now take some of the PCI Express devices in their systems and pass them through directly to a guest VM. This functionality is only there in the case of ESXi and AHV/KVM.

PCIe device pass-through is going to solve a lot of problem on Hyper-V platform, so far we were using disk pass-through (Hyper-V allows virtual machines to access storage mapped directly to the Hyper-V server without requiring the volume be configured.), which meant that we were relying on host for actual IO and were not getting optimum throughput as compared to other hypervisors.

Configuring Pass-through Disks in Hyper-V
Screen Shot 2017-06-06 at 12.50.30 PM
On Windows Server 2016, we finally get the ability to directly work with devices on the host and attach them to a child partition (guest VM) without being limited to only networking and storage. This feature was probably built for passing-through graphics processing units (GPUs) in Azure for N-series VMs (GPU-enabled VMs) however at the moment, we are qualifying it for SCSI disks as well.

Passing through devices to Hyper-V VMs by using discrete device assignment

The driver, which manages to get this done is pci.sys (NT Plug and Play PCI Enumerator)
By default, during the deployment, this should be configured and Repair-CVM, will take care of this during troubleshooting or PCI controller replacement. However adding the PCI device directly to CVM is really easy. ASPM in BIOS should be enabled,

Get-PnpDevice | Where-Object {$_.class -eq "scsiadapter"} | ft FriendlyName, InstanceId

FriendlyName InstanceId
------------ ----------
Microsoft Storage Spaces Controller ROOT\SPACEPORT\0000
Microsoft ClusPort HBA ROOT\CLUSPORT\0000
Avago Adapter, SAS3 3008 Fury -StorPort PCI\VEN_1000&DEV_0097&SUBSYS_080815D9&REV_02\4&364B5553&0&0008
Microsoft VHD Loopback Controller {8E7BD593-6E6C-4C52-86A6-77175494DD8E}\MSVHDHBA\1&3030E83&0&01
Get-PnpDeviceProperty -InstanceId "PCI\VEN_1000&DEV_0097&SUBSYS_080815D9&REV_02\4&364B5553&0&0008" | findstr DEVPKEY_Device_LocationPaths | fl *
PCI\VEN... DEVPKEY_Device_LocationPaths StringList {PCIROOT(0)#PCI(0100)#PCI(0000), ACPI(_SB_)#ACPI(PCI0)#A...

Get-VMAssignableDevice *
InstanceID : PCIP\VEN_1000&DEV_0097&SUBSYS_080815D9&REV_02\4&364B5553&0&0008
LocationPath : PCIROOT(0)#PCI(0100)#PCI(0000)
ResourcePoolName : Primordial
Name : Virtual PCI Express Port Settings
Id : Microsoft:03409128-2123-4030-9155-56785696146A\28347332-24C0-468F-8E2A-974C3A0AF37E
VMId : 03409128-2123-4030-9155-56785696146a
VMName : NTNX-16SM6C500255-A-CVM
VMSnapshotId : 00000000-0000-0000-0000-000000000000
VMSnapshotName :
CimSession : CimSession: .
ComputerName : GOGO-1
IsDeleted : False
VMCheckpointId : 00000000-0000-0000-0000-000000000000

Add-VMAssignableDevice -LocationPath "PCIROOT(0)#PCI(0100)#PCI(0000)" -VMName *CVM*

However there can be a scenario that the device is mounted on host, so we need to disable the device first

Dismount-VMHostAssignableDevice -LocationPath

Discrete Device Assignment

hv: New paravirtual PCI front-end for Hyper-V VMs