All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/7] virtio-mem: Device unplug support
@ 2023-07-10 10:07 David Hildenbrand
  2023-07-10 10:07 ` [PATCH v3 1/7] virtio-md-pci: New parent type for virtio-mem-pci and virtio-pmem-pci David Hildenbrand
                   ` (7 more replies)
  0 siblings, 8 replies; 15+ messages in thread
From: David Hildenbrand @ 2023-07-10 10:07 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,
	Mario Casquero

Any further comments? IMHO this is pretty straight forward. I'll wait
a bit longer for more feedback.


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.

v2 -> v3:
- "virtio-md-pci: New parent type for virtio-mem-pci and virtio-pmem-pci"
 -> Add MAINTAINERS entry

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>
Cc: Mario Casquero <mcasquer@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

 MAINTAINERS                       |   6 ++
 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 +
 13 files changed, 311 insertions(+), 167 deletions(-)
 create mode 100644 hw/virtio/virtio-md-pci.c
 create mode 100644 include/hw/virtio/virtio-md-pci.h

-- 
2.41.0



^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v3 1/7] virtio-md-pci: New parent type for virtio-mem-pci and virtio-pmem-pci
  2023-07-10 10:07 [PATCH v3 0/7] virtio-mem: Device unplug support David Hildenbrand
@ 2023-07-10 10:07 ` David Hildenbrand
  2023-07-10 10:07 ` [PATCH v3 2/7] pc: Factor out (un)plug handling of virtio-md-pci devices David Hildenbrand
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 15+ messages in thread
From: David Hildenbrand @ 2023-07-10 10:07 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,
	Mario Casquero

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>
---
 MAINTAINERS                       |  6 ++++++
 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 +++++++++++++++++++++++++++++++
 9 files changed, 89 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/MAINTAINERS b/MAINTAINERS
index 1817cfc62f..e3f09588ce 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2224,6 +2224,12 @@ F: hw/virtio/virtio-crypto.c
 F: hw/virtio/virtio-crypto-pci.c
 F: include/hw/virtio/virtio-crypto.h
 
+virtio based memory device
+M: David Hildenbrand <david@redhat.com>
+S: Supported
+F: hw/virtio/virtio-md-pci.c
+F: include/hw/virtio/virtio-md-pci.h
+
 virtio-mem
 M: David Hildenbrand <david@redhat.com>
 S: Supported
diff --git a/hw/virtio/Kconfig b/hw/virtio/Kconfig
index de7a35429a..e8cf1b95c0 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_COMMON
     bool
diff --git a/hw/virtio/meson.build b/hw/virtio/meson.build
index f32b22f61b..3dfd56f54d 100644
--- a/hw/virtio/meson.build
+++ b/hw/virtio/meson.build
@@ -61,6 +61,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.41.0



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v3 2/7] pc: Factor out (un)plug handling of virtio-md-pci devices
  2023-07-10 10:07 [PATCH v3 0/7] virtio-mem: Device unplug support David Hildenbrand
  2023-07-10 10:07 ` [PATCH v3 1/7] virtio-md-pci: New parent type for virtio-mem-pci and virtio-pmem-pci David Hildenbrand
@ 2023-07-10 10:07 ` David Hildenbrand
  2023-07-10 10:07 ` [PATCH v3 3/7] arm/virt: Use virtio-md-pci (un)plug functions David Hildenbrand
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 15+ messages in thread
From: David Hildenbrand @ 2023-07-10 10:07 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,
	Mario Casquero

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 f01d7de5ad..c74a4014f0 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.41.0



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v3 3/7] arm/virt: Use virtio-md-pci (un)plug functions
  2023-07-10 10:07 [PATCH v3 0/7] virtio-mem: Device unplug support David Hildenbrand
  2023-07-10 10:07 ` [PATCH v3 1/7] virtio-md-pci: New parent type for virtio-mem-pci and virtio-pmem-pci David Hildenbrand
  2023-07-10 10:07 ` [PATCH v3 2/7] pc: Factor out (un)plug handling of virtio-md-pci devices David Hildenbrand
@ 2023-07-10 10:07 ` David Hildenbrand
  2023-07-10 21:40   ` Michael S. Tsirkin
  2023-07-10 10:07 ` [PATCH v3 4/7] virtio-md-pci: Handle unplug of virtio based memory devices David Hildenbrand
                   ` (4 subsequent siblings)
  7 siblings, 1 reply; 15+ messages in thread
From: David Hildenbrand @ 2023-07-10 10:07 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,
	Mario Casquero

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 8a4c663735..4ae1996d37 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -73,11 +73,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"
@@ -2740,64 +2739,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)
 {
@@ -2805,8 +2746,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;
@@ -2855,12 +2796,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)) {
@@ -2915,8 +2855,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)));
@@ -2928,6 +2869,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)));
@@ -2941,7 +2884,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.41.0



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v3 4/7] virtio-md-pci: Handle unplug of virtio based memory devices
  2023-07-10 10:07 [PATCH v3 0/7] virtio-mem: Device unplug support David Hildenbrand
                   ` (2 preceding siblings ...)
  2023-07-10 10:07 ` [PATCH v3 3/7] arm/virt: Use virtio-md-pci (un)plug functions David Hildenbrand
@ 2023-07-10 10:07 ` David Hildenbrand
  2023-07-10 10:07 ` [PATCH v3 5/7] virtio-md-pci: Support unplug requests for compatible devices David Hildenbrand
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 15+ messages in thread
From: David Hildenbrand @ 2023-07-10 10:07 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,
	Mario Casquero

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.41.0



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v3 5/7] virtio-md-pci: Support unplug requests for compatible devices
  2023-07-10 10:07 [PATCH v3 0/7] virtio-mem: Device unplug support David Hildenbrand
                   ` (3 preceding siblings ...)
  2023-07-10 10:07 ` [PATCH v3 4/7] virtio-md-pci: Handle unplug of virtio based memory devices David Hildenbrand
@ 2023-07-10 10:07 ` David Hildenbrand
  2023-07-10 10:07 ` [PATCH v3 6/7] virtio-mem: Prepare for device unplug support David Hildenbrand
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 15+ messages in thread
From: David Hildenbrand @ 2023-07-10 10:07 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,
	Mario Casquero

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.41.0



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v3 6/7] virtio-mem: Prepare for device unplug support
  2023-07-10 10:07 [PATCH v3 0/7] virtio-mem: Device unplug support David Hildenbrand
                   ` (4 preceding siblings ...)
  2023-07-10 10:07 ` [PATCH v3 5/7] virtio-md-pci: Support unplug requests for compatible devices David Hildenbrand
@ 2023-07-10 10:07 ` David Hildenbrand
  2023-07-10 10:07 ` [PATCH v3 7/7] virtio-mem-pci: Device " David Hildenbrand
  2023-07-11 14:19 ` [PATCH v3 0/7] virtio-mem: " Mario Casquero
  7 siblings, 0 replies; 15+ messages in thread
From: David Hildenbrand @ 2023-07-10 10:07 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,
	Mario Casquero

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 ec0ae32589..27b3aac87c 100644
--- a/hw/virtio/virtio-mem.c
+++ b/hw/virtio/virtio-mem.c
@@ -1483,6 +1483,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);
@@ -1505,6 +1529,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.41.0



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v3 7/7] virtio-mem-pci: Device unplug support
  2023-07-10 10:07 [PATCH v3 0/7] virtio-mem: Device unplug support David Hildenbrand
                   ` (5 preceding siblings ...)
  2023-07-10 10:07 ` [PATCH v3 6/7] virtio-mem: Prepare for device unplug support David Hildenbrand
@ 2023-07-10 10:07 ` David Hildenbrand
  2023-07-11 14:19 ` [PATCH v3 0/7] virtio-mem: " Mario Casquero
  7 siblings, 0 replies; 15+ messages in thread
From: David Hildenbrand @ 2023-07-10 10:07 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,
	Mario Casquero

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.41.0



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH v3 3/7] arm/virt: Use virtio-md-pci (un)plug functions
  2023-07-10 10:07 ` [PATCH v3 3/7] arm/virt: Use virtio-md-pci (un)plug functions David Hildenbrand
@ 2023-07-10 21:40   ` Michael S. Tsirkin
  2023-07-11  8:32     ` David Hildenbrand
  0 siblings, 1 reply; 15+ messages in thread
From: Michael S. Tsirkin @ 2023-07-10 21:40 UTC (permalink / raw)
  To: David Hildenbrand
  Cc: qemu-devel, Peter Maydell, Paolo Bonzini, Richard Henderson,
	Eduardo Habkost, Marcel Apfelbaum, Igor Mammedov, qemu-arm,
	Gavin Shan, Mario Casquero

On Mon, Jul 10, 2023 at 12:07:10PM +0200, David Hildenbrand wrote:
> 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 8a4c663735..4ae1996d37 100644
> --- a/hw/arm/virt.c
> +++ b/hw/arm/virt.c
> @@ -73,11 +73,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"
> @@ -2740,64 +2739,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)
>  {
> @@ -2805,8 +2746,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;
> @@ -2855,12 +2796,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)) {


How is this supposed to link if virtio-md is disabled at compile time?

Indeed I see this on mingw:

FAILED: qemu-system-aarch64.exe 
i686-w64-mingw32-gcc -m32 @qemu-system-aarch64.exe.rsp
/usr/lib/gcc/i686-w64-mingw32/12.2.1/../../../../i686-w64-mingw32/bin/ld: libqemu-aarch64-softmmu.fa.p/hw_arm_virt.c.obj: in function `virt_machine_device_plug_cb':
/scm/qemu-mingw32-build/../qemu/hw/arm/virt.c:2803: undefined reference to `virtio_md_pci_plug'
/usr/lib/gcc/i686-w64-mingw32/12.2.1/../../../../i686-w64-mingw32/bin/ld: libqemu-aarch64-softmmu.fa.p/hw_arm_virt.c.obj: in function `virt_machine_device_unplug_request_cb':
/scm/qemu-mingw32-build/../qemu/hw/arm/virt.c:2859: undefined reference to `virtio_md_pci_unplug_request'
/usr/lib/gcc/i686-w64-mingw32/12.2.1/../../../../i686-w64-mingw32/bin/ld: libqemu-aarch64-softmmu.fa.p/hw_arm_virt.c.obj: in function `virt_machine_device_unplug_cb':
/scm/qemu-mingw32-build/../qemu/hw/arm/virt.c:2873: undefined reference to `virtio_md_pci_unplug'
/usr/lib/gcc/i686-w64-mingw32/12.2.1/../../../../i686-w64-mingw32/bin/ld: libqemu-aarch64-softmmu.fa.p/hw_arm_virt.c.obj: in function `virt_machine_device_pre_plug_cb':
/scm/qemu-mingw32-build/../qemu/hw/arm/virt.c:2750: undefined reference to `virtio_md_pci_pre_plug'
collect2: error: ld returned 1 exit status
[795/3838] Linking target qemu-system-aarch64w.exe
FAILED: qemu-system-aarch64w.exe 
i686-w64-mingw32-gcc -m32 @qemu-system-aarch64w.exe.rsp
/usr/lib/gcc/i686-w64-mingw32/12.2.1/../../../../i686-w64-mingw32/bin/ld: libqemu-aarch64-softmmu.fa.p/hw_arm_virt.c.obj: in function `virt_machine_device_plug_cb':
/scm/qemu-mingw32-build/../qemu/hw/arm/virt.c:2803: undefined reference to `virtio_md_pci_plug'
/usr/lib/gcc/i686-w64-mingw32/12.2.1/../../../../i686-w64-mingw32/bin/ld: libqemu-aarch64-softmmu.fa.p/hw_arm_virt.c.obj: in function `virt_machine_device_unplug_request_cb':
/scm/qemu-mingw32-build/../qemu/hw/arm/virt.c:2859: undefined reference to `virtio_md_pci_unplug_request'
/usr/lib/gcc/i686-w64-mingw32/12.2.1/../../../../i686-w64-mingw32/bin/ld: libqemu-aarch64-softmmu.fa.p/hw_arm_virt.c.obj: in function `virt_machine_device_unplug_cb':
/scm/qemu-mingw32-build/../qemu/hw/arm/virt.c:2873: undefined reference to `virtio_md_pci_unplug'
/usr/lib/gcc/i686-w64-mingw32/12.2.1/../../../../i686-w64-mingw32/bin/ld: libqemu-aarch64-softmmu.fa.p/hw_arm_virt.c.obj: in function `virt_machine_device_pre_plug_cb':
/scm/qemu-mingw32-build/../qemu/hw/arm/virt.c:2750: undefined reference to `virtio_md_pci_pre_plug'
collect2: error: ld returned 1 exit status
[796/3838] Compiling C object libqemu-cris-softmmu.fa.p/fpu_softfloat.c.obj
[797/3838] Compiling C object libqemu-hppa-softmmu.fa.p/fpu_softfloat.c.obj
ninja: build stopped: subcommand failed.
make: *** [Makefile:162: run-ninja] Error 1




> @@ -2915,8 +2855,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)));
> @@ -2928,6 +2869,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)));
> @@ -2941,7 +2884,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.41.0



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v3 3/7] arm/virt: Use virtio-md-pci (un)plug functions
  2023-07-10 21:40   ` Michael S. Tsirkin
@ 2023-07-11  8:32     ` David Hildenbrand
  2023-07-11  8:47       ` Michael S. Tsirkin
  0 siblings, 1 reply; 15+ messages in thread
From: David Hildenbrand @ 2023-07-11  8:32 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: qemu-devel, Peter Maydell, Paolo Bonzini, Richard Henderson,
	Eduardo Habkost, Marcel Apfelbaum, Igor Mammedov, qemu-arm,
	Gavin Shan, Mario Casquero

On 10.07.23 23:40, Michael S. Tsirkin wrote:
> On Mon, Jul 10, 2023 at 12:07:10PM +0200, David Hildenbrand wrote:
>> 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 8a4c663735..4ae1996d37 100644
>> --- a/hw/arm/virt.c
>> +++ b/hw/arm/virt.c
>> @@ -73,11 +73,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"
>> @@ -2740,64 +2739,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)
>>   {
>> @@ -2805,8 +2746,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;
>> @@ -2855,12 +2796,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)) {
> 
> 
> How is this supposed to link if virtio-md is disabled at compile time?
> 

Good point.

The old code unconditionally enabled MEM_DEVICE, so we never required 
subs for that.

We either need stubs or have to wrap this in #ifdef.

Stubs sound cleaner.

-- 
Cheers,

David / dhildenb



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v3 3/7] arm/virt: Use virtio-md-pci (un)plug functions
  2023-07-11  8:32     ` David Hildenbrand
@ 2023-07-11  8:47       ` Michael S. Tsirkin
  2023-07-11  9:22         ` David Hildenbrand
  0 siblings, 1 reply; 15+ messages in thread
From: Michael S. Tsirkin @ 2023-07-11  8:47 UTC (permalink / raw)
  To: David Hildenbrand
  Cc: qemu-devel, Peter Maydell, Paolo Bonzini, Richard Henderson,
	Eduardo Habkost, Marcel Apfelbaum, Igor Mammedov, qemu-arm,
	Gavin Shan, Mario Casquero

On Tue, Jul 11, 2023 at 10:32:31AM +0200, David Hildenbrand wrote:
> On 10.07.23 23:40, Michael S. Tsirkin wrote:
> > > @@ -2855,12 +2796,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)) {
> > 
> > 
> > How is this supposed to link if virtio-md is disabled at compile time?
> > 
> 
> Good point.
> 
> The old code unconditionally enabled MEM_DEVICE, so we never required subs
> for that.
> 
> We either need stubs or have to wrap this in #ifdef.
> 
> Stubs sound cleaner.

That is what we usually do, yes.

-- 
MST



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v3 3/7] arm/virt: Use virtio-md-pci (un)plug functions
  2023-07-11  8:47       ` Michael S. Tsirkin
@ 2023-07-11  9:22         ` David Hildenbrand
  2023-07-11  9:55           ` David Hildenbrand
  0 siblings, 1 reply; 15+ messages in thread
From: David Hildenbrand @ 2023-07-11  9:22 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: qemu-devel, Peter Maydell, Paolo Bonzini, Richard Henderson,
	Eduardo Habkost, Marcel Apfelbaum, Igor Mammedov, qemu-arm,
	Gavin Shan, Mario Casquero

On 11.07.23 10:47, Michael S. Tsirkin wrote:
> On Tue, Jul 11, 2023 at 10:32:31AM +0200, David Hildenbrand wrote:
>> On 10.07.23 23:40, Michael S. Tsirkin wrote:
>>>> @@ -2855,12 +2796,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)) {
>>>
>>>
>>> How is this supposed to link if virtio-md is disabled at compile time?
>>>
>>
>> Good point.
>>
>> The old code unconditionally enabled MEM_DEVICE, so we never required subs
>> for that.
>>
>> We either need stubs or have to wrap this in #ifdef.
>>
>> Stubs sound cleaner.
> 
> That is what we usually do, yes.
> 

I'm testing with the following:


diff --git a/stubs/meson.build b/stubs/meson.build
index a56645e2f7..160154912c 100644
--- a/stubs/meson.build
+++ b/stubs/meson.build
@@ -65,3 +65,4 @@ else
  endif
  stub_ss.add(files('semihost-all.c'))
  stub_ss.add(when: 'CONFIG_VFIO_USER_SERVER', if_false: files('vfio-user-obj.c'))
+stub_ss.add(when: 'CONFIG_VIRTIO_MD', if_false: files('virtio_md_pci.c'))
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");
+}


For now (not having virtio-md-ccw or virtio-md-mmio) this should do the trick I think.

-- 
Cheers,

David / dhildenb



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH v3 3/7] arm/virt: Use virtio-md-pci (un)plug functions
  2023-07-11  9:22         ` David Hildenbrand
@ 2023-07-11  9:55           ` David Hildenbrand
  0 siblings, 0 replies; 15+ messages in thread
From: David Hildenbrand @ 2023-07-11  9:55 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: qemu-devel, Peter Maydell, Paolo Bonzini, Richard Henderson,
	Eduardo Habkost, Marcel Apfelbaum, Igor Mammedov, qemu-arm,
	Gavin Shan, Mario Casquero

On 11.07.23 11:22, David Hildenbrand wrote:
> On 11.07.23 10:47, Michael S. Tsirkin wrote:
>> On Tue, Jul 11, 2023 at 10:32:31AM +0200, David Hildenbrand wrote:
>>> On 10.07.23 23:40, Michael S. Tsirkin wrote:
>>>>> @@ -2855,12 +2796,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)) {
>>>>
>>>>
>>>> How is this supposed to link if virtio-md is disabled at compile time?
>>>>
>>>
>>> Good point.
>>>
>>> The old code unconditionally enabled MEM_DEVICE, so we never required subs
>>> for that.
>>>
>>> We either need stubs or have to wrap this in #ifdef.
>>>
>>> Stubs sound cleaner.
>>
>> That is what we usually do, yes.
>>
> 
> I'm testing with the following:
> 
> 
> diff --git a/stubs/meson.build b/stubs/meson.build
> index a56645e2f7..160154912c 100644
> --- a/stubs/meson.build
> +++ b/stubs/meson.build
> @@ -65,3 +65,4 @@ else
>    endif
>    stub_ss.add(files('semihost-all.c'))
>    stub_ss.add(when: 'CONFIG_VFIO_USER_SERVER', if_false: files('vfio-user-obj.c'))
> +stub_ss.add(when: 'CONFIG_VIRTIO_MD', if_false: files('virtio_md_pci.c'))

Needs to be

diff --git a/stubs/meson.build b/stubs/meson.build
index a56645e2f7..f16a365731 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


Otherwise it still fails when building for multiple targets.

-- 
Cheers,

David / dhildenb



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH v3 0/7] virtio-mem: Device unplug support
  2023-07-10 10:07 [PATCH v3 0/7] virtio-mem: Device unplug support David Hildenbrand
                   ` (6 preceding siblings ...)
  2023-07-10 10:07 ` [PATCH v3 7/7] virtio-mem-pci: Device " David Hildenbrand
@ 2023-07-11 14:19 ` Mario Casquero
  2023-07-11 15:31   ` David Hildenbrand
  7 siblings, 1 reply; 15+ messages in thread
From: Mario Casquero @ 2023-07-11 14:19 UTC (permalink / raw)
  To: David Hildenbrand
  Cc: qemu-devel, Peter Maydell, Paolo Bonzini, Richard Henderson,
	Eduardo Habkost, Michael S. Tsirkin, Marcel Apfelbaum,
	Igor Mammedov, qemu-arm, Gavin Shan

This series has been successfully tested by QE. Start a VM, plug a
virtio-mem device, resize the device (adding memory) and verify that
the virtio-mem device cannot be unplugged. Finally, resize the device
(removing all the memory) and check that it can be unplugged
seamlessly.

Tested-by: Mario Casquero <mcasquer@redhat.com>

On Mon, Jul 10, 2023 at 12:07 PM David Hildenbrand <david@redhat.com> wrote:
>
> Any further comments? IMHO this is pretty straight forward. I'll wait
> a bit longer for more feedback.
>
>
> 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.
>
> v2 -> v3:
> - "virtio-md-pci: New parent type for virtio-mem-pci and virtio-pmem-pci"
>  -> Add MAINTAINERS entry
>
> 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>
> Cc: Mario Casquero <mcasquer@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
>
>  MAINTAINERS                       |   6 ++
>  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 +
>  13 files changed, 311 insertions(+), 167 deletions(-)
>  create mode 100644 hw/virtio/virtio-md-pci.c
>  create mode 100644 include/hw/virtio/virtio-md-pci.h
>
> --
> 2.41.0
>



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v3 0/7] virtio-mem: Device unplug support
  2023-07-11 14:19 ` [PATCH v3 0/7] virtio-mem: " Mario Casquero
@ 2023-07-11 15:31   ` David Hildenbrand
  0 siblings, 0 replies; 15+ messages in thread
From: David Hildenbrand @ 2023-07-11 15:31 UTC (permalink / raw)
  To: Mario Casquero
  Cc: qemu-devel, Peter Maydell, Paolo Bonzini, Richard Henderson,
	Eduardo Habkost, Michael S. Tsirkin, Marcel Apfelbaum,
	Igor Mammedov, qemu-arm, Gavin Shan

On 11.07.23 16:19, Mario Casquero wrote:
> Tested-by: Mario Casquero<mcasquer@redhat.com>

Thanks a lot Mario!

-- 
Cheers,

David / dhildenb



^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2023-07-11 15:32 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-07-10 10:07 [PATCH v3 0/7] virtio-mem: Device unplug support David Hildenbrand
2023-07-10 10:07 ` [PATCH v3 1/7] virtio-md-pci: New parent type for virtio-mem-pci and virtio-pmem-pci David Hildenbrand
2023-07-10 10:07 ` [PATCH v3 2/7] pc: Factor out (un)plug handling of virtio-md-pci devices David Hildenbrand
2023-07-10 10:07 ` [PATCH v3 3/7] arm/virt: Use virtio-md-pci (un)plug functions David Hildenbrand
2023-07-10 21:40   ` Michael S. Tsirkin
2023-07-11  8:32     ` David Hildenbrand
2023-07-11  8:47       ` Michael S. Tsirkin
2023-07-11  9:22         ` David Hildenbrand
2023-07-11  9:55           ` David Hildenbrand
2023-07-10 10:07 ` [PATCH v3 4/7] virtio-md-pci: Handle unplug of virtio based memory devices David Hildenbrand
2023-07-10 10:07 ` [PATCH v3 5/7] virtio-md-pci: Support unplug requests for compatible devices David Hildenbrand
2023-07-10 10:07 ` [PATCH v3 6/7] virtio-mem: Prepare for device unplug support David Hildenbrand
2023-07-10 10:07 ` [PATCH v3 7/7] virtio-mem-pci: Device " David Hildenbrand
2023-07-11 14:19 ` [PATCH v3 0/7] virtio-mem: " Mario Casquero
2023-07-11 15:31   ` David Hildenbrand

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.