On 10/28/2026 12:15 PM, Yonggang Luo wrote:
> 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);

Fine for me, let's see what virtio maintainers think about it.

Regards,
Pierrick

Reply via email to