All of lore.kernel.org
 help / color / mirror / Atom feed
From: Igor Mammedov <imammedo@redhat.com>
To: fanhuang <FangSheng.Huang@amd.com>
Cc: <qemu-devel@nongnu.org>, <david@kernel.org>, <gourry@gourry.net>,
	<philmd@mailo.com>, <Zhigang.Luo@amd.com>, <Lianjie.Shi@amd.com>
Subject: Re: [PATCH v10 1/4] hw/mem: add sp-mem device for Specific Purpose Memory
Date: Tue, 9 Jun 2026 11:03:24 +0200	[thread overview]
Message-ID: <20260609110324.41b410c0@imammedo> (raw)
In-Reply-To: <20260605104609.1739911-2-FangSheng.Huang@amd.com>

On Fri, 5 Jun 2026 18:46:06 +0800
fanhuang <FangSheng.Huang@amd.com> wrote:

> Introduce a TYPE_MEMORY_DEVICE subclass `sp-mem` for boot-time
> SOFT_RESERVED memory exposed to the guest with a per-device NUMA
> proximity domain.
> 
> The device targets accelerator memory (HBM and similar) that the
> firmware hands to the guest OS as SOFT_RESERVED memory, so a driver
> in the guest -- rather than the kernel's general allocator -- owns
> the range.
> 
> Usage:
> 
>     -object memory-backend-ram,id=spm0,size=$SIZE
>     -numa node,nodeid=$N
>     -device sp-mem,id=dev0,memdev=spm0,node=$N[,addr=$GPA]
> 
> The device is boot-time only (no hotplug).
> 
> Signed-off-by: FangSheng Huang <FangSheng.Huang@amd.com>
> ---
>  qapi/machine.json       |  43 ++++++++++++-
>  include/hw/mem/sp-mem.h |  35 +++++++++++
>  hw/mem/sp-mem.c         | 130 ++++++++++++++++++++++++++++++++++++++++
>  hw/mem/Kconfig          |   4 ++
>  hw/mem/meson.build      |   1 +
>  5 files changed, 211 insertions(+), 2 deletions(-)
>  create mode 100644 include/hw/mem/sp-mem.h
>  create mode 100644 hw/mem/sp-mem.c
> 
> diff --git a/qapi/machine.json b/qapi/machine.json
> index 685e4e29b8..41cc3a188a 100644
> --- a/qapi/machine.json
> +++ b/qapi/machine.json
> @@ -1413,6 +1413,32 @@
>            }
>  }
>  
> +##
> +# @SpMemDeviceInfo:
> +#
> +# sp-mem device state information
> +#
> +# @id: device's ID
> +#
> +# @memaddr: physical address in memory, where device is mapped
> +#
> +# @size: size of memory that the device provides
> +#
> +# @node: NUMA proximity domain to which the device is assigned
> +#
> +# @memdev: memory backend linked with device
> +#
> +# Since: 11.1
> +##
> +{ 'struct': 'SpMemDeviceInfo',
> +  'data': { '*id': 'str',
> +            'memaddr': 'size',

why not 'addr', like DIMM?

> +            'size': 'size',
> +            'node': 'int',
> +            'memdev': 'str'
> +          }
> +}
> +
>  ##
>  # @MemoryDeviceInfoKind:
>  #
> @@ -1426,11 +1452,13 @@
>  #
>  # @hv-balloon: since 8.2.
>  #
> +# @sp-mem: since 11.1.
> +#
>  # Since: 2.1
>  ##
>  { 'enum': 'MemoryDeviceInfoKind',
>    'data': [ 'dimm', 'nvdimm', 'virtio-pmem', 'virtio-mem', 'sgx-epc',
> -            'hv-balloon' ] }
> +            'hv-balloon', 'sp-mem' ] }
>  
>  ##
>  # @PCDIMMDeviceInfoWrapper:
> @@ -1482,6 +1510,16 @@
>  { 'struct': 'HvBalloonDeviceInfoWrapper',
>    'data': { 'data': 'HvBalloonDeviceInfo' } }
>  
> +##
> +# @SpMemDeviceInfoWrapper:
> +#
> +# @data: sp-mem device state information
> +#
> +# Since: 11.1
> +##
> +{ 'struct': 'SpMemDeviceInfoWrapper',
> +  'data': { 'data': 'SpMemDeviceInfo' } }
> +
>  ##
>  # @MemoryDeviceInfo:
>  #
> @@ -1499,7 +1537,8 @@
>              'virtio-pmem': 'VirtioPMEMDeviceInfoWrapper',
>              'virtio-mem': 'VirtioMEMDeviceInfoWrapper',
>              'sgx-epc': 'SgxEPCDeviceInfoWrapper',
> -            'hv-balloon': 'HvBalloonDeviceInfoWrapper'
> +            'hv-balloon': 'HvBalloonDeviceInfoWrapper',
> +            'sp-mem': 'SpMemDeviceInfoWrapper'
>            }
>  }
>  
> diff --git a/include/hw/mem/sp-mem.h b/include/hw/mem/sp-mem.h
> new file mode 100644
> index 0000000000..5c0b6ec4f8
> --- /dev/null
> +++ b/include/hw/mem/sp-mem.h
> @@ -0,0 +1,35 @@
> +/*
> + * Specific Purpose Memory (SPM) device
> + *
> + * TYPE_MEMORY_DEVICE subclass for boot-time-only memory exposed to the
> + * guest as an E820 SOFT_RESERVED range with a SRAT memory-affinity entry.
> + *
> + * Copyright (c) 2026 Advanced Micro Devices, Inc.
> + *
> + * Authors:
> + *  FangSheng Huang <FangSheng.Huang@amd.com>
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#ifndef QEMU_SP_MEM_H
> +#define QEMU_SP_MEM_H
> +
> +#include "hw/mem/memory-device.h"
> +#include "hw/core/qdev.h"
> +#include "qom/object.h"
> +#include "system/hostmem.h"
> +
> +#define TYPE_SP_MEM "sp-mem"
> +
> +OBJECT_DECLARE_SIMPLE_TYPE(SpMemDevice, SP_MEM)
> +
> +struct SpMemDevice {
> +    DeviceState parent_obj;
> +
> +    HostMemoryBackend *hostmem;
> +    uint32_t node;
> +    uint64_t addr;
> +};
> +
> +#endif /* QEMU_SP_MEM_H */
> diff --git a/hw/mem/sp-mem.c b/hw/mem/sp-mem.c
> new file mode 100644
> index 0000000000..f6ba9a6d7c
> --- /dev/null
> +++ b/hw/mem/sp-mem.c
> @@ -0,0 +1,130 @@
> +/*
> + * Specific Purpose Memory (SPM) device
> + *
> + * Copyright (c) 2026 Advanced Micro Devices, Inc.
> + *
> + * Authors:
> + *  FangSheng Huang <FangSheng.Huang@amd.com>
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu/module.h"
> +#include "qapi/error.h"
> +#include "hw/core/qdev-properties.h"
> +#include "hw/core/qdev.h"
> +#include "hw/mem/sp-mem.h"
> +#include "hw/mem/memory-device.h"
> +#include "migration/vmstate.h"
> +#include "system/hostmem.h"
> +
> +#define SP_MEM_MEMDEV_PROP    "memdev"
> +#define SP_MEM_NODE_PROP      "node"
> +#define SP_MEM_ADDR_PROP      "addr"
> +
> +static const Property sp_mem_properties[] = {
> +    DEFINE_PROP_LINK(SP_MEM_MEMDEV_PROP, SpMemDevice, hostmem,
> +                     TYPE_MEMORY_BACKEND, HostMemoryBackend *),
> +    DEFINE_PROP_UINT32(SP_MEM_NODE_PROP, SpMemDevice, node, 0),
> +    DEFINE_PROP_UINT64(SP_MEM_ADDR_PROP, SpMemDevice, addr, 0),
> +};
> +
> +static uint64_t sp_mem_get_addr(const MemoryDeviceState *md)
> +{
> +    return SP_MEM(md)->addr;

device cast + deref, should be separate. or even better look at
pc_dimm_md_get_addr()

> +}
> +
> +static void sp_mem_set_addr(MemoryDeviceState *md, uint64_t addr,
> +                            Error **errp)
> +{
> +    SP_MEM(md)->addr = addr;
> +}

ditto

> +
> +static MemoryRegion *sp_mem_get_memory_region(MemoryDeviceState *md,
> +                                              Error **errp)
> +{
> +    SpMemDevice *spm = SP_MEM(md);
> +
> +    if (!spm->hostmem) {
> +        error_setg(errp, "'memdev' property must be set");
> +        return NULL;
> +    }
> +    return host_memory_backend_get_memory(spm->hostmem);
> +}
> +
> +static uint64_t sp_mem_get_plugged_size(const MemoryDeviceState *md,
> +                                        Error **errp)
> +{
> +    SpMemDevice *spm = SP_MEM(md);
> +    return spm->hostmem ?
> +        memory_region_size(host_memory_backend_get_memory(spm->hostmem)) : 0;
> +}
> +
> +static void sp_mem_fill_device_info(const MemoryDeviceState *md,
> +                                    MemoryDeviceInfo *info)
> +{
> +    SpMemDeviceInfo *di = g_new0(SpMemDeviceInfo, 1);
> +    SpMemDevice *spm = SP_MEM(md);
> +    DeviceState *dev = DEVICE(md);
> +
> +    di->id = dev->id ? g_strdup(dev->id) : NULL;
> +    di->memaddr = spm->addr;
> +    di->size = spm->hostmem ? memory_region_size(
> +                   host_memory_backend_get_memory(spm->hostmem)) : 0;

why conditional?

> +    di->node = spm->node;
> +    di->memdev = spm->hostmem ?
> +                 object_get_canonical_path(OBJECT(spm->hostmem)) : NULL;
ditto

> +
> +    info->u.sp_mem.data = di;
> +    info->type = MEMORY_DEVICE_INFO_KIND_SP_MEM;
> +}
> +
> +static void sp_mem_realize(DeviceState *dev, Error **errp)
> +{
> +    SpMemDevice *spm = SP_MEM(dev);
> +
> +    if (!spm->hostmem) {
> +        error_setg(errp, "'%s' property is required", SP_MEM_MEMDEV_PROP);
> +        return;
> +    }
> +}
> +
> +/* boot-time only; no plug/unplug state to migrate */
> +static const VMStateDescription vmstate_sp_mem = {
> +    .name = TYPE_SP_MEM,
> +    .unmigratable = 1,
> +};
> +
> +static void sp_mem_class_init(ObjectClass *oc, const void *data)
> +{
> +    DeviceClass *dc = DEVICE_CLASS(oc);
> +    MemoryDeviceClass *mdc = MEMORY_DEVICE_CLASS(oc);
> +
> +    dc->desc = "SPM (Specific Purpose Memory) device";
> +    dc->hotpluggable = false;
> +    dc->realize = sp_mem_realize;
> +    dc->vmsd = &vmstate_sp_mem;
> +    device_class_set_props(dc, sp_mem_properties);
> +
> +    mdc->get_addr            = sp_mem_get_addr;
> +    mdc->set_addr            = sp_mem_set_addr;
> +    mdc->get_memory_region   = sp_mem_get_memory_region;
> +    mdc->get_plugged_size    = sp_mem_get_plugged_size;
                                   ^^^^
wouldn't memory_device_get_region_size() do here?

> +    mdc->fill_device_info    = sp_mem_fill_device_info;
> +}
> +
> +static const TypeInfo sp_mem_types[] = {
> +    {
> +        .name          = TYPE_SP_MEM,
> +        .parent        = TYPE_DEVICE,
> +        .class_init    = sp_mem_class_init,
> +        .instance_size = sizeof(SpMemDevice),
> +        .interfaces    = (InterfaceInfo[]) {
> +            { TYPE_MEMORY_DEVICE },
> +            { }
> +        },
> +    },
> +};
> +
> +DEFINE_TYPES(sp_mem_types)
> diff --git a/hw/mem/Kconfig b/hw/mem/Kconfig
> index 73c5ae8ad9..39ddb36710 100644
> --- a/hw/mem/Kconfig
> +++ b/hw/mem/Kconfig
> @@ -16,3 +16,7 @@ config CXL_MEM_DEVICE
>      bool
>      default y if CXL
>      select MEM_DEVICE
> +
> +config SP_MEM
> +    bool
> +    select MEM_DEVICE
> diff --git a/hw/mem/meson.build b/hw/mem/meson.build
> index 8c2beeb7d4..f410d75475 100644
> --- a/hw/mem/meson.build
> +++ b/hw/mem/meson.build
> @@ -4,6 +4,7 @@ mem_ss.add(when: 'CONFIG_DIMM', if_true: files('pc-dimm.c'))
>  mem_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_mc.c'))
>  mem_ss.add(when: 'CONFIG_NVDIMM', if_true: files('nvdimm.c'))
>  mem_ss.add(when: 'CONFIG_CXL_MEM_DEVICE', if_true: files('cxl_type3.c'))
> +mem_ss.add(when: 'CONFIG_SP_MEM', if_true: files('sp-mem.c'))
>  stub_ss.add(files('cxl_type3_stubs.c'))
>  
>  stub_ss.add(files('memory-device-stubs.c'))



  parent reply	other threads:[~2026-06-09  9:03 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-05 10:46 [PATCH v10 0/4] hw/mem: add sp-mem device for Specific Purpose Memory fanhuang
2026-06-05 10:46 ` [PATCH v10 1/4] " fanhuang
2026-06-05 15:10   ` David Hildenbrand (Arm)
2026-06-05 21:22   ` Gregory Price
2026-06-09  9:03   ` Igor Mammedov [this message]
2026-06-05 10:46 ` [PATCH v10 2/4] i386/acpi-build: partition device_memory SRAT umbrella for sp-mem fanhuang
2026-06-05 21:27   ` Gregory Price
2026-06-09  3:53     ` Huang, FangSheng (Jerry)
2026-06-09 11:14   ` Igor Mammedov
2026-06-05 10:46 ` [PATCH v10 3/4] hw/i386: hook sp-mem into the pc machine plug path fanhuang
2026-06-09 11:52   ` Igor Mammedov
2026-06-05 10:46 ` [PATCH v10 4/4] MAINTAINERS: cover sp-mem under Memory devices, add R: tag fanhuang
2026-06-09 11:53   ` Igor Mammedov
2026-06-09 12:51   ` David Hildenbrand (Arm)

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260609110324.41b410c0@imammedo \
    --to=imammedo@redhat.com \
    --cc=FangSheng.Huang@amd.com \
    --cc=Lianjie.Shi@amd.com \
    --cc=Zhigang.Luo@amd.com \
    --cc=david@kernel.org \
    --cc=gourry@gourry.net \
    --cc=philmd@mailo.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.