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