aboutsummaryrefslogtreecommitdiff
path: root/hw/virtio
diff options
context:
space:
mode:
authorDavid Hildenbrand <david@redhat.com>2023-07-11 17:34:42 +0200
committerDavid Hildenbrand <david@redhat.com>2023-07-12 09:27:29 +0200
commitc29dd73f74fe6020ee0755d938885919a3719194 (patch)
tree202aedc8728013305b40e5249af76a30c58926de /hw/virtio
parent30ec5ccd3a2692464f832ec5a18b448d5ff86752 (diff)
virtio-md-pci: Handle unplug of virtio based memory devices
While we fence unplug requests from the outside, the VM can still trigger unplug of virtio based memory devices, for example, in Linux doing on a virtio-mem-pci device: # echo 0 > /sys/bus/pci/slots/3/power While doing that is not really expected to work without harming the guest OS (e.g., removing a virtio-mem device while it still provides memory), let's make sure that we properly handle it on the QEMU side. We'll add support for unplugging of virtio-mem devices in some configurations next. Message-ID: <20230711153445.514112-5-david@redhat.com> Tested-by: Mario Casquero <mcasquer@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: David Hildenbrand <david@redhat.com>
Diffstat (limited to 'hw/virtio')
-rw-r--r--hw/virtio/virtio-md-pci.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/hw/virtio/virtio-md-pci.c b/hw/virtio/virtio-md-pci.c
index e849c3131d..a22a259e2d 100644
--- a/hw/virtio/virtio-md-pci.c
+++ b/hw/virtio/virtio-md-pci.c
@@ -14,6 +14,7 @@
#include "hw/virtio/virtio-md-pci.h"
#include "hw/mem/memory-device.h"
#include "qapi/error.h"
+#include "qemu/error-report.h"
void virtio_md_pci_pre_plug(VirtIOMDPCI *vmd, MachineState *ms, Error **errp)
{
@@ -74,7 +75,27 @@ void virtio_md_pci_unplug_request(VirtIOMDPCI *vmd, MachineState *ms,
void virtio_md_pci_unplug(VirtIOMDPCI *vmd, MachineState *ms, Error **errp)
{
- /* We don't support hot unplug of virtio based memory devices */
+ DeviceState *dev = DEVICE(vmd);
+ HotplugHandler *bus_handler = qdev_get_bus_hotplug_handler(dev);
+ MemoryDeviceState *md = MEMORY_DEVICE(vmd);
+ Error *local_err = NULL;
+
+ /* Unplug the memory device while it is still realized. */
+ memory_device_unplug(md, ms);
+
+ if (bus_handler) {
+ hotplug_handler_unplug(bus_handler, dev, &local_err);
+ if (local_err) {
+ /* Not expected to fail ... but still try to recover. */
+ memory_device_plug(md, ms);
+ error_propagate(errp, local_err);
+ return;
+ }
+ } else {
+ /* Very unexpected, but let's just try to do the right thing. */
+ warn_report("Unexpected unplug of virtio based memory device");
+ qdev_unrealize(dev);
+ }
}
static const TypeInfo virtio_md_pci_info = {