aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorJagannathan Raman <jag.raman@oracle.com>2022-06-13 16:26:21 -0400
committerStefan Hajnoczi <stefanha@redhat.com>2022-06-15 14:50:41 +0100
commit217c7f01adaf2853951d4725e3527ae70c45fbfc (patch)
tree6d98aab623149d74f19b1549cdb56d83e759b436 /hw
parente2848bc574fe2715c694bf8fe9a1ba7f78a1125a (diff)
downloadqemu-217c7f01adaf2853951d4725e3527ae70c45fbfc.zip
qemu-217c7f01adaf2853951d4725e3527ae70c45fbfc.tar.gz
qemu-217c7f01adaf2853951d4725e3527ae70c45fbfc.tar.bz2
qdev: unplug blocker for devices
Add blocker to prevent hot-unplug of devices TYPE_VFIO_USER_SERVER, which is introduced shortly, attaches itself to a PCIDevice on which it depends. If the attached PCIDevice gets removed while the server in use, it could cause it crash. To prevent this, TYPE_VFIO_USER_SERVER adds an unplug blocker for the PCIDevice. Signed-off-by: Elena Ufimtseva <elena.ufimtseva@oracle.com> Signed-off-by: John G Johnson <john.g.johnson@oracle.com> Signed-off-by: Jagannathan Raman <jag.raman@oracle.com> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Message-id: c41ef80b7cc063314d629737bed2159e5713f2e0.1655151679.git.jag.raman@oracle.com Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Diffstat (limited to 'hw')
-rw-r--r--hw/core/qdev.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 84f3019..0806d8f 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -468,6 +468,28 @@ char *qdev_get_dev_path(DeviceState *dev)
return NULL;
}
+void qdev_add_unplug_blocker(DeviceState *dev, Error *reason)
+{
+ dev->unplug_blockers = g_slist_prepend(dev->unplug_blockers, reason);
+}
+
+void qdev_del_unplug_blocker(DeviceState *dev, Error *reason)
+{
+ dev->unplug_blockers = g_slist_remove(dev->unplug_blockers, reason);
+}
+
+bool qdev_unplug_blocked(DeviceState *dev, Error **errp)
+{
+ ERRP_GUARD();
+
+ if (dev->unplug_blockers) {
+ error_propagate(errp, error_copy(dev->unplug_blockers->data));
+ return true;
+ }
+
+ return false;
+}
+
static bool device_get_realized(Object *obj, Error **errp)
{
DeviceState *dev = DEVICE(obj);
@@ -704,6 +726,8 @@ static void device_finalize(Object *obj)
DeviceState *dev = DEVICE(obj);
+ g_assert(!dev->unplug_blockers);
+
QLIST_FOREACH_SAFE(ngl, &dev->gpios, node, next) {
QLIST_REMOVE(ngl, node);
qemu_free_irqs(ngl->in, ngl->num_in);