* [PATCH v2 0/7] virtio-mem: Device unplug support
@ 2023-06-23 12:20 David Hildenbrand
2023-06-23 12:20 ` [PATCH v2 1/7] virtio-md-pci: New parent type for virtio-mem-pci and virtio-pmem-pci David Hildenbrand
` (6 more replies)
0 siblings, 7 replies; 8+ messages in thread
From: David Hildenbrand @ 2023-06-23 12:20 UTC (permalink / raw)
To: qemu-devel
Cc: David Hildenbrand, Peter Maydell, Paolo Bonzini,
Richard Henderson, Eduardo Habkost, Michael S. Tsirkin,
Marcel Apfelbaum, Igor Mammedov, qemu-arm, Gavin Shan
One limitation of virtio-mem is that we cannot currently unplug virtio-mem
devices that have all memory unplugged from the VM.
Let's properly handle forced unplug (as can be triggered by the VM) and
add support for ordinary unplug (requests) of virtio-mem devices that are
in a compatible state (no legacy mode, no plugged memory, no plug request).
Briefly tested on both, x86_64 and aarch64.
v1 -> v2:
- Reduce code duplication and implement it in a cleaner way using a
new abstract virtio-md-pci parent class
- "virtio-md-pci: New parent type for virtio-mem-pci and virtio-pmem-pci"
-> Added, use a new aprent type like virtio-input-pci
- "pc: Factor out (un)plug handling of virtio-md-pci devices"
-> Added, factor it cleanly out
- "arm/virt: Use virtio-md-pci (un)plug functions"
-> Added, reduce code duplciation
- "virtio-md-pci: Handle unplug of virtio based memory devices"
-> More generic without any device-specifics
- "virtio-md-pci: Support unplug requests for compatible devices"
-> More generic without any device-specifics
- "virtio-mem: Prepare for device unplug support"
-> Use callback, separated from virtio-mem-pci device change
- "virtio-mem-pci: Device unplug support"
-> Use callback, separated from virtio-mem device change
Cc: Peter Maydell <peter.maydell@linaro.org>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Richard Henderson <richard.henderson@linaro.org>
Cc: Eduardo Habkost <eduardo@habkost.net>
Cc: "Michael S. Tsirkin" <mst@redhat.com>
Cc: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
Cc: Igor Mammedov <imammedo@redhat.com>
Cc: qemu-arm@nongnu.org
Cc: Gavin Shan <gshan@redhat.com>
David Hildenbrand (7):
virtio-md-pci: New parent type for virtio-mem-pci and virtio-pmem-pci
pc: Factor out (un)plug handling of virtio-md-pci devices
arm/virt: Use virtio-md-pci (un)plug functions
virtio-md-pci: Handle unplug of virtio based memory devices
virtio-md-pci: Support unplug requests for compatible devices
virtio-mem: Prepare for device unplug support
virtio-mem-pci: Device unplug support
hw/arm/virt.c | 81 +++-------------
hw/i386/pc.c | 90 +++---------------
hw/virtio/Kconfig | 8 +-
hw/virtio/meson.build | 1 +
hw/virtio/virtio-md-pci.c | 151 ++++++++++++++++++++++++++++++
hw/virtio/virtio-mem-pci.c | 54 +++++++++--
hw/virtio/virtio-mem-pci.h | 6 +-
hw/virtio/virtio-mem.c | 25 +++++
hw/virtio/virtio-pmem-pci.c | 5 +-
hw/virtio/virtio-pmem-pci.h | 6 +-
include/hw/virtio/virtio-md-pci.h | 44 +++++++++
include/hw/virtio/virtio-mem.h | 1 +
12 files changed, 305 insertions(+), 167 deletions(-)
create mode 100644 hw/virtio/virtio-md-pci.c
create mode 100644 include/hw/virtio/virtio-md-pci.h
--
2.40.1
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2 1/7] virtio-md-pci: New parent type for virtio-mem-pci and virtio-pmem-pci
2023-06-23 12:20 [PATCH v2 0/7] virtio-mem: Device unplug support David Hildenbrand
@ 2023-06-23 12:20 ` David Hildenbrand
2023-06-23 12:20 ` [PATCH v2 2/7] pc: Factor out (un)plug handling of virtio-md-pci devices David Hildenbrand
` (5 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: David Hildenbrand @ 2023-06-23 12:20 UTC (permalink / raw)
To: qemu-devel
Cc: David Hildenbrand, Peter Maydell, Paolo Bonzini,
Richard Henderson, Eduardo Habkost, Michael S. Tsirkin,
Marcel Apfelbaum, Igor Mammedov, qemu-arm, Gavin Shan
Let's add a new abstract "virtio memory device" type, and use it as
parent class of virtio-mem-pci and virtio-pmem-pci.
Signed-off-by: David Hildenbrand <david@redhat.com>
---
hw/virtio/Kconfig | 8 +++++--
hw/virtio/meson.build | 1 +
hw/virtio/virtio-md-pci.c | 33 +++++++++++++++++++++++++++++
hw/virtio/virtio-mem-pci.c | 5 +----
hw/virtio/virtio-mem-pci.h | 6 +++---
hw/virtio/virtio-pmem-pci.c | 5 +----
hw/virtio/virtio-pmem-pci.h | 6 +++---
include/hw/virtio/virtio-md-pci.h | 35 +++++++++++++++++++++++++++++++
8 files changed, 83 insertions(+), 16 deletions(-)
create mode 100644 hw/virtio/virtio-md-pci.c
create mode 100644 include/hw/virtio/virtio-md-pci.h
diff --git a/hw/virtio/Kconfig b/hw/virtio/Kconfig
index 89e9e426d8..1a42d2edf0 100644
--- a/hw/virtio/Kconfig
+++ b/hw/virtio/Kconfig
@@ -35,6 +35,10 @@ config VIRTIO_CRYPTO
default y
depends on VIRTIO
+config VIRTIO_MD
+ bool
+ select MEM_DEVICE
+
config VIRTIO_PMEM_SUPPORTED
bool
@@ -43,7 +47,7 @@ config VIRTIO_PMEM
default y
depends on VIRTIO
depends on VIRTIO_PMEM_SUPPORTED
- select MEM_DEVICE
+ select VIRTIO_MD
config VIRTIO_MEM_SUPPORTED
bool
@@ -54,7 +58,7 @@ config VIRTIO_MEM
depends on VIRTIO
depends on LINUX
depends on VIRTIO_MEM_SUPPORTED
- select MEM_DEVICE
+ select VIRTIO_MD
config VHOST_VSOCK
bool
diff --git a/hw/virtio/meson.build b/hw/virtio/meson.build
index e83c37fffd..7b50bb282f 100644
--- a/hw/virtio/meson.build
+++ b/hw/virtio/meson.build
@@ -59,6 +59,7 @@ virtio_pci_ss.add(when: 'CONFIG_VIRTIO_PMEM', if_true: files('virtio-pmem-pci.c'
virtio_pci_ss.add(when: 'CONFIG_VIRTIO_IOMMU', if_true: files('virtio-iommu-pci.c'))
virtio_pci_ss.add(when: 'CONFIG_VIRTIO_MEM', if_true: files('virtio-mem-pci.c'))
virtio_pci_ss.add(when: 'CONFIG_VHOST_VDPA_DEV', if_true: files('vdpa-dev-pci.c'))
+virtio_pci_ss.add(when: 'CONFIG_VIRTIO_MD', if_true: files('virtio-md-pci.c'))
specific_virtio_ss.add_all(when: 'CONFIG_VIRTIO_PCI', if_true: virtio_pci_ss)
diff --git a/hw/virtio/virtio-md-pci.c b/hw/virtio/virtio-md-pci.c
new file mode 100644
index 0000000000..6b02ff908e
--- /dev/null
+++ b/hw/virtio/virtio-md-pci.c
@@ -0,0 +1,33 @@
+/*
+ * Abstract virtio based memory device
+ *
+ * Copyright (C) 2023 Red Hat, Inc.
+ *
+ * Authors:
+ * David Hildenbrand <david@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/virtio/virtio-md-pci.h"
+#include "hw/mem/memory-device.h"
+
+static const TypeInfo virtio_md_pci_info = {
+ .name = TYPE_VIRTIO_MD_PCI,
+ .parent = TYPE_VIRTIO_PCI,
+ .instance_size = sizeof(VirtIOMDPCI),
+ .class_size = sizeof(VirtIOMDPCIClass),
+ .abstract = true,
+ .interfaces = (InterfaceInfo[]) {
+ { TYPE_MEMORY_DEVICE },
+ { }
+ },
+};
+
+static void virtio_md_pci_register(void)
+{
+ type_register_static(&virtio_md_pci_info);
+}
+type_init(virtio_md_pci_register)
diff --git a/hw/virtio/virtio-mem-pci.c b/hw/virtio/virtio-mem-pci.c
index b85c12668d..2ef0f07630 100644
--- a/hw/virtio/virtio-mem-pci.c
+++ b/hw/virtio/virtio-mem-pci.c
@@ -142,14 +142,11 @@ static void virtio_mem_pci_instance_init(Object *obj)
static const VirtioPCIDeviceTypeInfo virtio_mem_pci_info = {
.base_name = TYPE_VIRTIO_MEM_PCI,
+ .parent = TYPE_VIRTIO_MD_PCI,
.generic_name = "virtio-mem-pci",
.instance_size = sizeof(VirtIOMEMPCI),
.instance_init = virtio_mem_pci_instance_init,
.class_init = virtio_mem_pci_class_init,
- .interfaces = (InterfaceInfo[]) {
- { TYPE_MEMORY_DEVICE },
- { }
- },
};
static void virtio_mem_pci_register_types(void)
diff --git a/hw/virtio/virtio-mem-pci.h b/hw/virtio/virtio-mem-pci.h
index e636e1a48d..c50b51d608 100644
--- a/hw/virtio/virtio-mem-pci.h
+++ b/hw/virtio/virtio-mem-pci.h
@@ -13,21 +13,21 @@
#ifndef QEMU_VIRTIO_MEM_PCI_H
#define QEMU_VIRTIO_MEM_PCI_H
-#include "hw/virtio/virtio-pci.h"
+#include "hw/virtio/virtio-md-pci.h"
#include "hw/virtio/virtio-mem.h"
#include "qom/object.h"
typedef struct VirtIOMEMPCI VirtIOMEMPCI;
/*
- * virtio-mem-pci: This extends VirtioPCIProxy.
+ * virtio-mem-pci: This extends VirtIOMDPCI.
*/
#define TYPE_VIRTIO_MEM_PCI "virtio-mem-pci-base"
DECLARE_INSTANCE_CHECKER(VirtIOMEMPCI, VIRTIO_MEM_PCI,
TYPE_VIRTIO_MEM_PCI)
struct VirtIOMEMPCI {
- VirtIOPCIProxy parent_obj;
+ VirtIOMDPCI parent_obj;
VirtIOMEM vdev;
Notifier size_change_notifier;
};
diff --git a/hw/virtio/virtio-pmem-pci.c b/hw/virtio/virtio-pmem-pci.c
index 197d219204..cfe7f3b67c 100644
--- a/hw/virtio/virtio-pmem-pci.c
+++ b/hw/virtio/virtio-pmem-pci.c
@@ -110,13 +110,10 @@ static void virtio_pmem_pci_instance_init(Object *obj)
static const VirtioPCIDeviceTypeInfo virtio_pmem_pci_info = {
.base_name = TYPE_VIRTIO_PMEM_PCI,
.generic_name = "virtio-pmem-pci",
+ .parent = TYPE_VIRTIO_MD_PCI,
.instance_size = sizeof(VirtIOPMEMPCI),
.instance_init = virtio_pmem_pci_instance_init,
.class_init = virtio_pmem_pci_class_init,
- .interfaces = (InterfaceInfo[]) {
- { TYPE_MEMORY_DEVICE },
- { }
- },
};
static void virtio_pmem_pci_register_types(void)
diff --git a/hw/virtio/virtio-pmem-pci.h b/hw/virtio/virtio-pmem-pci.h
index 63cfe727f7..88b01ce2db 100644
--- a/hw/virtio/virtio-pmem-pci.h
+++ b/hw/virtio/virtio-pmem-pci.h
@@ -14,21 +14,21 @@
#ifndef QEMU_VIRTIO_PMEM_PCI_H
#define QEMU_VIRTIO_PMEM_PCI_H
-#include "hw/virtio/virtio-pci.h"
+#include "hw/virtio/virtio-md-pci.h"
#include "hw/virtio/virtio-pmem.h"
#include "qom/object.h"
typedef struct VirtIOPMEMPCI VirtIOPMEMPCI;
/*
- * virtio-pmem-pci: This extends VirtioPCIProxy.
+ * virtio-pmem-pci: This extends VirtIOMDPCI.
*/
#define TYPE_VIRTIO_PMEM_PCI "virtio-pmem-pci-base"
DECLARE_INSTANCE_CHECKER(VirtIOPMEMPCI, VIRTIO_PMEM_PCI,
TYPE_VIRTIO_PMEM_PCI)
struct VirtIOPMEMPCI {
- VirtIOPCIProxy parent_obj;
+ VirtIOMDPCI parent_obj;
VirtIOPMEM vdev;
};
diff --git a/include/hw/virtio/virtio-md-pci.h b/include/hw/virtio/virtio-md-pci.h
new file mode 100644
index 0000000000..a241b54fcd
--- /dev/null
+++ b/include/hw/virtio/virtio-md-pci.h
@@ -0,0 +1,35 @@
+/*
+ * Abstract virtio based memory device
+ *
+ * Copyright (C) 2023 Red Hat, Inc.
+ *
+ * Authors:
+ * David Hildenbrand <david@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef HW_VIRTIO_MD_PCI_H
+#define HW_VIRTIO_MD_PCI_H
+
+#include "hw/virtio/virtio-pci.h"
+#include "qom/object.h"
+
+/*
+ * virtio-md-pci: This extends VirtioPCIProxy.
+ */
+#define TYPE_VIRTIO_MD_PCI "virtio-md-pci"
+
+OBJECT_DECLARE_TYPE(VirtIOMDPCI, VirtIOMDPCIClass, VIRTIO_MD_PCI)
+
+struct VirtIOMDPCIClass {
+ /* private */
+ VirtioPCIClass parent;
+};
+
+struct VirtIOMDPCI {
+ VirtIOPCIProxy parent_obj;
+};
+
+#endif
--
2.40.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v2 2/7] pc: Factor out (un)plug handling of virtio-md-pci devices
2023-06-23 12:20 [PATCH v2 0/7] virtio-mem: Device unplug support David Hildenbrand
2023-06-23 12:20 ` [PATCH v2 1/7] virtio-md-pci: New parent type for virtio-mem-pci and virtio-pmem-pci David Hildenbrand
@ 2023-06-23 12:20 ` David Hildenbrand
2023-06-23 12:20 ` [PATCH v2 3/7] arm/virt: Use virtio-md-pci (un)plug functions David Hildenbrand
` (4 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: David Hildenbrand @ 2023-06-23 12:20 UTC (permalink / raw)
To: qemu-devel
Cc: David Hildenbrand, Peter Maydell, Paolo Bonzini,
Richard Henderson, Eduardo Habkost, Michael S. Tsirkin,
Marcel Apfelbaum, Igor Mammedov, qemu-arm, Gavin Shan
Let's factor out (un)plug handling, to be reused from arm/virt code.
Signed-off-by: David Hildenbrand <david@redhat.com>
---
hw/i386/pc.c | 90 ++++---------------------------
hw/virtio/virtio-md-pci.c | 63 ++++++++++++++++++++++
include/hw/virtio/virtio-md-pci.h | 6 +++
3 files changed, 80 insertions(+), 79 deletions(-)
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index fc52772fdd..462b33bc2c 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"
@@ -1500,68 +1498,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)
{
@@ -1569,9 +1505,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",
@@ -1603,9 +1538,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);
}
}
@@ -1616,9 +1550,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)));
@@ -1632,9 +1566,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)));
@@ -1646,8 +1579,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
--
2.40.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v2 3/7] arm/virt: Use virtio-md-pci (un)plug functions
2023-06-23 12:20 [PATCH v2 0/7] virtio-mem: Device unplug support David Hildenbrand
2023-06-23 12:20 ` [PATCH v2 1/7] virtio-md-pci: New parent type for virtio-mem-pci and virtio-pmem-pci David Hildenbrand
2023-06-23 12:20 ` [PATCH v2 2/7] pc: Factor out (un)plug handling of virtio-md-pci devices David Hildenbrand
@ 2023-06-23 12:20 ` David Hildenbrand
2023-06-23 12:20 ` [PATCH v2 4/7] virtio-md-pci: Handle unplug of virtio based memory devices David Hildenbrand
` (3 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: David Hildenbrand @ 2023-06-23 12:20 UTC (permalink / raw)
To: qemu-devel
Cc: David Hildenbrand, Peter Maydell, Paolo Bonzini,
Richard Henderson, Eduardo Habkost, Michael S. Tsirkin,
Marcel Apfelbaum, Igor Mammedov, qemu-arm, Gavin Shan
Let's use our new helper functions. Note that virtio-pmem-pci is not
enabled for arm and, therefore, not compiled in.
Signed-off-by: David Hildenbrand <david@redhat.com>
---
hw/arm/virt.c | 81 ++++++++-------------------------------------------
1 file changed, 12 insertions(+), 69 deletions(-)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 9b9f7d9c68..4ab8468e0b 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -72,11 +72,10 @@
#include "hw/arm/smmuv3.h"
#include "hw/acpi/acpi.h"
#include "target/arm/internals.h"
-#include "hw/mem/memory-device.h"
#include "hw/mem/pc-dimm.h"
#include "hw/mem/nvdimm.h"
#include "hw/acpi/generic_event_device.h"
-#include "hw/virtio/virtio-mem-pci.h"
+#include "hw/virtio/virtio-md-pci.h"
#include "hw/virtio/virtio-iommu.h"
#include "hw/char/pl011.h"
#include "qemu/guest-random.h"
@@ -2744,64 +2743,6 @@ static void virt_memory_plug(HotplugHandler *hotplug_dev,
dev, &error_abort);
}
-static void virt_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 ARM.
- * However, it's nice to add a safety net, similar to what we have
- * on x86.
- */
- 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 virt_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 virt_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 virt_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp)
{
@@ -2809,8 +2750,8 @@ static void virt_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
virt_memory_pre_plug(hotplug_dev, dev, errp);
- } else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MEM_PCI)) {
- virt_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)) {
hwaddr db_start = 0, db_end = 0;
char *resv_prop_str;
@@ -2859,12 +2800,11 @@ static void virt_machine_device_plug_cb(HotplugHandler *hotplug_dev,
SYS_BUS_DEVICE(dev));
}
}
+
if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
virt_memory_plug(hotplug_dev, dev, errp);
- }
-
- if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MEM_PCI)) {
- virt_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);
}
if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI)) {
@@ -2919,8 +2859,9 @@ static void virt_machine_device_unplug_request_cb(HotplugHandler *hotplug_dev,
{
if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
virt_dimm_unplug_request(hotplug_dev, dev, errp);
- } else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MEM_PCI)) {
- virt_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, "device unplug request for unsupported device"
" type: %s", object_get_typename(OBJECT(dev)));
@@ -2932,6 +2873,8 @@ static void virt_machine_device_unplug_cb(HotplugHandler *hotplug_dev,
{
if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
virt_dimm_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, "virt: device unplug for unsupported device"
" type: %s", object_get_typename(OBJECT(dev)));
@@ -2945,7 +2888,7 @@ static HotplugHandler *virt_machine_get_hotplug_handler(MachineState *machine,
if (device_is_dynamic_sysbus(mc, dev) ||
object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) ||
- 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)) {
return HOTPLUG_HANDLER(machine);
}
--
2.40.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v2 4/7] virtio-md-pci: Handle unplug of virtio based memory devices
2023-06-23 12:20 [PATCH v2 0/7] virtio-mem: Device unplug support David Hildenbrand
` (2 preceding siblings ...)
2023-06-23 12:20 ` [PATCH v2 3/7] arm/virt: Use virtio-md-pci (un)plug functions David Hildenbrand
@ 2023-06-23 12:20 ` David Hildenbrand
2023-06-23 12:20 ` [PATCH v2 5/7] virtio-md-pci: Support unplug requests for compatible devices David Hildenbrand
` (2 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: David Hildenbrand @ 2023-06-23 12:20 UTC (permalink / raw)
To: qemu-devel
Cc: David Hildenbrand, Peter Maydell, Paolo Bonzini,
Richard Henderson, Eduardo Habkost, Michael S. Tsirkin,
Marcel Apfelbaum, Igor Mammedov, qemu-arm, Gavin Shan
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.
Signed-off-by: David Hildenbrand <david@redhat.com>
---
hw/virtio/virtio-md-pci.c | 23 ++++++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)
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 = {
--
2.40.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v2 5/7] virtio-md-pci: Support unplug requests for compatible devices
2023-06-23 12:20 [PATCH v2 0/7] virtio-mem: Device unplug support David Hildenbrand
` (3 preceding siblings ...)
2023-06-23 12:20 ` [PATCH v2 4/7] virtio-md-pci: Handle unplug of virtio based memory devices David Hildenbrand
@ 2023-06-23 12:20 ` David Hildenbrand
2023-06-23 12:20 ` [PATCH v2 6/7] virtio-mem: Prepare for device unplug support David Hildenbrand
2023-06-23 12:20 ` [PATCH v2 7/7] virtio-mem-pci: Device " David Hildenbrand
6 siblings, 0 replies; 8+ messages in thread
From: David Hildenbrand @ 2023-06-23 12:20 UTC (permalink / raw)
To: qemu-devel
Cc: David Hildenbrand, Peter Maydell, Paolo Bonzini,
Richard Henderson, Eduardo Habkost, Michael S. Tsirkin,
Marcel Apfelbaum, Igor Mammedov, qemu-arm, Gavin Shan
Let's support unplug requests for virtio-md-pci devices that provide
a unplug_request_check() callback.
We'll wire that up for virtio-mem-pci next.
Signed-off-by: David Hildenbrand <david@redhat.com>
---
hw/virtio/virtio-md-pci.c | 38 +++++++++++++++++++++++++++++--
include/hw/virtio/virtio-md-pci.h | 3 +++
2 files changed, 39 insertions(+), 2 deletions(-)
diff --git a/hw/virtio/virtio-md-pci.c b/hw/virtio/virtio-md-pci.c
index a22a259e2d..62bfb7920b 100644
--- a/hw/virtio/virtio-md-pci.c
+++ b/hw/virtio/virtio-md-pci.c
@@ -69,8 +69,42 @@ void virtio_md_pci_plug(VirtIOMDPCI *vmd, MachineState *ms, Error **errp)
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.");
+ VirtIOMDPCIClass *vmdc = VIRTIO_MD_PCI_GET_CLASS(vmd);
+ DeviceState *dev = DEVICE(vmd);
+ HotplugHandler *bus_handler = qdev_get_bus_hotplug_handler(dev);
+ HotplugHandlerClass *hdc;
+ Error *local_err = NULL;
+
+ if (!vmdc->unplug_request_check) {
+ error_setg(errp, "this virtio based memory devices cannot be unplugged");
+ return;
+ }
+
+ if (!bus_handler) {
+ error_setg(errp, "hotunplug of virtio based memory devices not"
+ "supported on this bus");
+ return;
+ }
+
+ vmdc->unplug_request_check(vmd, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+
+ /*
+ * Forward the async request or turn it into a sync request (handling it
+ * like qdev_unplug()).
+ */
+ hdc = HOTPLUG_HANDLER_GET_CLASS(bus_handler);
+ if (hdc->unplug_request) {
+ hotplug_handler_unplug_request(bus_handler, dev, &local_err);
+ } else {
+ virtio_md_pci_unplug(vmd, ms, &local_err);
+ if (!local_err) {
+ object_unparent(OBJECT(dev));
+ }
+ }
}
void virtio_md_pci_unplug(VirtIOMDPCI *vmd, MachineState *ms, Error **errp)
diff --git a/include/hw/virtio/virtio-md-pci.h b/include/hw/virtio/virtio-md-pci.h
index f9fa857aec..5912e16674 100644
--- a/include/hw/virtio/virtio-md-pci.h
+++ b/include/hw/virtio/virtio-md-pci.h
@@ -26,6 +26,9 @@ OBJECT_DECLARE_TYPE(VirtIOMDPCI, VirtIOMDPCIClass, VIRTIO_MD_PCI)
struct VirtIOMDPCIClass {
/* private */
VirtioPCIClass parent;
+
+ /* public */
+ void (*unplug_request_check)(VirtIOMDPCI *vmd, Error **errp);
};
struct VirtIOMDPCI {
--
2.40.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v2 6/7] virtio-mem: Prepare for device unplug support
2023-06-23 12:20 [PATCH v2 0/7] virtio-mem: Device unplug support David Hildenbrand
` (4 preceding siblings ...)
2023-06-23 12:20 ` [PATCH v2 5/7] virtio-md-pci: Support unplug requests for compatible devices David Hildenbrand
@ 2023-06-23 12:20 ` David Hildenbrand
2023-06-23 12:20 ` [PATCH v2 7/7] virtio-mem-pci: Device " David Hildenbrand
6 siblings, 0 replies; 8+ messages in thread
From: David Hildenbrand @ 2023-06-23 12:20 UTC (permalink / raw)
To: qemu-devel
Cc: David Hildenbrand, Peter Maydell, Paolo Bonzini,
Richard Henderson, Eduardo Habkost, Michael S. Tsirkin,
Marcel Apfelbaum, Igor Mammedov, qemu-arm, Gavin Shan
In many cases, blindly unplugging a virtio-mem device is problematic. We
can only safely remove a device once:
* The guest is not expecting to be able to read unplugged memory
(unplugged-inaccessible == on)
* The virtio-mem device does not have memory plugged (size == 0)
* The virtio-mem device does not have outstanding requests to the VM to
plug memory (requested-size == 0)
So let's add a callback to the virtio-mem device class to check for that.
We'll wire-up virtio-mem-pci next.
Signed-off-by: David Hildenbrand <david@redhat.com>
---
hw/virtio/virtio-mem.c | 25 +++++++++++++++++++++++++
include/hw/virtio/virtio-mem.h | 1 +
2 files changed, 26 insertions(+)
diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c
index 538b695c29..f32f95a7dc 100644
--- a/hw/virtio/virtio-mem.c
+++ b/hw/virtio/virtio-mem.c
@@ -1468,6 +1468,30 @@ static void virtio_mem_rdm_unregister_listener(RamDiscardManager *rdm,
QLIST_REMOVE(rdl, next);
}
+static void virtio_mem_unplug_request_check(VirtIOMEM *vmem, Error **errp)
+{
+ if (vmem->unplugged_inaccessible == ON_OFF_AUTO_OFF) {
+ /*
+ * We could allow it with a usable region size of 0, but let's just
+ * not care about that legacy setting.
+ */
+ error_setg(errp, "virtio-mem device cannot get unplugged while"
+ " '" VIRTIO_MEM_UNPLUGGED_INACCESSIBLE_PROP "' != 'on'");
+ return;
+ }
+
+ if (vmem->size) {
+ error_setg(errp, "virtio-mem device cannot get unplugged while"
+ " '" VIRTIO_MEM_SIZE_PROP "' != '0'");
+ return;
+ }
+ if (vmem->requested_size) {
+ error_setg(errp, "virtio-mem device cannot get unplugged while"
+ " '" VIRTIO_MEM_REQUESTED_SIZE_PROP "' != '0'");
+ return;
+ }
+}
+
static void virtio_mem_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
@@ -1490,6 +1514,7 @@ static void virtio_mem_class_init(ObjectClass *klass, void *data)
vmc->get_memory_region = virtio_mem_get_memory_region;
vmc->add_size_change_notifier = virtio_mem_add_size_change_notifier;
vmc->remove_size_change_notifier = virtio_mem_remove_size_change_notifier;
+ vmc->unplug_request_check = virtio_mem_unplug_request_check;
rdmc->get_min_granularity = virtio_mem_rdm_get_min_granularity;
rdmc->is_populated = virtio_mem_rdm_is_populated;
diff --git a/include/hw/virtio/virtio-mem.h b/include/hw/virtio/virtio-mem.h
index f15e561785..ab0fe2b4f2 100644
--- a/include/hw/virtio/virtio-mem.h
+++ b/include/hw/virtio/virtio-mem.h
@@ -98,6 +98,7 @@ struct VirtIOMEMClass {
MemoryRegion *(*get_memory_region)(VirtIOMEM *vmem, Error **errp);
void (*add_size_change_notifier)(VirtIOMEM *vmem, Notifier *notifier);
void (*remove_size_change_notifier)(VirtIOMEM *vmem, Notifier *notifier);
+ void (*unplug_request_check)(VirtIOMEM *vmem, Error **errp);
};
#endif
--
2.40.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v2 7/7] virtio-mem-pci: Device unplug support
2023-06-23 12:20 [PATCH v2 0/7] virtio-mem: Device unplug support David Hildenbrand
` (5 preceding siblings ...)
2023-06-23 12:20 ` [PATCH v2 6/7] virtio-mem: Prepare for device unplug support David Hildenbrand
@ 2023-06-23 12:20 ` David Hildenbrand
6 siblings, 0 replies; 8+ messages in thread
From: David Hildenbrand @ 2023-06-23 12:20 UTC (permalink / raw)
To: qemu-devel
Cc: David Hildenbrand, Peter Maydell, Paolo Bonzini,
Richard Henderson, Eduardo Habkost, Michael S. Tsirkin,
Marcel Apfelbaum, Igor Mammedov, qemu-arm, Gavin Shan
Let's support device unplug by forwarding the unplug_request_check()
callback to the virtio-mem device.
Further, disallow changing the requested-size once an unplug request is
pending.
Disallowing requested-size changes handles corner cases such as
(1) pausing the VM (2) requesting device unplug and (3) adjusting the
requested size. If the VM would plug memory (due to the requested size
change) before processing the unplug request, we would be in trouble.
Signed-off-by: David Hildenbrand <david@redhat.com>
---
hw/virtio/virtio-mem-pci.c | 49 +++++++++++++++++++++++++++++++++++---
1 file changed, 46 insertions(+), 3 deletions(-)
diff --git a/hw/virtio/virtio-mem-pci.c b/hw/virtio/virtio-mem-pci.c
index 2ef0f07630..c4597e029e 100644
--- a/hw/virtio/virtio-mem-pci.c
+++ b/hw/virtio/virtio-mem-pci.c
@@ -93,12 +93,53 @@ static void virtio_mem_pci_size_change_notify(Notifier *notifier, void *data)
g_free(qom_path);
}
+static void virtio_mem_pci_unplug_request_check(VirtIOMDPCI *vmd, Error **errp)
+{
+ VirtIOMEMPCI *pci_mem = VIRTIO_MEM_PCI(vmd);
+ VirtIOMEM *vmem = &pci_mem->vdev;
+ VirtIOMEMClass *vpc = VIRTIO_MEM_GET_CLASS(vmem);
+
+ vpc->unplug_request_check(vmem, errp);
+}
+
+static void virtio_mem_pci_get_requested_size(Object *obj, Visitor *v,
+ const char *name, void *opaque,
+ Error **errp)
+{
+ VirtIOMEMPCI *pci_mem = VIRTIO_MEM_PCI(obj);
+
+ object_property_get(OBJECT(&pci_mem->vdev), name, v, errp);
+}
+
+static void virtio_mem_pci_set_requested_size(Object *obj, Visitor *v,
+ const char *name, void *opaque,
+ Error **errp)
+{
+ VirtIOMEMPCI *pci_mem = VIRTIO_MEM_PCI(obj);
+ DeviceState *dev = DEVICE(obj);
+
+ /*
+ * If we passed virtio_mem_pci_unplug_request_check(), making sure that
+ * the requested size is 0, don't allow modifying the requested size
+ * anymore, otherwise the VM might end up hotplugging memory before
+ * handling the unplug request.
+ */
+ if (dev->pending_deleted_event) {
+ error_setg(errp, "'%s' cannot be changed if the device is in the"
+ " process of unplug", name);
+ return;
+ }
+
+ object_property_set(OBJECT(&pci_mem->vdev), name, v, errp);
+}
+
static void virtio_mem_pci_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
MemoryDeviceClass *mdc = MEMORY_DEVICE_CLASS(klass);
+ VirtIOMDPCIClass *vmdc = VIRTIO_MD_PCI_CLASS(klass);
k->realize = virtio_mem_pci_realize;
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
@@ -111,6 +152,8 @@ static void virtio_mem_pci_class_init(ObjectClass *klass, void *data)
mdc->get_memory_region = virtio_mem_pci_get_memory_region;
mdc->fill_device_info = virtio_mem_pci_fill_device_info;
mdc->get_min_alignment = virtio_mem_pci_get_min_alignment;
+
+ vmdc->unplug_request_check = virtio_mem_pci_unplug_request_check;
}
static void virtio_mem_pci_instance_init(Object *obj)
@@ -135,9 +178,9 @@ static void virtio_mem_pci_instance_init(Object *obj)
OBJECT(&dev->vdev), VIRTIO_MEM_BLOCK_SIZE_PROP);
object_property_add_alias(obj, VIRTIO_MEM_SIZE_PROP, OBJECT(&dev->vdev),
VIRTIO_MEM_SIZE_PROP);
- object_property_add_alias(obj, VIRTIO_MEM_REQUESTED_SIZE_PROP,
- OBJECT(&dev->vdev),
- VIRTIO_MEM_REQUESTED_SIZE_PROP);
+ object_property_add(obj, VIRTIO_MEM_REQUESTED_SIZE_PROP, "size",
+ virtio_mem_pci_get_requested_size,
+ virtio_mem_pci_set_requested_size, NULL, NULL);
}
static const VirtioPCIDeviceTypeInfo virtio_mem_pci_info = {
--
2.40.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
end of thread, other threads:[~2023-06-23 12:28 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-06-23 12:20 [PATCH v2 0/7] virtio-mem: Device unplug support David Hildenbrand
2023-06-23 12:20 ` [PATCH v2 1/7] virtio-md-pci: New parent type for virtio-mem-pci and virtio-pmem-pci David Hildenbrand
2023-06-23 12:20 ` [PATCH v2 2/7] pc: Factor out (un)plug handling of virtio-md-pci devices David Hildenbrand
2023-06-23 12:20 ` [PATCH v2 3/7] arm/virt: Use virtio-md-pci (un)plug functions David Hildenbrand
2023-06-23 12:20 ` [PATCH v2 4/7] virtio-md-pci: Handle unplug of virtio based memory devices David Hildenbrand
2023-06-23 12:20 ` [PATCH v2 5/7] virtio-md-pci: Support unplug requests for compatible devices David Hildenbrand
2023-06-23 12:20 ` [PATCH v2 6/7] virtio-mem: Prepare for device unplug support David Hildenbrand
2023-06-23 12:20 ` [PATCH v2 7/7] virtio-mem-pci: Device " David Hildenbrand
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).