[libvirt] Question about pci-passthrough

Hello All, I had a question about pci-passthrough using hostdev mode in Libvirt. When I assign hostdev->parent.type = VIR_DOMAIN_DEVICE_NET, the hostdev is passed into the guest and acts as a network device. When I assign hostdev->parent.type = VIR_DOMAIN_DEVICE_NONE, the hostdev is passed into the guest and acts as a PCI Host device. Please can someone point me to the part of code in libvirt where this decision is made based on hostdev->parent.type? -- Many Thanks, Regards, Shradha Shah

On 07/26/2012 11:53 AM, Shradha Shah wrote:
Hello All,
I had a question about pci-passthrough using hostdev mode in Libvirt.
When I assign hostdev->parent.type = VIR_DOMAIN_DEVICE_NET, the hostdev is passed into the guest and acts as a network device.
Actually, aside from libvirt setting the MAC address prior to assigning the device to the guest, all the rest of the handling is identical to that of a PCI device.
When I assign hostdev->parent.type = VIR_DOMAIN_DEVICE_NONE, the hostdev is passed into the guest and acts as a PCI Host device.
Please can someone point me to the part of code in libvirt where this decision is made based on hostdev->parent.type?
I'm curious why you're setting those yourself. that's really something internal that should only be set when parsing a device defined as <interface type='hostdev'> - this ends up creating entries for both types of devices, a virDomainNetDef and a virDomainHostdevDef, that are tightly intertwined. If you attempt to just allocate your own virDomainHostdevDef and set hostdev->parent.type = VIR_DOMAIN_DEVICE_NET, you will have a "very bad time" (tm). The code assumes that any HostdevDef that has a parent-type != NONE is not a standalone object, but is one that resides within a higher level object (see the definition of _virDomainNetDef, in particular the "virDomainHostdevDef def" that is defined within it). The *only way* to setup one of these objects that will work properly is to create a virDomainNetDef object (e.g. call it "net"), then set net->type = VIR_DOMAIN_NET_TYPE_HOSTDEV, and initialize net->data.hostdev.dev with all the hostdev info, including pointing its "parent back to the original "net". Likewise, the virDomainNetDef that you create *must* be placed on the domain's list of network devices and &net->data.hostdev.def *must* be placed on the domain's list of hostdevs. All of this is handled for you by virDomainNetDefParse (look for the VIR_DOMAIN_NET_TYPE_HOSTDEV case). As to where the decision is made about how to treat the device - for starters, <interface type='hostdev'> devices are never attached by calling the function to do a hostdev attach (qemuDomainAttachHostDevice)directly - they are attached by calling the function that does an attach of a net device (qemuDomainAttachNetDevice) - that function calls networkAllocateActualDevice if necessary (in case it's a type='hostdev' hiding behind a type='network') and then if the "actualType" is hostdev, calls qemuDomainAttachHostDevice to do the rest of the work. qemuDomainAttachHostDevice will call down a couple of levels to qemuPrepareHostdevPCIDevices, which will check for hostdev->parent.type == VIR_DOMAIN_DEVICE_NET, and if so will call qemuDomainHostdevNetConfigReplace, which calls the functions that do the netdev-specific setup (i.e. setting the MAC address, although I plan to also add support for setting the VLAN tag). So, a more organized version of this: 1) if you want a hybrid netdev/hostdev, start by creating a virDomainNetDef and filling in the hostdev part, not vice versa, and make sure the corresponding parts are on their respective lists for the domain. (hostdevs and nets) 2) to attach/detach any of these devices, call the *net* version of the attach/detach functions, not the hostdev version. 3) The place that checks if a particular device is a network-type of hostdev, is qemuPrepareHostdevPCIDevices - look for "hostdev->parent.type == VIR_DOMAIN_DEVICE_NET" in that function and follow the call chain down from there to where the action is.

On 07/26/2012 11:53 AM, Shradha Shah wrote:
Hello All,
I had a question about pci-passthrough using hostdev mode in Libvirt.
When I assign hostdev->parent.type = VIR_DOMAIN_DEVICE_NET, the hostdev is passed into the guest and acts as a network device.
Actually, aside from libvirt setting the MAC address prior to assigning the device to the guest, all the rest of the handling is identical to that of a PCI device.
When I assign hostdev->parent.type = VIR_DOMAIN_DEVICE_NONE, the hostdev is passed into the guest and acts as a PCI Host device.
Please can someone point me to the part of code in libvirt where this decision is made based on hostdev->parent.type?
I'm curious why you're setting those yourself. that's really something internal that should only be set when parsing a device defined as <interface type='hostdev'> - this ends up creating entries for both types of devices, a virDomainNetDef and a virDomainHostdevDef, that are tightly intertwined. I am working on HOSTDEV_HYBRID patches. I am following the exact same steps as for HOSTDEV mode. So in the Hybrid mode I need a net device in the guest along with the VF,
Hello Laine, Thanks for your help. Please find my comments inline. On 07/27/2012 08:41 PM, Laine Stump wrote: the VF needs to be pushed into the guest as a PCI device.
If you attempt to just allocate your own virDomainHostdevDef and set hostdev->parent.type = VIR_DOMAIN_DEVICE_NET, you will have a "very bad time" (tm). The code assumes that any HostdevDef that has a parent-type != NONE is not a standalone object, but is one that resides within a higher level object (see the definition of _virDomainNetDef, in particular the "virDomainHostdevDef def" that is defined within it). The *only way* to setup one of these objects that will work properly is to create a virDomainNetDef object (e.g. call it "net"), then set net->type = VIR_DOMAIN_NET_TYPE_HOSTDEV, and initialize net->data.hostdev.dev with all the hostdev info, including pointing its "parent back to the original "net". Likewise, the virDomainNetDef that you create *must* be placed on the domain's list of network devices and &net->data.hostdev.def *must* be placed on the domain's list of hostdevs. All of this is handled for you by virDomainNetDefParse (look for the VIR_DOMAIN_NET_TYPE_HOSTDEV case).
Agreed
As to where the decision is made about how to treat the device - for starters, <interface type='hostdev'> devices are never attached by calling the function to do a hostdev attach (qemuDomainAttachHostDevice)directly - they are attached by calling the function that does an attach of a net device (qemuDomainAttachNetDevice) - that function calls networkAllocateActualDevice if necessary (in case it's a type='hostdev' hiding behind a type='network') and then if the "actualType" is hostdev, calls qemuDomainAttachHostDevice to do the rest of the work. qemuDomainAttachHostDevice will call down a couple of levels to qemuPrepareHostdevPCIDevices, which will check for hostdev->parent.type == VIR_DOMAIN_DEVICE_NET, and if so will call qemuDomainHostdevNetConfigReplace, which calls the functions that do the netdev-specific setup (i.e. setting the MAC address, although I plan to also add support for setting the VLAN tag).
Agreed
So, a more organized version of this:
1) if you want a hybrid netdev/hostdev, start by creating a virDomainNetDef and filling in the hostdev part, not vice versa, and make sure the corresponding parts are on their respective lists for the domain. (hostdevs and nets)
I have followed this step, Created the virDomainNetDef and filled in the hostdev part but I had to assign hostdev->parent.type = VIR_DOMAIN_DEVICE_NONE as I wanted to push the VF as a PCI device into the guest.
2) to attach/detach any of these devices, call the *net* version of the attach/detach functions, not the hostdev version.
I have correctly followed this step as well.
3) The place that checks if a particular device is a network-type of hostdev, is qemuPrepareHostdevPCIDevices - look for "hostdev->parent.type == VIR_DOMAIN_DEVICE_NET" in that function and follow the call chain down from there to where the action is.
The only problem now is, since hostdev->parent.type = VIR_DOMAIN_DEVICE_NONE I cannot assign the VF a mac address. If I change hostdev->parent.type = VIR_DOMAIN_DEVICE_NET, I am able to assign VF a mac address but the VF is pushed into the guest as a net device not a PCI device.
So I am able to push the VF into the guest as a PCI device along with a virio net device but I cannot resolve the problem of assigning a MAC address to the VF. This is the only issue remaining in the HOSTDEV_HYBRID patches. Many Thanks, Regards, Shradha Shah
participants (2)
-
Laine Stump
-
Shradha Shah