{"id":2216047,"url":"http://patchwork.ozlabs.org/api/patches/2216047/?format=json","web_url":"http://patchwork.ozlabs.org/project/qemu-devel/patch/20260325184259.366-3-alireza.sanaee@huawei.com/","project":{"id":14,"url":"http://patchwork.ozlabs.org/api/projects/14/?format=json","name":"QEMU Development","link_name":"qemu-devel","list_id":"qemu-devel.nongnu.org","list_email":"qemu-devel@nongnu.org","web_url":"","scm_url":"","webscm_url":"","list_archive_url":"","list_archive_url_format":"","commit_url_format":""},"msgid":"<20260325184259.366-3-alireza.sanaee@huawei.com>","list_archive_url":null,"date":"2026-03-25T18:42:50","name":"[2/9] hw/cxl: Allow initializing type3 device with no backing device","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"17a0395dea366d6b145df1fdb0f36fff2ddb970b","submitter":{"id":90159,"url":"http://patchwork.ozlabs.org/api/people/90159/?format=json","name":"Alireza Sanaee","email":"alireza.sanaee@huawei.com"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/qemu-devel/patch/20260325184259.366-3-alireza.sanaee@huawei.com/mbox/","series":[{"id":497484,"url":"http://patchwork.ozlabs.org/api/series/497484/?format=json","web_url":"http://patchwork.ozlabs.org/project/qemu-devel/list/?series=497484","date":"2026-03-25T18:42:48","name":"Application Specific Tagged Memory Support in CXL Type 3 Devices","version":1,"mbox":"http://patchwork.ozlabs.org/series/497484/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/2216047/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/2216047/checks/","tags":{},"related":[],"headers":{"Return-Path":"<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>","X-Original-To":"incoming@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming@legolas.ozlabs.org","Authentication-Results":"legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org\n (client-ip=209.51.188.17; helo=lists.gnu.org;\n envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n receiver=patchwork.ozlabs.org)","Received":["from lists.gnu.org (lists.gnu.org [209.51.188.17])\n\t(using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fgwmg3G5nz1y1K\n\tfor <incoming@patchwork.ozlabs.org>; Thu, 26 Mar 2026 05:44:19 +1100 (AEDT)","from localhost ([::1] helo=lists1p.gnu.org)\n\tby lists.gnu.org with esmtp (Exim 4.90_1)\n\t(envelope-from <qemu-devel-bounces@nongnu.org>)\n\tid 1w5TDE-0002Fg-Dn; Wed, 25 Mar 2026 14:44:16 -0400","from eggs.gnu.org ([2001:470:142:3::10])\n by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <alireza.sanaee@huawei.com>)\n id 1w5TDD-0002F1-6A\n for qemu-devel@nongnu.org; Wed, 25 Mar 2026 14:44:15 -0400","from frasgout.his.huawei.com ([185.176.79.56])\n by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <alireza.sanaee@huawei.com>)\n id 1w5TDA-0005xE-Jc\n for qemu-devel@nongnu.org; Wed, 25 Mar 2026 14:44:14 -0400","from mail.maildlp.com (unknown [172.18.224.150])\n by frasgout.his.huawei.com (SkyGuard) with ESMTPS id 4fgwlq03HMzHnGk0;\n Thu, 26 Mar 2026 02:43:35 +0800 (CST)","from dubpeml500005.china.huawei.com (unknown [7.214.145.207])\n by mail.maildlp.com (Postfix) with ESMTPS id CF7554056E;\n Thu, 26 Mar 2026 02:44:10 +0800 (CST)","from a2303103017.china.huawei.com (10.47.66.203) by\n dubpeml500005.china.huawei.com (7.214.145.207) with Microsoft SMTP Server\n (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id\n 15.2.1544.11; Wed, 25 Mar 2026 18:44:09 +0000"],"To":"<qemu-devel@nongnu.org>","CC":"<anisa.su@samsung.com>, <armbru@redhat.com>, <berrange@redhat.com>,\n <eblake@redhat.com>, <jonathan.cameron@huawei.com>,\n <linux-cxl@vger.kernel.org>, <linuxarm@huawei.com>, <lizhijian@fujitsu.com>,\n <mst@redhat.com>, <pbonzini@redhat.com>, <gourry@gourry.net>,\n <nifan.cxl@gmail.com>, <me@linux.beauty>","Subject":"[PATCH 2/9] hw/cxl: Allow initializing type3 device with no backing\n device","Date":"Wed, 25 Mar 2026 18:42:50 +0000","Message-ID":"<20260325184259.366-3-alireza.sanaee@huawei.com>","X-Mailer":"git-send-email 2.51.0.windows.2","In-Reply-To":"<20260325184259.366-1-alireza.sanaee@huawei.com>","References":"<20260325184259.366-1-alireza.sanaee@huawei.com>","MIME-Version":"1.0","Content-Transfer-Encoding":"8bit","Content-Type":"text/plain","X-Originating-IP":"[10.47.66.203]","X-ClientProxiedBy":"lhrpeml500011.china.huawei.com (7.191.174.215) To\n dubpeml500005.china.huawei.com (7.214.145.207)","Received-SPF":"pass client-ip=185.176.79.56;\n envelope-from=alireza.sanaee@huawei.com; helo=frasgout.his.huawei.com","X-Spam_score_int":"-41","X-Spam_score":"-4.2","X-Spam_bar":"----","X-Spam_report":"(-4.2 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3,\n RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001,\n RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001,\n SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no","X-Spam_action":"no action","X-BeenThere":"qemu-devel@nongnu.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"qemu development <qemu-devel.nongnu.org>","List-Unsubscribe":"<https://lists.nongnu.org/mailman/options/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=unsubscribe>","List-Archive":"<https://lists.nongnu.org/archive/html/qemu-devel>","List-Post":"<mailto:qemu-devel@nongnu.org>","List-Help":"<mailto:qemu-devel-request@nongnu.org?subject=help>","List-Subscribe":"<https://lists.nongnu.org/mailman/listinfo/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=subscribe>","Reply-to":"Alireza Sanaee <alireza.sanaee@huawei.com>","From":"Alireza Sanaee via qemu development <qemu-devel@nongnu.org>","Errors-To":"qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org","Sender":"qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org"},"content":"Add a dc-regions-total-size property that allows creating a CXL type3\ndevice with DC regions but without a backing memory device at init time. In\nDynamic Capacity scenarios, memory can show up asynchronously from\ndifferent resources (RAM, PMEM, file-backed).  For these cases, only the\ntotal DC size needs to be known upfront.\n\nWhen dc-regions-total-size is set (instead of volatile-dc-memdev), the\ndevice initializes DC regions using the specified total size but does not\nset up any backing memory. Any FMAPI or QMP command that attempts to add or\nrelease extents will fail with an error, since no backing device is\navailable yet. The runtime hookup of tagged memory backends will be added\nin a subsequent patch.\n\nSigned-off-by: Alireza Sanaee <alireza.sanaee@huawei.com>\n---\n hw/cxl/cxl-mailbox-utils.c  |  8 ++++\n hw/mem/cxl_type3.c          | 92 ++++++++++++++++++++++---------------\n include/hw/cxl/cxl_device.h |  1 +\n 3 files changed, 65 insertions(+), 36 deletions(-)","diff":"diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c\nindex c83b5f90d4..e6e136cf44 100644\n--- a/hw/cxl/cxl-mailbox-utils.c\n+++ b/hw/cxl/cxl-mailbox-utils.c\n@@ -4270,6 +4270,10 @@ static CXLRetCode cmd_fm_initiate_dc_add(const struct cxl_cmd *cmd,\n     CXLType3Dev *ct3d = CXL_TYPE3(cci->d);\n     int i, rc;\n \n+    if (ct3d->dc.total_capacity_cmd) {\n+        return CXL_MBOX_UNSUPPORTED;\n+    }\n+\n     switch (in->selection_policy) {\n         case CXL_EXTENT_SELECTION_POLICY_PRESCRIPTIVE: {\n             /* Adding extents exceeds device's extent tracking ability. */\n@@ -4357,6 +4361,10 @@ static CXLRetCode cmd_fm_initiate_dc_release(const struct cxl_cmd *cmd,\n     CXLType3Dev *ct3d = CXL_TYPE3(cci->d);\n     int i, rc;\n \n+    if (ct3d->dc.total_capacity_cmd) {\n+        return CXL_MBOX_UNSUPPORTED;\n+    }\n+\n     switch (in->flags & CXL_EXTENT_REMOVAL_POLICY_MASK) {\n         case CXL_EXTENT_REMOVAL_POLICY_PRESCRIPTIVE: {\n             CXLDCExtentList updated_list;\ndiff --git a/hw/mem/cxl_type3.c b/hw/mem/cxl_type3.c\nindex d9fc0bec8f..45fb6c55bc 100644\n--- a/hw/mem/cxl_type3.c\n+++ b/hw/mem/cxl_type3.c\n@@ -190,12 +190,15 @@ static int ct3_build_cdat_table(CDATSubHeader ***cdat_table, void *priv)\n     }\n \n     if (ct3d->dc.num_regions) {\n-        if (!ct3d->dc.host_dc) {\n-            return -EINVAL;\n-        }\n-        dc_mr = host_memory_backend_get_memory(ct3d->dc.host_dc);\n-        if (!dc_mr) {\n-            return -EINVAL;\n+        /* Only check if DC is static (has a backing device) */\n+        if (ct3d->dc.total_capacity_cmd == 0) {\n+            if (!ct3d->dc.host_dc) {\n+                return -EINVAL;\n+            }\n+            dc_mr = host_memory_backend_get_memory(ct3d->dc.host_dc);\n+            if (!dc_mr) {\n+                return -EINVAL;\n+            }\n         }\n         len += CT3_CDAT_NUM_ENTRIES * ct3d->dc.num_regions;\n     }\n@@ -216,7 +219,7 @@ static int ct3_build_cdat_table(CDATSubHeader ***cdat_table, void *priv)\n         cur_ent += CT3_CDAT_NUM_ENTRIES;\n     }\n \n-    if (dc_mr) {\n+    if (dc_mr || ct3d->dc.total_capacity_cmd) {\n         int i;\n         uint64_t region_base = vmr_size + pmr_size;\n \n@@ -651,8 +654,12 @@ static bool cxl_create_dc_regions(CXLType3Dev *ct3d, Error **errp)\n     MemoryRegion *mr;\n     uint64_t dc_size;\n \n-    mr = host_memory_backend_get_memory(ct3d->dc.host_dc);\n-    dc_size = memory_region_size(mr);\n+    if (ct3d->dc.total_capacity_cmd != 0) {\n+        dc_size = ct3d->dc.total_capacity_cmd;\n+    } else {\n+        mr = host_memory_backend_get_memory(ct3d->dc.host_dc);\n+        dc_size = memory_region_size(mr);\n+    }\n     region_len = DIV_ROUND_UP(dc_size, ct3d->dc.num_regions);\n \n     if (dc_size % (ct3d->dc.num_regions * CXL_CAPACITY_MULTIPLIER) != 0) {\n@@ -818,36 +825,41 @@ static bool cxl_setup_memory(CXLType3Dev *ct3d, Error **errp)\n         MemoryRegion *dc_mr;\n         char *dc_name;\n \n-        if (!ct3d->dc.host_dc) {\n-            error_setg(errp, \"dynamic capacity must have a backing device\");\n-            return false;\n-        }\n+        /* Only require backing device if total_capacity_cmd is zero */\n+        if (ct3d->dc.total_capacity_cmd == 0) {\n+            if (!ct3d->dc.host_dc) {\n+                error_setg(errp, \"dynamic capacity must have a backing device\");\n+                return false;\n+            }\n \n-        dc_mr = host_memory_backend_get_memory(ct3d->dc.host_dc);\n-        if (!dc_mr) {\n-            error_setg(errp, \"dynamic capacity must have a backing device\");\n-            return false;\n-        }\n+            dc_mr = host_memory_backend_get_memory(ct3d->dc.host_dc);\n+            if (!dc_mr) {\n+                error_setg(errp, \"dynamic capacity must have a backing device\");\n+                return false;\n+            }\n \n-        if (host_memory_backend_is_mapped(ct3d->dc.host_dc)) {\n-            error_setg(errp, \"memory backend %s can't be used multiple times.\",\n-               object_get_canonical_path_component(OBJECT(ct3d->dc.host_dc)));\n-            return false;\n-        }\n-        /*\n-         * Set DC regions as volatile for now, non-volatile support can\n-         * be added in the future if needed.\n-         */\n-        memory_region_set_nonvolatile(dc_mr, false);\n-        memory_region_set_enabled(dc_mr, true);\n-        host_memory_backend_set_mapped(ct3d->dc.host_dc, true);\n-        if (ds->id) {\n-            dc_name = g_strdup_printf(\"cxl-dcd-dpa-dc-space:%s\", ds->id);\n-        } else {\n-            dc_name = g_strdup(\"cxl-dcd-dpa-dc-space\");\n+            if (host_memory_backend_is_mapped(ct3d->dc.host_dc)) {\n+                error_setg(errp,\n+                           \"memory backend %s can't be used multiple times.\",\n+                           object_get_canonical_path_component(\n+                               OBJECT(ct3d->dc.host_dc)));\n+                return false;\n+            }\n+            /*\n+             * Set DC regions as volatile for now, non-volatile support can\n+             * be added in the future if needed.\n+             */\n+            memory_region_set_nonvolatile(dc_mr, false);\n+            memory_region_set_enabled(dc_mr, true);\n+            host_memory_backend_set_mapped(ct3d->dc.host_dc, true);\n+            if (ds->id) {\n+                dc_name = g_strdup_printf(\"cxl-dcd-dpa-dc-space:%s\", ds->id);\n+            } else {\n+                dc_name = g_strdup(\"cxl-dcd-dpa-dc-space\");\n+            }\n+            address_space_init(&ct3d->dc.host_dc_as, dc_mr, dc_name);\n+            g_free(dc_name);\n         }\n-        address_space_init(&ct3d->dc.host_dc_as, dc_mr, dc_name);\n-        g_free(dc_name);\n \n         if (!cxl_create_dc_regions(ct3d, errp)) {\n             error_append_hint(errp, \"setup DC regions failed\");\n@@ -1361,6 +1373,8 @@ static const Property ct3_props[] = {\n     DEFINE_PROP_UINT8(\"num-dc-regions\", CXLType3Dev, dc.num_regions, 0),\n     DEFINE_PROP_LINK(\"volatile-dc-memdev\", CXLType3Dev, dc.host_dc,\n                      TYPE_MEMORY_BACKEND, HostMemoryBackend *),\n+    DEFINE_PROP_SIZE(\"dc-regions-total-size\", CXLType3Dev,\n+                     dc.total_capacity_cmd, 0),\n     DEFINE_PROP_PCIE_LINK_SPEED(\"x-speed\", CXLType3Dev,\n                                 speed, PCIE_LINK_SPEED_32),\n     DEFINE_PROP_PCIE_LINK_WIDTH(\"x-width\", CXLType3Dev,\n@@ -2305,6 +2319,12 @@ static void qmp_cxl_process_dynamic_capacity_prescriptive(const char *path,\n         return;\n     }\n \n+    if (dcd->dc.total_capacity_cmd) {\n+        error_setg(errp,\n+                   \"dc-regions-total-size is set: extent add/release via QMP \"\n+                   \"not yet supported without a backing device at init\");\n+        return;\n+    }\n \n     if (rid >= dcd->dc.num_regions) {\n         error_setg(errp, \"region id is too large\");\ndiff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h\nindex ba551fa5f9..630cf44e0e 100644\n--- a/include/hw/cxl/cxl_device.h\n+++ b/include/hw/cxl/cxl_device.h\n@@ -785,6 +785,7 @@ struct CXLType3Dev {\n          * memory region size.\n          */\n         uint64_t total_capacity; /* 256M aligned */\n+        uint64_t total_capacity_cmd; /* 256M aligned */\n         CXLDCExtentList extents;\n         CXLDCExtentGroupList extents_pending;\n         uint32_t total_extent_count;\n","prefixes":["2/9"]}