From nobody Fri Apr 3 01:25:53 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1774464258; cv=none; d=zohomail.com; s=zohoarc; b=cJI366QU5xIXZ/6C+L1d4WjBMSKmujHDE/LexEPMHVMOEDvzfJDX5lX9ewy8AEyoKFAegI5ylsdhnkKWvchpt8N5VtbbLg910T9fJmMXFPDIOUuhraiuV6owcTbqtH1RVd5gJj5fiZzcjMxDl++MJqUR0ojO+EPmOOJBoDKdjwk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1774464258; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Sender:Subject:Subject:To:To:Message-Id; bh=/yz6BKIa6GfOLq7BMmwtxYgDrShXqFkwOH3hDGB5Jwk=; b=FG3faWWAgCyhDGLK94TIRkI1VhxfFXOr9yTUiHIobMwGIxk4fEcf1F9X8yS4lIWkj0N3q9uDm8qKVAbmBTMRmig9p8yW13kz7iWc3EnL/uBsul2UM7Z3PPGyHdvrpdZE778XrAdd3B4MKp1xo2wqGRRFNUVYoaAm1MSfKShFsjo= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1774464258395278.7713029299957; Wed, 25 Mar 2026 11:44:18 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w5TDE-0002Fg-Dn; Wed, 25 Mar 2026 14:44:16 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1w5TDD-0002F1-6A for qemu-devel@nongnu.org; Wed, 25 Mar 2026 14:44:15 -0400 Received: from frasgout.his.huawei.com ([185.176.79.56]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1w5TDA-0005xE-Jc for qemu-devel@nongnu.org; Wed, 25 Mar 2026 14:44:14 -0400 Received: from mail.maildlp.com (unknown [172.18.224.150]) by frasgout.his.huawei.com (SkyGuard) with ESMTPS id 4fgwlq03HMzHnGk0; Thu, 26 Mar 2026 02:43:35 +0800 (CST) Received: from dubpeml500005.china.huawei.com (unknown [7.214.145.207]) by mail.maildlp.com (Postfix) with ESMTPS id CF7554056E; Thu, 26 Mar 2026 02:44:10 +0800 (CST) Received: from a2303103017.china.huawei.com (10.47.66.203) by dubpeml500005.china.huawei.com (7.214.145.207) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.11; Wed, 25 Mar 2026 18:44:09 +0000 To: CC: , , , , , , , , , , , , Subject: [PATCH 2/9] hw/cxl: Allow initializing type3 device with no backing 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: quoted-printable X-Originating-IP: [10.47.66.203] X-ClientProxiedBy: lhrpeml500011.china.huawei.com (7.191.174.215) To dubpeml500005.china.huawei.com (7.214.145.207) Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=185.176.79.56; 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, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-to: Alireza Sanaee From: Alireza Sanaee via qemu development Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1774464259611158500 Content-Type: text/plain; charset="utf-8" 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 --- 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 struc= t cxl_cmd *cmd, CXLType3Dev *ct3d =3D CXL_TYPE3(cci->d); int i, rc; =20 + 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 s= truct cxl_cmd *cmd, CXLType3Dev *ct3d =3D CXL_TYPE3(cci->d); int i, rc; =20 + 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) } =20 if (ct3d->dc.num_regions) { - if (!ct3d->dc.host_dc) { - return -EINVAL; - } - dc_mr =3D 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 =3D=3D 0) { + if (!ct3d->dc.host_dc) { + return -EINVAL; + } + dc_mr =3D host_memory_backend_get_memory(ct3d->dc.host_dc); + if (!dc_mr) { + return -EINVAL; + } } len +=3D CT3_CDAT_NUM_ENTRIES * ct3d->dc.num_regions; } @@ -216,7 +219,7 @@ static int ct3_build_cdat_table(CDATSubHeader ***cdat_t= able, void *priv) cur_ent +=3D CT3_CDAT_NUM_ENTRIES; } =20 - if (dc_mr) { + if (dc_mr || ct3d->dc.total_capacity_cmd) { int i; uint64_t region_base =3D vmr_size + pmr_size; =20 @@ -651,8 +654,12 @@ static bool cxl_create_dc_regions(CXLType3Dev *ct3d, E= rror **errp) MemoryRegion *mr; uint64_t dc_size; =20 - mr =3D host_memory_backend_get_memory(ct3d->dc.host_dc); - dc_size =3D memory_region_size(mr); + if (ct3d->dc.total_capacity_cmd !=3D 0) { + dc_size =3D ct3d->dc.total_capacity_cmd; + } else { + mr =3D host_memory_backend_get_memory(ct3d->dc.host_dc); + dc_size =3D memory_region_size(mr); + } region_len =3D DIV_ROUND_UP(dc_size, ct3d->dc.num_regions); =20 if (dc_size % (ct3d->dc.num_regions * CXL_CAPACITY_MULTIPLIER) !=3D 0)= { @@ -818,36 +825,41 @@ static bool cxl_setup_memory(CXLType3Dev *ct3d, Error= **errp) MemoryRegion *dc_mr; char *dc_name; =20 - 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 =3D=3D 0) { + if (!ct3d->dc.host_dc) { + error_setg(errp, "dynamic capacity must have a backing dev= ice"); + return false; + } =20 - dc_mr =3D 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 =3D host_memory_backend_get_memory(ct3d->dc.host_dc); + if (!dc_mr) { + error_setg(errp, "dynamic capacity must have a backing dev= ice"); + return false; + } =20 - if (host_memory_backend_is_mapped(ct3d->dc.host_dc)) { - error_setg(errp, "memory backend %s can't be used multiple tim= es.", - 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 =3D g_strdup_printf("cxl-dcd-dpa-dc-space:%s", ds->id); - } else { - dc_name =3D 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 =3D g_strdup_printf("cxl-dcd-dpa-dc-space:%s", ds-= >id); + } else { + dc_name =3D 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); =20 if (!cxl_create_dc_regions(ct3d, errp)) { error_append_hint(errp, "setup DC regions failed"); @@ -1361,6 +1373,8 @@ static const Property ct3_props[] =3D { 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_prescri= ptive(const char *path, return; } =20 + if (dcd->dc.total_capacity_cmd) { + error_setg(errp, + "dc-regions-total-size is set: extent add/release via Q= MP " + "not yet supported without a backing device at init"); + return; + } =20 if (rid >=3D 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; --=20 2.50.1 (Apple Git-155)