[libvirt] [PATCH v2 0/3] Introduce hot plug support for mediated devices

Libvirt shouldn't forbid the operation as unsupported. In fact, from VFIO point of view, mdevs have supported hot plug since the beginning. Then it's up to the 3rd party vendor driver whether it can cope with this feature reliably or not. Since v1 [1]: - dropped the original patch 1 as that adjustment can be done in a bigger scale across multiple modules as part of a 'bite-sized' task - reworded commit message for patches 2 and 3 - fixed the error path in patch 1 where I mistakenly tried to re-attach all host devices for a domain if the hotplug of an mdev failed [1] https://www.redhat.com/archives/libvir-list/2018-March/msg01631.html Erik Skultety (3): qemu: hotplug: Introduce hot plug support for mediated devices qemu: hotplug: Introduce hot unplug for mediated devices news: Update release news with mediated devices hot {plug,unplug} docs/news.xml | 10 ++++ src/qemu/qemu_hotplug.c | 133 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 143 insertions(+) -- 2.14.3

Mediated devices support hot-{plug,unplug} since their introduction in kernel 4.10, however libvirt has still been missing support for this. Signed-off-by: Erik Skultety <eskultet@redhat.com> --- src/qemu/qemu_hotplug.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 49af4d4ff..92e4d1cc9 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -2567,6 +2567,88 @@ qemuDomainAttachSCSIVHostDevice(virQEMUDriverPtr driver, } +static int +qemuDomainAttachMediatedDevice(virQEMUDriverPtr driver, + virDomainObjPtr vm, + virDomainHostdevDefPtr hostdev) +{ + int ret = -1; + char *devstr = NULL; + bool added = false; + bool teardowncgroup = false; + bool teardownlabel = false; + bool teardowndevice = false; + qemuDomainObjPrivatePtr priv = vm->privateData; + virDomainDeviceDef dev = { VIR_DOMAIN_DEVICE_HOSTDEV, + { .hostdev = hostdev } }; + + if (qemuDomainEnsurePCIAddress(vm, &dev, driver) < 0) + return -1; + + if (qemuHostdevPrepareMediatedDevices(driver, + vm->def->name, + &hostdev, + 1) < 0) + goto cleanup; + added = true; + + if (qemuDomainNamespaceSetupHostdev(vm, hostdev) < 0) + goto cleanup; + teardowndevice = true; + + if (qemuSetupHostdevCgroup(vm, hostdev) < 0) + goto cleanup; + teardowncgroup = true; + + if (qemuSecuritySetHostdevLabel(driver, vm, hostdev) < 0) + goto cleanup; + teardownlabel = true; + + if (qemuAssignDeviceHostdevAlias(vm->def, &hostdev->info->alias, -1) < 0) + goto cleanup; + + if (!(devstr = qemuBuildHostdevMediatedDevStr(vm->def, hostdev, + priv->qemuCaps))) + goto cleanup; + + if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs + 1) < 0) + goto cleanup; + + qemuDomainObjEnterMonitor(driver, vm); + ret = qemuMonitorAddDevice(priv->mon, devstr); + if (qemuDomainObjExitMonitor(driver, vm) < 0) { + ret = -1; + goto cleanup; + } + + virDomainAuditHostdev(vm, hostdev, "attach", ret == 0); + if (ret < 0) + goto cleanup; + + VIR_APPEND_ELEMENT_INPLACE(vm->def->hostdevs, vm->def->nhostdevs, hostdev); + ret = 0; + cleanup: + if (ret < 0) { + if (teardowncgroup && qemuTeardownHostdevCgroup(vm, hostdev) < 0) + VIR_WARN("Unable to remove host device cgroup ACL on hotplug fail"); + if (teardownlabel && + qemuSecurityRestoreHostdevLabel(driver, vm, hostdev) < 0) + VIR_WARN("Unable to restore host device labelling on hotplug fail"); + if (teardowndevice && + qemuDomainNamespaceTeardownHostdev(vm, hostdev) < 0) + VIR_WARN("Unable to remove host device from /dev"); + if (added) + qemuHostdevReAttachMediatedDevices(driver, + vm->def->name, + &hostdev, + 1); + qemuDomainReleaseDeviceAddress(vm, hostdev->info, NULL); + } + VIR_FREE(devstr); + return ret; +} + + int qemuDomainAttachHostDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, @@ -2602,6 +2684,10 @@ qemuDomainAttachHostDevice(virQEMUDriverPtr driver, if (qemuDomainAttachSCSIVHostDevice(driver, vm, hostdev) < 0) goto error; break; + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV: + if (qemuDomainAttachMediatedDevice(driver, vm, hostdev) < 0) + goto error; + break; default: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, -- 2.14.3

Mediated devices support hot-{plug,unplug} since their introduction in kernel 4.10, however libvirt has still been missing support for this. Signed-off-by: Erik Skultety <eskultet@redhat.com> --- src/qemu/qemu_hotplug.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 92e4d1cc9..ea94f7d2b 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -4030,6 +4030,17 @@ qemuDomainRemoveSCSIVHostDevice(virQEMUDriverPtr driver, qemuHostdevReAttachSCSIVHostDevices(driver, vm->def->name, &hostdev, 1); } + +static void +qemuDomainRemoveMediatedDevice(virQEMUDriverPtr driver, + virDomainObjPtr vm, + virDomainHostdevDefPtr hostdev) +{ + qemuHostdevReAttachMediatedDevices(driver, vm->def->name, &hostdev, 1); + qemuDomainReleaseDeviceAddress(vm, hostdev->info, NULL); +} + + static int qemuDomainRemoveHostDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, @@ -4132,6 +4143,7 @@ qemuDomainRemoveHostDevice(virQEMUDriverPtr driver, qemuDomainRemoveSCSIVHostDevice(driver, vm, hostdev); break; case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV: + qemuDomainRemoveMediatedDevice(driver, vm, hostdev); break; case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST: break; @@ -5059,6 +5071,32 @@ qemuDomainDetachSCSIVHostDevice(virQEMUDriverPtr driver, return ret; } + +static int +qemuDomainDetachMediatedDevice(virQEMUDriverPtr driver, + virDomainObjPtr vm, + virDomainHostdevDefPtr detach) +{ + int ret = -1; + qemuDomainObjPrivatePtr priv = vm->privateData; + + if (!detach->info->alias) { + virReportError(VIR_ERR_OPERATION_FAILED, "%s", + _("device cannot be detached without a device alias")); + return -1; + } + + qemuDomainMarkDeviceForRemoval(vm, detach->info); + + qemuDomainObjEnterMonitor(driver, vm); + ret = qemuMonitorDelDevice(priv->mon, detach->info->alias); + if (qemuDomainObjExitMonitor(driver, vm) < 0) + ret = -1; + + return ret; +} + + static int qemuDomainDetachThisHostDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, @@ -5082,6 +5120,9 @@ qemuDomainDetachThisHostDevice(virQEMUDriverPtr driver, case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST: ret = qemuDomainDetachSCSIVHostDevice(driver, vm, detach); break; + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV: + ret = qemuDomainDetachMediatedDevice(driver, vm, detach); + break; default: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("hot unplug is not supported for hostdev subsys type '%s'"), @@ -5111,6 +5152,7 @@ int qemuDomainDetachHostDevice(virQEMUDriverPtr driver, virDomainHostdevSubsysUSBPtr usbsrc = &subsys->u.usb; virDomainHostdevSubsysPCIPtr pcisrc = &subsys->u.pci; virDomainHostdevSubsysSCSIPtr scsisrc = &subsys->u.scsi; + virDomainHostdevSubsysMediatedDevPtr mdevsrc = &subsys->u.mdev; virDomainHostdevDefPtr detach = NULL; int idx; @@ -5159,6 +5201,11 @@ int qemuDomainDetachHostDevice(virQEMUDriverPtr driver, } break; } + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV: + virReportError(VIR_ERR_DEVICE_MISSING, + _("mediated device '%s' not found"), + mdevsrc->uuidstr); + break; case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST: break; default: -- 2.14.3

Signed-off-by: Erik Skultety <eskultet@redhat.com> --- docs/news.xml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/news.xml b/docs/news.xml index 108889574..5f41208c2 100644 --- a/docs/news.xml +++ b/docs/news.xml @@ -92,6 +92,16 @@ previously started domains to 256, or restart them. </description> </change> + <change> + <summary> + qemu: Support hot plug and hot unplug of mediated devices + </summary> + <description> + Libvirt now allows mediated devices to be hot plugged and hot + unplugged from a guest rather than reporting an error that this isn't + supported. In fact, kernel has been supporting this since 4.10. + </description> + </change> </section> <section title="Bug fixes"> </section> -- 2.14.3

On Wed, Mar 28, 2018 at 15:02:33 +0200, Erik Skultety wrote:
Libvirt shouldn't forbid the operation as unsupported. In fact, from VFIO point of view, mdevs have supported hot plug since the beginning. Then it's up to the 3rd party vendor driver whether it can cope with this feature reliably or not.
Since v1 [1]: - dropped the original patch 1 as that adjustment can be done in a bigger scale across multiple modules as part of a 'bite-sized' task - reworded commit message for patches 2 and 3 - fixed the error path in patch 1 where I mistakenly tried to re-attach all host devices for a domain if the hotplug of an mdev failed
ACK series

On Wed, Mar 28, 2018 at 03:13:02PM +0200, Peter Krempa wrote:
On Wed, Mar 28, 2018 at 15:02:33 +0200, Erik Skultety wrote:
Libvirt shouldn't forbid the operation as unsupported. In fact, from VFIO point of view, mdevs have supported hot plug since the beginning. Then it's up to the 3rd party vendor driver whether it can cope with this feature reliably or not.
Since v1 [1]: - dropped the original patch 1 as that adjustment can be done in a bigger scale across multiple modules as part of a 'bite-sized' task - reworded commit message for patches 2 and 3 - fixed the error path in patch 1 where I mistakenly tried to re-attach all host devices for a domain if the hotplug of an mdev failed
ACK series
Thanks, I'll merge this once 4.2 is out. Erik
participants (2)
-
Erik Skultety
-
Peter Krempa