virtio-mem decided in class_init and realize whether x86 guests can
leave unplugged memory accessible. Register a second virtio-mem type
that adds virtio_mem_legacy_guests_properties and sets
VirtIOMEMClass.has_legacy_guests. Select the two with
target_base_i386() and target_not_base_i386().

Signed-off-by: Yonggang Luo <[email protected]>
---
 hw/virtio/virtio-mem.c         | 47 +++++++++++++++++++---------------
 include/hw/virtio/virtio-mem.h |  2 ++
 2 files changed, 29 insertions(+), 20 deletions(-)

diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c
index 7130ed852d9..bf241a3112b 100644
--- a/hw/virtio/virtio-mem.c
+++ b/hw/virtio/virtio-mem.c
@@ -15,6 +15,7 @@
 #include "qemu/cutils.h"
 #include "qemu/error-report.h"
 #include "qemu/units.h"
+#include "qemu/target-info.h"
 #include "qemu/target-info-qapi.h"
 #include "system/memory.h"
 #include "system/numa.h"
@@ -35,22 +36,6 @@
 
 static const VMStateDescription vmstate_virtio_mem_device_early;
 
-static bool virtio_mem_has_legacy_guests(void)
-{
-    /*
-     * We only had legacy x86 guests that did not support
-     * VIRTIO_MEM_F_UNPLUGGED_INACCESSIBLE. Other targets don't have
-     * legacy guests.
-     */
-    switch (target_arch()) {
-    case SYS_EMU_TARGET_I386:
-    case SYS_EMU_TARGET_X86_64:
-        return true;
-    default:
-        return false;
-    }
-}
-
 /*
  * Let's not allow blocks smaller than 1 MiB, for example, to keep the tracking
  * bitmap small.
@@ -859,7 +844,7 @@ static void virtio_mem_device_realize(DeviceState *dev, 
Error **errp)
     rb = vmem->memdev->mr.ram_block;
     page_size = qemu_ram_pagesize(rb);
 
-    if (virtio_mem_has_legacy_guests()) {
+    if (VIRTIO_MEM_GET_CLASS(vmem)->has_legacy_guests) {
         switch (vmem->unplugged_inaccessible) {
         case ON_OFF_AUTO_AUTO:
             if (virtio_mem_has_shared_zeropage(rb)) {
@@ -1635,9 +1620,6 @@ static void virtio_mem_class_init(ObjectClass *klass, 
const void *data)
     RamDiscardSourceClass *rdsc = RAM_DISCARD_SOURCE_CLASS(klass);
 
     device_class_set_props(dc, virtio_mem_properties);
-    if (virtio_mem_has_legacy_guests()) {
-        device_class_set_props(dc, virtio_mem_legacy_guests_properties);
-    }
     dc->vmsd = &vmstate_virtio_mem;
 
     set_bit(DEVICE_CATEGORY_MISC, dc->categories);
@@ -1660,6 +1642,14 @@ static void virtio_mem_class_init(ObjectClass *klass, 
const void *data)
     rdsc->is_populated = virtio_mem_rds_is_populated;
 }
 
+static void virtio_mem_legacy_class_init(ObjectClass *klass, const void *data)
+{
+    virtio_mem_class_init(klass, data);
+    device_class_set_props(DEVICE_CLASS(klass),
+                           virtio_mem_legacy_guests_properties);
+    VIRTIO_MEM_CLASS(klass)->has_legacy_guests = true;
+}
+
 static const TypeInfo virtio_mem_info = {
     .name = TYPE_VIRTIO_MEM,
     .parent = TYPE_VIRTIO_DEVICE,
@@ -1668,6 +1658,22 @@ static const TypeInfo virtio_mem_info = {
     .instance_finalize = virtio_mem_instance_finalize,
     .class_init = virtio_mem_class_init,
     .class_size = sizeof(VirtIOMEMClass),
+    .is_available = target_not_base_i386,
+    .interfaces = (const InterfaceInfo[]) {
+        { TYPE_RAM_DISCARD_SOURCE },
+        { }
+    },
+};
+
+static const TypeInfo virtio_mem_legacy_info = {
+    .name = TYPE_VIRTIO_MEM,
+    .parent = TYPE_VIRTIO_DEVICE,
+    .instance_size = sizeof(VirtIOMEM),
+    .instance_init = virtio_mem_instance_init,
+    .instance_finalize = virtio_mem_instance_finalize,
+    .class_init = virtio_mem_legacy_class_init,
+    .class_size = sizeof(VirtIOMEMClass),
+    .is_available = target_base_i386,
     .interfaces = (const InterfaceInfo[]) {
         { TYPE_RAM_DISCARD_SOURCE },
         { }
@@ -1677,6 +1683,7 @@ static const TypeInfo virtio_mem_info = {
 static void virtio_register_types(void)
 {
     type_register_static(&virtio_mem_info);
+    type_register_static(&virtio_mem_legacy_info);
 }
 
 type_init(virtio_register_types)
diff --git a/include/hw/virtio/virtio-mem.h b/include/hw/virtio/virtio-mem.h
index 5d1d19c6bec..f367959ecb0 100644
--- a/include/hw/virtio/virtio-mem.h
+++ b/include/hw/virtio/virtio-mem.h
@@ -134,6 +134,8 @@ struct VirtIOMEMClass {
     VirtioDeviceClass parent_class;
 
     /* public */
+    bool has_legacy_guests;
+
     void (*fill_device_info)(const VirtIOMEM *vmen, VirtioMEMDeviceInfo *vi);
     MemoryRegion *(*get_memory_region)(VirtIOMEM *vmem, Error **errp);
     void (*decide_memslots)(VirtIOMEM *vmem, unsigned int limit);
-- 
2.55.0.windows.3


Reply via email to