summary refs log tree commit diff
path: root/drivers/xen/xen-pciback/vpci.c
diff options
context:
space:
mode:
authorLaszlo Ersek <lersek@redhat.com>2012-10-17 11:55:55 +0200
committerKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>2012-10-19 15:17:47 -0400
commit8a5248fe10b101104d92d01438f918e899414fd1 (patch)
treea995ee103e16708cc393fcf11f6bdef07de9adb7 /drivers/xen/xen-pciback/vpci.c
parente9d1aa05da264cf7e1906b81a90d6abfdbe3700b (diff)
downloadlinux-8a5248fe10b101104d92d01438f918e899414fd1.tar.gz
xen PV passthru: assign SR-IOV virtual functions to separate virtual slots
VFs are reported as single-function devices in PCI_HEADER_TYPE, which
causes pci_scan_slot() in the PV domU to skip all VFs beyond #0 in the
pciback-provided slot. Avoid this by assigning each VF to a separate
virtual slot.

Acked-by: Jan Beulich <jbeulich@suse.com>
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Diffstat (limited to 'drivers/xen/xen-pciback/vpci.c')
-rw-r--r--drivers/xen/xen-pciback/vpci.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/drivers/xen/xen-pciback/vpci.c b/drivers/xen/xen-pciback/vpci.c
index 46d140baebd8..0f478ac483cd 100644
--- a/drivers/xen/xen-pciback/vpci.c
+++ b/drivers/xen/xen-pciback/vpci.c
@@ -89,9 +89,15 @@ static int __xen_pcibk_add_pci_dev(struct xen_pcibk_device *pdev,
 
 	mutex_lock(&vpci_dev->lock);
 
-	/* Keep multi-function devices together on the virtual PCI bus */
-	for (slot = 0; slot < PCI_SLOT_MAX; slot++) {
-		if (!list_empty(&vpci_dev->dev_list[slot])) {
+	/*
+	 * Keep multi-function devices together on the virtual PCI bus, except
+	 * virtual functions.
+	 */
+	if (!dev->is_virtfn) {
+		for (slot = 0; slot < PCI_SLOT_MAX; slot++) {
+			if (list_empty(&vpci_dev->dev_list[slot]))
+				continue;
+
 			t = list_entry(list_first(&vpci_dev->dev_list[slot]),
 				       struct pci_dev_entry, list);
 
@@ -116,7 +122,7 @@ static int __xen_pcibk_add_pci_dev(struct xen_pcibk_device *pdev,
 			       pci_name(dev), slot);
 			list_add_tail(&dev_entry->list,
 				      &vpci_dev->dev_list[slot]);
-			func = PCI_FUNC(dev->devfn);
+			func = dev->is_virtfn ? 0 : PCI_FUNC(dev->devfn);
 			goto unlock;
 		}
 	}