[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] [PATCH 7/7] support multifunction PCI device



If qemu supports multi function PCI device, the format of the PCI address passed
to qemu is "bus=pci.0,multifunction=on,addr=slot.function".

If qemu does not support multi function PCI device, the format of the PCI address
passed to qemu is "bus=pci.0,addr=slot".
---
 src/conf/domain_conf.c  |    3 +++
 src/qemu/qemu_command.c |   27 +++++++++++++++++++++------
 2 files changed, 24 insertions(+), 6 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 8ff155b..6d70efd 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -1296,6 +1296,9 @@ int virDomainDeviceAddressIsValid(virDomainDeviceInfoPtr info,
 
 int virDomainDevicePCIAddressIsValid(virDomainDevicePCIAddressPtr addr)
 {
+    /* PCI bus has 32 slots and 8 functions per slot */
+    if (addr->slot >= 32 || addr->function >= 8)
+        return 0;
     return addr->domain || addr->bus || addr->slot;
 }
 
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index da18719..21c7cdb 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -1251,10 +1251,20 @@ qemuBuildDeviceAddressStr(virBufferPtr buf,
                             _("Only PCI device addresses with bus=0 are supported"));
             return -1;
         }
-        if (info->addr.pci.function != 0) {
-            qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                            _("Only PCI device addresses with function=0 are supported"));
-            return -1;
+        if (qemuCapsGet(qemuCaps, QEMU_CAPS_PCI_MULTIFUNCTION)) {
+            if (info->addr.pci.function > 7) {
+                qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                                _("The function of PCI device addresses must "
+                                  "less than 8"));
+                return -1;
+            }
+        } else {
+            if (info->addr.pci.function != 0) {
+                qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                                _("Only PCI device addresses with function=0 "
+                                  "are supported"));
+                return -1;
+            }
         }
 
         /* XXX
@@ -1264,9 +1274,14 @@ qemuBuildDeviceAddressStr(virBufferPtr buf,
          * to pciNN.0  where NN is the domain number
          */
         if (qemuCapsGet(qemuCaps, QEMU_CAPS_PCI_MULTIBUS))
-            virBufferAsprintf(buf, ",bus=pci.0,addr=0x%x", info->addr.pci.slot);
+            virBufferAsprintf(buf, ",bus=pci.0");
+        else
+            virBufferAsprintf(buf, ",bus=pci");
+        if (qemuCapsGet(qemuCaps, QEMU_CAPS_PCI_MULTIFUNCTION))
+            virBufferAsprintf(buf, ",multifunction=on,addr=0x%x.0x%x",
+                              info->addr.pci.slot, info->addr.pci.function);
         else
-            virBufferAsprintf(buf, ",bus=pci,addr=0x%x", info->addr.pci.slot);
+            virBufferAsprintf(buf, ",addr=0x%x", info->addr.pci.slot);
     }
     return 0;
 }
-- 
1.7.1


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]