From 23a7b3445fb342b02326e9cb6ea5ee5f80e680c1 Mon Sep 17 00:00:00 2001 From: Xu Yandong Date: Wed, 25 Dec 2019 11:04:59 +0800 Subject: [PATCH] qemu: avoid double reservation of PCI address for interface type='hostdev' Commit 01ca4010d86 (libvirt v5.1.0) moved address reservation for hotplugged interface devices up to an earlier point in qemuDomainAttachNetDevice(), because that function calls qemuDomainSupportsNicdev() (in the case of VIR_DOMAIN_NET_TYPE_VHOSTUSER), and qemuDomainSupportsNicdev() needs to know the address type (for ARM machinetypes) and returns incorrect results when the address type is "none". This bugfix unfortunately caused a regression, because it also made PCI address reservation happen before we noticed that the device was a *hostdev* interface. Those interfaces are hotplugged by just calling out to qemuDomainAttachHostdevDevice() - that function would then also attempt to reserve the *same PCI address* that had just been reserved in qemuDomainAttachNetDevice(). The solution is to move the bit of code that short-circuits out to virDomainHostdevAttach() up *even earlier* so that no PCI address has been allocated by the time it's called. https://bugzilla.redhat.com/show_bug.cgi?id=1744523 Signed-off-by: Laine Stump Reviewed-by: Andrea Bolognani (cherry-picked from commit 47a7b8a96b6343d4af18ef80330f805ef031fe9b) Signed-off-by: Xu Yandong --- src/qemu/qemu_hotplug.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 08b6e8b..a26a3c2 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -1129,6 +1129,18 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver, if (qemuAssignDeviceNetAlias(vm->def, net, -1) < 0) goto cleanup; + if (actualType == VIR_DOMAIN_NET_TYPE_HOSTDEV) { + /* This is really a "smart hostdev", so it should be attached + * as a hostdev (the hostdev code will reach over into the + * netdev-specific code as appropriate), then also added to + * the nets list (see cleanup:) if successful. + */ + ret = qemuDomainAttachHostDevice(driver, vm, + virDomainNetGetActualHostdev(net)); + goto cleanup; + } + + if (qemuDomainIsS390CCW(vm->def) && net->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI && virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_CCW)) { @@ -1208,17 +1220,6 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver, goto cleanup; break; - case VIR_DOMAIN_NET_TYPE_HOSTDEV: - /* This is really a "smart hostdev", so it should be attached - * as a hostdev (the hostdev code will reach over into the - * netdev-specific code as appropriate), then also added to - * the nets list (see cleanup:) if successful. - */ - ret = qemuDomainAttachHostDevice(driver, vm, - virDomainNetGetActualHostdev(net)); - goto cleanup; - break; - case VIR_DOMAIN_NET_TYPE_VHOSTUSER: queueSize = net->driver.virtio.queues; if (!queueSize) @@ -1242,6 +1243,10 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver, /* No preparation needed. */ break; + case VIR_DOMAIN_NET_TYPE_HOSTDEV: + /* hostdev interfaces were handled earlier in this function */ + break; + case VIR_DOMAIN_NET_TYPE_SERVER: case VIR_DOMAIN_NET_TYPE_CLIENT: case VIR_DOMAIN_NET_TYPE_MCAST: -- 2.21.0