From dbdf841b2ed8b88d30a8a1f0c26029b2ebb93e76 Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Tue, 11 Jul 2023 17:34:40 +0200 Subject: [PATCH] pc: Factor out (un)plug handling of virtio-md-pci devices Let's factor out (un)plug handling, to be reused from arm/virt code. Provide stubs for the case that CONFIG_VIRTIO_MD is not selected because neither virtio-mem nor virtio-pmem is enabled. While this cannot currently happen for x86, it will be possible for arm/virt. Message-ID: <20230711153445.514112-3-david@redhat.com> Tested-by: Mario Casquero Reviewed-by: Michael S. Tsirkin Signed-off-by: David Hildenbrand --- MAINTAINERS | 1 + hw/i386/pc.c | 90 ++++--------------------------- hw/virtio/virtio-md-pci.c | 63 ++++++++++++++++++++++ include/hw/virtio/virtio-md-pci.h | 6 +++ stubs/meson.build | 1 + stubs/virtio-md-pci.c | 24 +++++++++ 6 files changed, 106 insertions(+), 79 deletions(-) create mode 100644 stubs/virtio-md-pci.c diff --git a/MAINTAINERS b/MAINTAINERS index bb4626faf7..12e59b6b27 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2234,6 +2234,7 @@ M: David Hildenbrand S: Supported F: hw/virtio/virtio-md-pci.c F: include/hw/virtio/virtio-md-pci.h +F: stubs/virtio-md-pci.c virtio-mem M: David Hildenbrand diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 1bd1e5ead1..3109d5e0e0 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -88,13 +88,11 @@ #include "hw/net/ne2000-isa.h" #include "standard-headers/asm-x86/bootparam.h" #include "hw/virtio/virtio-iommu.h" -#include "hw/virtio/virtio-pmem-pci.h" -#include "hw/virtio/virtio-mem-pci.h" +#include "hw/virtio/virtio-md-pci.h" #include "hw/i386/kvm/xen_overlay.h" #include "hw/i386/kvm/xen_evtchn.h" #include "hw/i386/kvm/xen_gnttab.h" #include "hw/i386/kvm/xen_xenstore.h" -#include "hw/mem/memory-device.h" #include "sysemu/replay.h" #include "target/i386/cpu.h" #include "e820_memory_layout.h" @@ -1493,68 +1491,6 @@ static void pc_memory_unplug(HotplugHandler *hotplug_dev, error_propagate(errp, local_err); } -static void pc_virtio_md_pci_pre_plug(HotplugHandler *hotplug_dev, - DeviceState *dev, Error **errp) -{ - HotplugHandler *hotplug_dev2 = qdev_get_bus_hotplug_handler(dev); - Error *local_err = NULL; - - if (!hotplug_dev2 && dev->hotplugged) { - /* - * Without a bus hotplug handler, we cannot control the plug/unplug - * order. We should never reach this point when hotplugging on x86, - * however, better add a safety net. - */ - error_setg(errp, "hotplug of virtio based memory devices not supported" - " on this bus."); - return; - } - /* - * First, see if we can plug this memory device at all. If that - * succeeds, branch of to the actual hotplug handler. - */ - memory_device_pre_plug(MEMORY_DEVICE(dev), MACHINE(hotplug_dev), NULL, - &local_err); - if (!local_err && hotplug_dev2) { - hotplug_handler_pre_plug(hotplug_dev2, dev, &local_err); - } - error_propagate(errp, local_err); -} - -static void pc_virtio_md_pci_plug(HotplugHandler *hotplug_dev, - DeviceState *dev, Error **errp) -{ - HotplugHandler *hotplug_dev2 = qdev_get_bus_hotplug_handler(dev); - Error *local_err = NULL; - - /* - * Plug the memory device first and then branch off to the actual - * hotplug handler. If that one fails, we can easily undo the memory - * device bits. - */ - memory_device_plug(MEMORY_DEVICE(dev), MACHINE(hotplug_dev)); - if (hotplug_dev2) { - hotplug_handler_plug(hotplug_dev2, dev, &local_err); - if (local_err) { - memory_device_unplug(MEMORY_DEVICE(dev), MACHINE(hotplug_dev)); - } - } - error_propagate(errp, local_err); -} - -static void pc_virtio_md_pci_unplug_request(HotplugHandler *hotplug_dev, - DeviceState *dev, Error **errp) -{ - /* We don't support hot unplug of virtio based memory devices */ - error_setg(errp, "virtio based memory devices cannot be unplugged."); -} - -static void pc_virtio_md_pci_unplug(HotplugHandler *hotplug_dev, - DeviceState *dev, Error **errp) -{ - /* We don't support hot unplug of virtio based memory devices */ -} - static void pc_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { @@ -1562,9 +1498,8 @@ static void pc_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev, pc_memory_pre_plug(hotplug_dev, dev, errp); } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { x86_cpu_pre_plug(hotplug_dev, dev, errp); - } else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_PMEM_PCI) || - object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MEM_PCI)) { - pc_virtio_md_pci_pre_plug(hotplug_dev, dev, errp); + } else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MD_PCI)) { + virtio_md_pci_pre_plug(VIRTIO_MD_PCI(dev), MACHINE(hotplug_dev), errp); } else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI)) { /* Declare the APIC range as the reserved MSI region */ char *resv_prop_str = g_strdup_printf("0xfee00000:0xfeefffff:%d", @@ -1596,9 +1531,8 @@ static void pc_machine_device_plug_cb(HotplugHandler *hotplug_dev, pc_memory_plug(hotplug_dev, dev, errp); } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { x86_cpu_plug(hotplug_dev, dev, errp); - } else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_PMEM_PCI) || - object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MEM_PCI)) { - pc_virtio_md_pci_plug(hotplug_dev, dev, errp); + } else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MD_PCI)) { + virtio_md_pci_plug(VIRTIO_MD_PCI(dev), MACHINE(hotplug_dev), errp); } } @@ -1609,9 +1543,9 @@ static void pc_machine_device_unplug_request_cb(HotplugHandler *hotplug_dev, pc_memory_unplug_request(hotplug_dev, dev, errp); } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { x86_cpu_unplug_request_cb(hotplug_dev, dev, errp); - } else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_PMEM_PCI) || - object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MEM_PCI)) { - pc_virtio_md_pci_unplug_request(hotplug_dev, dev, errp); + } else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MD_PCI)) { + virtio_md_pci_unplug_request(VIRTIO_MD_PCI(dev), MACHINE(hotplug_dev), + errp); } else { error_setg(errp, "acpi: device unplug request for not supported device" " type: %s", object_get_typename(OBJECT(dev))); @@ -1625,9 +1559,8 @@ static void pc_machine_device_unplug_cb(HotplugHandler *hotplug_dev, pc_memory_unplug(hotplug_dev, dev, errp); } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { x86_cpu_unplug_cb(hotplug_dev, dev, errp); - } else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_PMEM_PCI) || - object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MEM_PCI)) { - pc_virtio_md_pci_unplug(hotplug_dev, dev, errp); + } else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MD_PCI)) { + virtio_md_pci_unplug(VIRTIO_MD_PCI(dev), MACHINE(hotplug_dev), errp); } else { error_setg(errp, "acpi: device unplug for not supported device" " type: %s", object_get_typename(OBJECT(dev))); @@ -1639,8 +1572,7 @@ static HotplugHandler *pc_get_hotplug_handler(MachineState *machine, { if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) || object_dynamic_cast(OBJECT(dev), TYPE_CPU) || - object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_PMEM_PCI) || - object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MEM_PCI) || + object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MD_PCI) || object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI) || object_dynamic_cast(OBJECT(dev), TYPE_X86_IOMMU_DEVICE)) { return HOTPLUG_HANDLER(machine); diff --git a/hw/virtio/virtio-md-pci.c b/hw/virtio/virtio-md-pci.c index 6b02ff908e..e849c3131d 100644 --- a/hw/virtio/virtio-md-pci.c +++ b/hw/virtio/virtio-md-pci.c @@ -13,6 +13,69 @@ #include "qemu/osdep.h" #include "hw/virtio/virtio-md-pci.h" #include "hw/mem/memory-device.h" +#include "qapi/error.h" + +void virtio_md_pci_pre_plug(VirtIOMDPCI *vmd, MachineState *ms, Error **errp) +{ + DeviceState *dev = DEVICE(vmd); + HotplugHandler *bus_handler = qdev_get_bus_hotplug_handler(dev); + MemoryDeviceState *md = MEMORY_DEVICE(vmd); + Error *local_err = NULL; + + if (!bus_handler && dev->hotplugged) { + /* + * Without a bus hotplug handler, we cannot control the plug/unplug + * order. We should never reach this point when hotplugging on x86, + * however, better add a safety net. + */ + error_setg(errp, "hotplug of virtio based memory devices not supported" + " on this bus."); + return; + } + /* + * First, see if we can plug this memory device at all. If that + * succeeds, branch of to the actual hotplug handler. + */ + memory_device_pre_plug(md, ms, NULL, &local_err); + if (!local_err && bus_handler) { + hotplug_handler_pre_plug(bus_handler, dev, &local_err); + } + error_propagate(errp, local_err); +} + +void virtio_md_pci_plug(VirtIOMDPCI *vmd, MachineState *ms, Error **errp) +{ + DeviceState *dev = DEVICE(vmd); + HotplugHandler *bus_handler = qdev_get_bus_hotplug_handler(dev); + MemoryDeviceState *md = MEMORY_DEVICE(vmd); + Error *local_err = NULL; + + /* + * Plug the memory device first and then branch off to the actual + * hotplug handler. If that one fails, we can easily undo the memory + * device bits. + */ + memory_device_plug(md, ms); + if (bus_handler) { + hotplug_handler_plug(bus_handler, dev, &local_err); + if (local_err) { + memory_device_unplug(md, ms); + } + } + error_propagate(errp, local_err); +} + +void virtio_md_pci_unplug_request(VirtIOMDPCI *vmd, MachineState *ms, + Error **errp) +{ + /* We don't support hot unplug of virtio based memory devices */ + error_setg(errp, "virtio based memory devices cannot be unplugged."); +} + +void virtio_md_pci_unplug(VirtIOMDPCI *vmd, MachineState *ms, Error **errp) +{ + /* We don't support hot unplug of virtio based memory devices */ +} static const TypeInfo virtio_md_pci_info = { .name = TYPE_VIRTIO_MD_PCI, diff --git a/include/hw/virtio/virtio-md-pci.h b/include/hw/virtio/virtio-md-pci.h index a241b54fcd..f9fa857aec 100644 --- a/include/hw/virtio/virtio-md-pci.h +++ b/include/hw/virtio/virtio-md-pci.h @@ -32,4 +32,10 @@ struct VirtIOMDPCI { VirtIOPCIProxy parent_obj; }; +void virtio_md_pci_pre_plug(VirtIOMDPCI *vmd, MachineState *ms, Error **errp); +void virtio_md_pci_plug(VirtIOMDPCI *vmd, MachineState *ms, Error **errp); +void virtio_md_pci_unplug_request(VirtIOMDPCI *vmd, MachineState *ms, + Error **errp); +void virtio_md_pci_unplug(VirtIOMDPCI *vmd, MachineState *ms, Error **errp); + #endif diff --git a/stubs/meson.build b/stubs/meson.build index a56645e2f7..ef6e39a64d 100644 --- a/stubs/meson.build +++ b/stubs/meson.build @@ -60,6 +60,7 @@ if have_system stub_ss.add(files('semihost.c')) stub_ss.add(files('usb-dev-stub.c')) stub_ss.add(files('xen-hw-stub.c')) + stub_ss.add(files('virtio-md-pci.c')) else stub_ss.add(files('qdev.c')) endif diff --git a/stubs/virtio-md-pci.c b/stubs/virtio-md-pci.c new file mode 100644 index 0000000000..ce5bba0c9d --- /dev/null +++ b/stubs/virtio-md-pci.c @@ -0,0 +1,24 @@ +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "hw/virtio/virtio-md-pci.h" + +void virtio_md_pci_pre_plug(VirtIOMDPCI *vmd, MachineState *ms, Error **errp) +{ + error_setg(errp, "virtio based memory devices not supported"); +} + +void virtio_md_pci_plug(VirtIOMDPCI *vmd, MachineState *ms, Error **errp) +{ + error_setg(errp, "virtio based memory devices not supported"); +} + +void virtio_md_pci_unplug_request(VirtIOMDPCI *vmd, MachineState *ms, + Error **errp) +{ + error_setg(errp, "virtio based memory devices not supported"); +} + +void virtio_md_pci_unplug(VirtIOMDPCI *vmd, MachineState *ms, Error **errp) +{ + error_setg(errp, "virtio based memory devices not supported"); +}