public inbox for qemu-devel@nongnu.org
 help / color / mirror / Atom feed
From: Alireza Sanaee via qemu development <qemu-devel@nongnu.org>
To: <qemu-devel@nongnu.org>
Cc: <anisa.su@samsung.com>, <armbru@redhat.com>,
	<berrange@redhat.com>, <eblake@redhat.com>,
	<jonathan.cameron@huawei.com>, <linux-cxl@vger.kernel.org>,
	<linuxarm@huawei.com>, <lizhijian@fujitsu.com>, <mst@redhat.com>,
	<pbonzini@redhat.com>, <gourry@gourry.net>, <nifan.cxl@gmail.com>,
	<me@linux.beauty>
Subject: [PATCH 2/9] hw/cxl: Allow initializing type3 device with no backing device
Date: Wed, 25 Mar 2026 18:42:50 +0000	[thread overview]
Message-ID: <20260325184259.366-3-alireza.sanaee@huawei.com> (raw)
In-Reply-To: <20260325184259.366-1-alireza.sanaee@huawei.com>

Add a dc-regions-total-size property that allows creating a CXL type3
device with DC regions but without a backing memory device at init time. In
Dynamic Capacity scenarios, memory can show up asynchronously from
different resources (RAM, PMEM, file-backed).  For these cases, only the
total DC size needs to be known upfront.

When dc-regions-total-size is set (instead of volatile-dc-memdev), the
device initializes DC regions using the specified total size but does not
set up any backing memory. Any FMAPI or QMP command that attempts to add or
release extents will fail with an error, since no backing device is
available yet. The runtime hookup of tagged memory backends will be added
in a subsequent patch.

Signed-off-by: Alireza Sanaee <alireza.sanaee@huawei.com>
---
 hw/cxl/cxl-mailbox-utils.c  |  8 ++++
 hw/mem/cxl_type3.c          | 92 ++++++++++++++++++++++---------------
 include/hw/cxl/cxl_device.h |  1 +
 3 files changed, 65 insertions(+), 36 deletions(-)

diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
index c83b5f90d4..e6e136cf44 100644
--- a/hw/cxl/cxl-mailbox-utils.c
+++ b/hw/cxl/cxl-mailbox-utils.c
@@ -4270,6 +4270,10 @@ static CXLRetCode cmd_fm_initiate_dc_add(const struct cxl_cmd *cmd,
     CXLType3Dev *ct3d = CXL_TYPE3(cci->d);
     int i, rc;
 
+    if (ct3d->dc.total_capacity_cmd) {
+        return CXL_MBOX_UNSUPPORTED;
+    }
+
     switch (in->selection_policy) {
         case CXL_EXTENT_SELECTION_POLICY_PRESCRIPTIVE: {
             /* Adding extents exceeds device's extent tracking ability. */
@@ -4357,6 +4361,10 @@ static CXLRetCode cmd_fm_initiate_dc_release(const struct cxl_cmd *cmd,
     CXLType3Dev *ct3d = CXL_TYPE3(cci->d);
     int i, rc;
 
+    if (ct3d->dc.total_capacity_cmd) {
+        return CXL_MBOX_UNSUPPORTED;
+    }
+
     switch (in->flags & CXL_EXTENT_REMOVAL_POLICY_MASK) {
         case CXL_EXTENT_REMOVAL_POLICY_PRESCRIPTIVE: {
             CXLDCExtentList updated_list;
diff --git a/hw/mem/cxl_type3.c b/hw/mem/cxl_type3.c
index d9fc0bec8f..45fb6c55bc 100644
--- a/hw/mem/cxl_type3.c
+++ b/hw/mem/cxl_type3.c
@@ -190,12 +190,15 @@ static int ct3_build_cdat_table(CDATSubHeader ***cdat_table, void *priv)
     }
 
     if (ct3d->dc.num_regions) {
-        if (!ct3d->dc.host_dc) {
-            return -EINVAL;
-        }
-        dc_mr = host_memory_backend_get_memory(ct3d->dc.host_dc);
-        if (!dc_mr) {
-            return -EINVAL;
+        /* Only check if DC is static (has a backing device) */
+        if (ct3d->dc.total_capacity_cmd == 0) {
+            if (!ct3d->dc.host_dc) {
+                return -EINVAL;
+            }
+            dc_mr = host_memory_backend_get_memory(ct3d->dc.host_dc);
+            if (!dc_mr) {
+                return -EINVAL;
+            }
         }
         len += CT3_CDAT_NUM_ENTRIES * ct3d->dc.num_regions;
     }
@@ -216,7 +219,7 @@ static int ct3_build_cdat_table(CDATSubHeader ***cdat_table, void *priv)
         cur_ent += CT3_CDAT_NUM_ENTRIES;
     }
 
-    if (dc_mr) {
+    if (dc_mr || ct3d->dc.total_capacity_cmd) {
         int i;
         uint64_t region_base = vmr_size + pmr_size;
 
@@ -651,8 +654,12 @@ static bool cxl_create_dc_regions(CXLType3Dev *ct3d, Error **errp)
     MemoryRegion *mr;
     uint64_t dc_size;
 
-    mr = host_memory_backend_get_memory(ct3d->dc.host_dc);
-    dc_size = memory_region_size(mr);
+    if (ct3d->dc.total_capacity_cmd != 0) {
+        dc_size = ct3d->dc.total_capacity_cmd;
+    } else {
+        mr = host_memory_backend_get_memory(ct3d->dc.host_dc);
+        dc_size = memory_region_size(mr);
+    }
     region_len = DIV_ROUND_UP(dc_size, ct3d->dc.num_regions);
 
     if (dc_size % (ct3d->dc.num_regions * CXL_CAPACITY_MULTIPLIER) != 0) {
@@ -818,36 +825,41 @@ static bool cxl_setup_memory(CXLType3Dev *ct3d, Error **errp)
         MemoryRegion *dc_mr;
         char *dc_name;
 
-        if (!ct3d->dc.host_dc) {
-            error_setg(errp, "dynamic capacity must have a backing device");
-            return false;
-        }
+        /* Only require backing device if total_capacity_cmd is zero */
+        if (ct3d->dc.total_capacity_cmd == 0) {
+            if (!ct3d->dc.host_dc) {
+                error_setg(errp, "dynamic capacity must have a backing device");
+                return false;
+            }
 
-        dc_mr = host_memory_backend_get_memory(ct3d->dc.host_dc);
-        if (!dc_mr) {
-            error_setg(errp, "dynamic capacity must have a backing device");
-            return false;
-        }
+            dc_mr = host_memory_backend_get_memory(ct3d->dc.host_dc);
+            if (!dc_mr) {
+                error_setg(errp, "dynamic capacity must have a backing device");
+                return false;
+            }
 
-        if (host_memory_backend_is_mapped(ct3d->dc.host_dc)) {
-            error_setg(errp, "memory backend %s can't be used multiple times.",
-               object_get_canonical_path_component(OBJECT(ct3d->dc.host_dc)));
-            return false;
-        }
-        /*
-         * Set DC regions as volatile for now, non-volatile support can
-         * be added in the future if needed.
-         */
-        memory_region_set_nonvolatile(dc_mr, false);
-        memory_region_set_enabled(dc_mr, true);
-        host_memory_backend_set_mapped(ct3d->dc.host_dc, true);
-        if (ds->id) {
-            dc_name = g_strdup_printf("cxl-dcd-dpa-dc-space:%s", ds->id);
-        } else {
-            dc_name = g_strdup("cxl-dcd-dpa-dc-space");
+            if (host_memory_backend_is_mapped(ct3d->dc.host_dc)) {
+                error_setg(errp,
+                           "memory backend %s can't be used multiple times.",
+                           object_get_canonical_path_component(
+                               OBJECT(ct3d->dc.host_dc)));
+                return false;
+            }
+            /*
+             * Set DC regions as volatile for now, non-volatile support can
+             * be added in the future if needed.
+             */
+            memory_region_set_nonvolatile(dc_mr, false);
+            memory_region_set_enabled(dc_mr, true);
+            host_memory_backend_set_mapped(ct3d->dc.host_dc, true);
+            if (ds->id) {
+                dc_name = g_strdup_printf("cxl-dcd-dpa-dc-space:%s", ds->id);
+            } else {
+                dc_name = g_strdup("cxl-dcd-dpa-dc-space");
+            }
+            address_space_init(&ct3d->dc.host_dc_as, dc_mr, dc_name);
+            g_free(dc_name);
         }
-        address_space_init(&ct3d->dc.host_dc_as, dc_mr, dc_name);
-        g_free(dc_name);
 
         if (!cxl_create_dc_regions(ct3d, errp)) {
             error_append_hint(errp, "setup DC regions failed");
@@ -1361,6 +1373,8 @@ static const Property ct3_props[] = {
     DEFINE_PROP_UINT8("num-dc-regions", CXLType3Dev, dc.num_regions, 0),
     DEFINE_PROP_LINK("volatile-dc-memdev", CXLType3Dev, dc.host_dc,
                      TYPE_MEMORY_BACKEND, HostMemoryBackend *),
+    DEFINE_PROP_SIZE("dc-regions-total-size", CXLType3Dev,
+                     dc.total_capacity_cmd, 0),
     DEFINE_PROP_PCIE_LINK_SPEED("x-speed", CXLType3Dev,
                                 speed, PCIE_LINK_SPEED_32),
     DEFINE_PROP_PCIE_LINK_WIDTH("x-width", CXLType3Dev,
@@ -2305,6 +2319,12 @@ static void qmp_cxl_process_dynamic_capacity_prescriptive(const char *path,
         return;
     }
 
+    if (dcd->dc.total_capacity_cmd) {
+        error_setg(errp,
+                   "dc-regions-total-size is set: extent add/release via QMP "
+                   "not yet supported without a backing device at init");
+        return;
+    }
 
     if (rid >= dcd->dc.num_regions) {
         error_setg(errp, "region id is too large");
diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h
index ba551fa5f9..630cf44e0e 100644
--- a/include/hw/cxl/cxl_device.h
+++ b/include/hw/cxl/cxl_device.h
@@ -785,6 +785,7 @@ struct CXLType3Dev {
          * memory region size.
          */
         uint64_t total_capacity; /* 256M aligned */
+        uint64_t total_capacity_cmd; /* 256M aligned */
         CXLDCExtentList extents;
         CXLDCExtentGroupList extents_pending;
         uint32_t total_extent_count;
-- 
2.50.1 (Apple Git-155)



  parent reply	other threads:[~2026-03-25 18:44 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-25 18:42 [QEMU PATCH 0/9] Application Specific Tagged Memory Support in CXL Type 3 Devices Alireza Sanaee via qemu development
2026-03-25 18:42 ` [PATCH 1/9] hw/mem: Add tag support to generic host memory backends Alireza Sanaee via qemu development
2026-03-26 10:42   ` Markus Armbruster
2026-03-26 11:29     ` Alireza Sanaee via qemu development
2026-03-26 13:01       ` Markus Armbruster
2026-03-26 13:04         ` Alireza Sanaee via qemu development
2026-03-25 18:42 ` Alireza Sanaee via qemu development [this message]
2026-03-25 18:42 ` [PATCH 3/9] hw/cxl: Hook up tagged host memory backends at runtime for DC extents Alireza Sanaee via qemu development
2026-03-25 18:42 ` [PATCH 4/9] hw/cxl: Carry backend metadata in DC extent records Alireza Sanaee via qemu development
2026-03-25 18:42 ` [PATCH 5/9] hw/cxl: Map lazy memory backend after host acceptance Alireza Sanaee via qemu development
2026-03-25 18:42 ` [PATCH 6/9] hw/cxl: Create direct fixed-window aliases for accepted extents Alireza Sanaee via qemu development
2026-03-25 18:42 ` [PATCH 7/9] hw/cxl: Add release-time teardown for direct-mapped extents Alireza Sanaee via qemu development
2026-03-25 18:42 ` [PATCH 8/9] hw/cxl: Add tag-based dynamic-capacity release support Alireza Sanaee via qemu development
2026-03-25 18:42 ` [PATCH 9/9] hw/cxl: Add QMP status query for dynamic-capacity extent release Alireza Sanaee via qemu development
2026-03-26 15:15   ` Markus Armbruster

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=20260325184259.366-3-alireza.sanaee@huawei.com \
    --to=qemu-devel@nongnu.org \
    --cc=alireza.sanaee@huawei.com \
    --cc=anisa.su@samsung.com \
    --cc=armbru@redhat.com \
    --cc=berrange@redhat.com \
    --cc=eblake@redhat.com \
    --cc=gourry@gourry.net \
    --cc=jonathan.cameron@huawei.com \
    --cc=linux-cxl@vger.kernel.org \
    --cc=linuxarm@huawei.com \
    --cc=lizhijian@fujitsu.com \
    --cc=me@linux.beauty \
    --cc=mst@redhat.com \
    --cc=nifan.cxl@gmail.com \
    --cc=pbonzini@redhat.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox