From nobody Thu Apr 2 23:57:07 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=1774464263; cv=none; d=zohomail.com; s=zohoarc; b=W+vlOUfVGtX4k4PW2kpyLz7j7LCbUqXessPK2Vs0jmJtdkXdHMilNf1IE3njrtiK0UwJ4xtz24/5uFnt2qPAVZQCugbNrV1GCUu3l+/WCpZqzrvngsNI6oegKW6Xw60GIkJ4flqwJYb3KV15Vv0/CAVgLvElzn57K9pp05t+DCA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1774464263; 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=h9TbjHYYgC2QwQLSbj5EeHZfdaCvzceOMYGOaKMvWbk=; b=CFwXF+cVlemz63QCuUasWN9SWWLBQEfxEH9Ht2XFRkKDmGsg9CuVDMvwenJC7eKp+Eep0MOwoT8NNZ9YBPB24hitmMj8Rsg78j+spfxo5ZRzpxGoB0MuHrtfAvbg2Yrzp2Ci7NfWG5IypRh6y2F6nXY6Ciho0mWqfljzwHnzoJY= 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 177446426381843.01571181380996; Wed, 25 Mar 2026 11:44:23 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w5TCi-00026k-Kq; Wed, 25 Mar 2026 14:43:44 -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 1w5TCg-00026X-CZ for qemu-devel@nongnu.org; Wed, 25 Mar 2026 14:43:42 -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 1w5TCe-0005u5-E6 for qemu-devel@nongnu.org; Wed, 25 Mar 2026 14:43:42 -0400 Received: from mail.maildlp.com (unknown [172.18.224.83]) by frasgout.his.huawei.com (SkyGuard) with ESMTPS id 4fgwlB5KS0zHnGhl; Thu, 26 Mar 2026 02:43:02 +0800 (CST) Received: from dubpeml500005.china.huawei.com (unknown [7.214.145.207]) by mail.maildlp.com (Postfix) with ESMTPS id 8F53240086; Thu, 26 Mar 2026 02:43:38 +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:43:37 +0000 To: CC: , , , , , , , , , , , , Subject: [PATCH 1/9] hw/mem: Add tag support to generic host memory backends Date: Wed, 25 Mar 2026 18:42:49 +0000 Message-ID: <20260325184259.366-2-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: 1774464266809154100 Content-Type: text/plain; charset="utf-8" Add a string tag property to HostMemoryBackend so that backends can be identified by a user-assigned name at runtime. Expose the property through QOM and add a host_memory_backend_find_by_tag() helper that walks the object tree to locate a backend by its tag. This is used by the following CXL patches to resolve a named backend for a pending DC extent and attach it to the accepted extent when the host acknowledges the add request. Signed-off-by: Alireza Sanaee --- backends/hostmem.c | 72 ++++++++++++++++++++++++++++++++++++++++ include/system/hostmem.h | 2 ++ qapi/qom.json | 3 ++ tests/qtest/qom-test.c | 8 +++-- 4 files changed, 83 insertions(+), 2 deletions(-) diff --git a/backends/hostmem.c b/backends/hostmem.c index 15d4365b69..270cae9569 100644 --- a/backends/hostmem.c +++ b/backends/hostmem.c @@ -47,6 +47,50 @@ host_memory_backend_get_name(HostMemoryBackend *backend) return object_get_canonical_path(OBJECT(backend)); } =20 +typedef struct HostMemoryBackendTagSearch { + const char *tag; + HostMemoryBackend *backend; +} HostMemoryBackendTagSearch; + +static int host_memory_backend_find_by_tag_cb(Object *obj, void *opaque) +{ + HostMemoryBackendTagSearch *ctx =3D opaque; + HostMemoryBackend *backend; + + if (!object_dynamic_cast(obj, TYPE_MEMORY_BACKEND)) { + return 0; + } + + backend =3D MEMORY_BACKEND(obj); + if (!backend->tag) { + return 0; + } + + if (strcmp(backend->tag, ctx->tag) =3D=3D 0) { + ctx->backend =3D backend; + return 1; + } + + return 0; +} + +HostMemoryBackend *host_memory_backend_find_by_tag(const char *tag) +{ + HostMemoryBackendTagSearch ctx =3D { + .tag =3D tag, + .backend =3D NULL, + }; + + if (!tag) { + return NULL; + } + + object_child_foreach_recursive(object_get_objects_root(), + host_memory_backend_find_by_tag_cb, &ct= x); + + return ctx.backend; +} + static void host_memory_backend_get_size(Object *obj, Visitor *v, const char *name, void *opaque, Error **errp) @@ -460,6 +504,22 @@ static void host_memory_backend_set_share(Object *o, b= ool value, Error **errp) backend->share =3D value; } =20 +static void +host_memory_backend_set_tag(Object *obj, const char *value, Error **errp) +{ + HostMemoryBackend *backend =3D MEMORY_BACKEND(obj); + + g_free(backend->tag); + backend->tag =3D g_strdup(value); +} + +static char *host_memory_backend_get_tag(Object *obj, Error **errp) +{ + HostMemoryBackend *backend =3D MEMORY_BACKEND(obj); + + return g_strdup(backend->tag); +} + #ifdef CONFIG_LINUX static bool host_memory_backend_get_reserve(Object *o, Error **errp) { @@ -501,6 +561,13 @@ host_memory_backend_set_use_canonical_path(Object *obj= , bool value, backend->use_canonical_path =3D value; } =20 +static void host_memory_backend_finalize(Object *obj) +{ + HostMemoryBackend *backend =3D MEMORY_BACKEND(obj); + + g_free(backend->tag); +} + static void host_memory_backend_class_init(ObjectClass *oc, const void *data) { @@ -557,6 +624,10 @@ host_memory_backend_class_init(ObjectClass *oc, const = void *data) host_memory_backend_get_share, host_memory_backend_set_share); object_class_property_set_description(oc, "share", "Mark the memory as private to QEMU or shared"); + object_class_property_add_str(oc, "tag", + host_memory_backend_get_tag, host_memory_backend_set_tag); + object_class_property_set_description(oc, "tag", + "A user-defined tag to identify this memory backend"); #ifdef CONFIG_LINUX object_class_property_add_bool(oc, "reserve", host_memory_backend_get_reserve, host_memory_backend_set_reserve); @@ -586,6 +657,7 @@ static const TypeInfo host_memory_backend_info =3D { .class_init =3D host_memory_backend_class_init, .instance_size =3D sizeof(HostMemoryBackend), .instance_init =3D host_memory_backend_init, + .instance_finalize =3D host_memory_backend_finalize, .instance_post_init =3D host_memory_backend_post_init, .interfaces =3D (const InterfaceInfo[]) { { TYPE_USER_CREATABLE }, diff --git a/include/system/hostmem.h b/include/system/hostmem.h index 88fa791ac7..a02e173d48 100644 --- a/include/system/hostmem.h +++ b/include/system/hostmem.h @@ -81,12 +81,14 @@ struct HostMemoryBackend { ThreadContext *prealloc_context; DECLARE_BITMAP(host_nodes, MAX_NODES + 1); HostMemPolicy policy; + char *tag; =20 MemoryRegion mr; }; =20 bool host_memory_backend_mr_inited(HostMemoryBackend *backend); MemoryRegion *host_memory_backend_get_memory(HostMemoryBackend *backend); +HostMemoryBackend *host_memory_backend_find_by_tag(const char *tag); =20 void host_memory_backend_set_mapped(HostMemoryBackend *backend, bool mappe= d); bool host_memory_backend_is_mapped(HostMemoryBackend *backend); diff --git a/qapi/qom.json b/qapi/qom.json index c653248f85..e6feeb324a 100644 --- a/qapi/qom.json +++ b/qapi/qom.json @@ -658,6 +658,8 @@ # @reserve: if true, reserve swap space (or huge pages) if applicable # (default: true) (since 6.1) # +# @tag: user-defined memory backend tag (since 11.1) +# # @size: size of the memory region in bytes # # @x-use-canonical-path-for-ramblock-id: if true, the canonical path @@ -683,6 +685,7 @@ '*prealloc-context': 'str', '*share': 'bool', '*reserve': 'bool', + '*tag': 'str', 'size': 'size', '*x-use-canonical-path-for-ramblock-id': 'bool' } } =20 diff --git a/tests/qtest/qom-test.c b/tests/qtest/qom-test.c index 6421f2d9d9..3109b47cca 100644 --- a/tests/qtest/qom-test.c +++ b/tests/qtest/qom-test.c @@ -17,6 +17,7 @@ =20 #define RAM_NAME "node0" #define RAM_SIZE 65536 +#define RAM_TAG "ramtag0" =20 static int verbosity_level; =20 @@ -59,6 +60,8 @@ static void test_list_get_value(QTestState *qts) =20 } else if (!strcmp(prop_name, "size")) { g_assert_cmpint(qdict_get_int(prop, "value"), =3D=3D, RAM_SIZE= ); + } else if (!strcmp(prop_name, "tag")) { + g_assert_cmpstr(qdict_get_str(prop, "value"), =3D=3D, RAM_TAG); } } } @@ -195,8 +198,9 @@ static void test_machine(gconstpointer data) QTestState *qts; g_autoptr(QList) paths =3D qlist_new(); =20 - qts =3D qtest_initf("-machine %s -object memory-backend-ram,id=3D%s,si= ze=3D%d", - machine, RAM_NAME, RAM_SIZE); + qts =3D qtest_initf("-machine %s -object memory-backend-ram,id=3D%s,si= ze=3D%d" + ",tag=3D%s", + machine, RAM_NAME, RAM_SIZE, RAM_TAG); =20 if (g_test_slow()) { /* Make sure we can get the machine class properties: */ --=20 2.50.1 (Apple Git-155) From nobody Thu Apr 2 23:57:07 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) From nobody Thu Apr 2 23:57:07 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=1774464309; cv=none; d=zohomail.com; s=zohoarc; b=mcFmDjmmT/7smvsx2n5VKBgj/BEdIxApTAJVPk76tZjzdWSmWb3XOqGCg89/zsmS2WOoji58nKP4ndYSDWyld02zZADoBf+mtDFRjAQClKW5IeXiU/N03R8g5mEV1q5UO4qvTgRNaNSuA+GBKEVp0mTqLnrzLGrsZist0DX6wNs= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1774464309; 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=s3U0tmJK0T3QgyQD9Hu/O4IWBkLW44ZXZLV6X2p+Wlc=; b=k0rgSKW8piMr+J7QqehgZPaTt36w2mrZlB5Vl9BlXIwlRy6YdHI0K9OXt4ReBwIv9tkso6GH4k96oCxya88Wmy9ThtXl5XW6L4jfcQoI2WdbLU/++2OSyTwh0MzuOGoAw6CPsBwWgQlPQdiIgRnTTUCm4GIL1rDLnmGpxbtXG/s= 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 177446430983245.72680345195181; Wed, 25 Mar 2026 11:45:09 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w5TDp-0003Pb-Sz; Wed, 25 Mar 2026 14:44:53 -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 1w5TDn-0003P6-9g for qemu-devel@nongnu.org; Wed, 25 Mar 2026 14:44:51 -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 1w5TDl-0007Mw-Dl for qemu-devel@nongnu.org; Wed, 25 Mar 2026 14:44:51 -0400 Received: from mail.maildlp.com (unknown [172.18.224.150]) by frasgout.his.huawei.com (SkyGuard) with ESMTPS id 4fgwmW4qzZzHnGjr; Thu, 26 Mar 2026 02:44:11 +0800 (CST) Received: from dubpeml500005.china.huawei.com (unknown [7.214.145.207]) by mail.maildlp.com (Postfix) with ESMTPS id 7F6D74056B; Thu, 26 Mar 2026 02:44:47 +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:46 +0000 To: CC: , , , , , , , , , , , , Subject: [PATCH 3/9] hw/cxl: Hook up tagged host memory backends at runtime for DC extents Date: Wed, 25 Mar 2026 18:42:51 +0000 Message-ID: <20260325184259.366-4-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: 1774464313210154100 Content-Type: text/plain; charset="utf-8" When a type3 device is created with dc-regions-total-size instead of an initial volatile-dc-memdev, prescriptive DC add requests need a way to name the backend to attach to the accepted extent. Teach the QMP and mailbox paths to carry that tag through the lazy dynamic-capacity flow. In the add path, resolve the tag to a generic host memory backend, reject reuse of an already-mapped backend, and verify that the backend size matches the requested extent. Store the selected backend metadata on the pending extent so a later patch can bind the accepted extent to the chosen backend when the host acknowledges the request. Signed-off-by: Alireza Sanaee --- hw/cxl/cxl-mailbox-utils.c | 8 ---- hw/mem/cxl_type3.c | 77 ++++++++++++++++++++++++++++++++------ 2 files changed, 65 insertions(+), 20 deletions(-) diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c index e6e136cf44..c83b5f90d4 100644 --- a/hw/cxl/cxl-mailbox-utils.c +++ b/hw/cxl/cxl-mailbox-utils.c @@ -4270,10 +4270,6 @@ 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. */ @@ -4361,10 +4357,6 @@ 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 45fb6c55bc..569184975f 100644 --- a/hw/mem/cxl_type3.c +++ b/hw/mem/cxl_type3.c @@ -30,6 +30,7 @@ #include "system/numa.h" #include "hw/cxl/cxl.h" #include "hw/pci/msix.h" +#include "qemu/uuid.h" =20 /* type3 device private */ enum CXL_T3_MSIX_VECTOR { @@ -2289,13 +2290,42 @@ bool cxl_extent_groups_overlaps_dpa_range(CXLDCExte= ntGroupList *list, return false; } =20 +static bool cxl_device_lazy_dynamic_capacity_init(CXLType3Dev *ct3d, + const char *tag, + Error **errp) +{ + MemoryRegion *dc_mr; + + ct3d->dc.host_dc =3D host_memory_backend_find_by_tag(tag); + if (!ct3d->dc.host_dc) { + 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 device"); + return false; + } + + if (host_memory_backend_is_mapped(ct3d->dc.host_dc)) { + error_setg(errp, + "memory backend %s is already mapped and cannot be reus= ed", + object_get_canonical_path_component( + OBJECT(ct3d->dc.host_dc))); + return false; + } + + return true; +} + /* * The main function to process dynamic capacity event with extent list. * Currently DC extents add/release requests are processed. */ static void qmp_cxl_process_dynamic_capacity_prescriptive(const char *path, uint16_t hid, CXLDCEventType type, uint8_t rid, - CxlDynamicCapacityExtentList *records, Error **errp) + const char *tag, CxlDynamicCapacityExtentList *records, Error **er= rp) { Object *obj; CXLType3Dev *dcd; @@ -2303,7 +2333,8 @@ static void qmp_cxl_process_dynamic_capacity_prescrip= tive(const char *path, CxlDynamicCapacityExtentList *list; CXLDCExtentGroup *group =3D NULL; g_autofree CXLDCExtentRaw *extents =3D NULL; - uint64_t dpa, offset, len, block_size; + uint64_t dpa, offset, block_size; + uint64_t len =3D 0; g_autofree unsigned long *blk_bitmap =3D NULL; int i; =20 @@ -2319,13 +2350,6 @@ 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; - } - if (rid >=3D dcd->dc.num_regions) { error_setg(errp, "region id is too large"); return; @@ -2334,6 +2358,8 @@ static void qmp_cxl_process_dynamic_capacity_prescrip= tive(const char *path, blk_bitmap =3D bitmap_new(dcd->dc.regions[rid].len / block_size); =20 /* Sanity check and count the extents */ + QemuUUID uuid; + qemu_uuid_parse(tag, &uuid); list =3D records; while (list) { offset =3D list->value->offset; @@ -2392,6 +2418,31 @@ static void qmp_cxl_process_dynamic_capacity_prescri= ptive(const char *path, num_extents++; } =20 + if (type =3D=3D DC_EVENT_ADD_CAPACITY && dcd->dc.total_capacity_cmd) { + MemoryRegion *host_dc_mr; + uint64_t size; + + if (num_extents > 1) { + error_setg(errp, "Only single extent add is supported currentl= y"); + return; + } + + if (!cxl_device_lazy_dynamic_capacity_init(dcd, tag, errp)) { + return; + } + + host_dc_mr =3D host_memory_backend_get_memory(dcd->dc.host_dc); + size =3D memory_region_size(host_dc_mr); + + if (size !=3D len) { + error_setg(errp, + "Host memory backend size 0x%" PRIx64 + " does not match extent length 0x%" PRIx64, + size, len); + return; + } + } + /* Create extent list for event being passed to host */ i =3D 0; list =3D records; @@ -2403,7 +2454,7 @@ static void qmp_cxl_process_dynamic_capacity_prescrip= tive(const char *path, =20 extents[i].start_dpa =3D dpa; extents[i].len =3D len; - memset(extents[i].tag, 0, 0x10); + memcpy(extents[i].tag, &uuid.data, 0x10); extents[i].shared_seq =3D 0; if (type =3D=3D DC_EVENT_ADD_CAPACITY) { group =3D cxl_insert_extent_to_extent_group(group, @@ -2434,7 +2485,8 @@ void qmp_cxl_add_dynamic_capacity(const char *path, u= int16_t host_id, case CXL_EXTENT_SELECTION_POLICY_PRESCRIPTIVE: qmp_cxl_process_dynamic_capacity_prescriptive(path, host_id, DC_EVENT_ADD_CAPACIT= Y, - region, extents, err= p); + region, tag, + extents, errp); return; default: error_setg(errp, "Selection policy not supported"); @@ -2465,7 +2517,8 @@ void qmp_cxl_release_dynamic_capacity(const char *pat= h, uint16_t host_id, switch (removal_policy) { case CXL_EXTENT_REMOVAL_POLICY_PRESCRIPTIVE: qmp_cxl_process_dynamic_capacity_prescriptive(path, host_id, type, - region, extents, err= p); + region, tag, + extents, errp); return; default: error_setg(errp, "Removal policy not supported"); --=20 2.50.1 (Apple Git-155) From nobody Thu Apr 2 23:57:07 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=1774464333; cv=none; d=zohomail.com; s=zohoarc; b=c+eFhxaDfH9UzXFG5vCvgHVkOaIBRq3YAirOPn+OV3EZD2zWxOWD7r3elmKk3Qu3ncfm50qor2cVk0fvUnYb4S6HS7XsbKAFD6uwuBt6XsvwMdhm7S+cONZXNUp6pDPGft/AqzH/BQqTkL/vnbOnQR6ahAkSSZM054lM6g6gYLw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1774464333; 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=jKrclZyG+9k8U2wn71XfDIx+0DJ/mpdbFOspV6ZVP68=; b=FHMqm8uvltFhhl25BPiSKpN7/GKJ9lkYi940LI1t+606tJ8SP2mmTLWYk5P1nUcyziaVgKO6CPTImYxVwNVB2DsCHzTwN/h4A/0OwEmkggs6tIl6dvc1mpGfuSETkY6+0wwsFunWZTMJR339Ptsl8yA3OxCK5WYjjXYzeNjmwH4= 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 177446433337482.94406421334395; Wed, 25 Mar 2026 11:45:33 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w5TEM-0003ti-7a; Wed, 25 Mar 2026 14:45:26 -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 1w5TEK-0003tO-8g for qemu-devel@nongnu.org; Wed, 25 Mar 2026 14:45:24 -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 1w5TEI-000804-00 for qemu-devel@nongnu.org; Wed, 25 Mar 2026 14:45:23 -0400 Received: from mail.maildlp.com (unknown [172.18.224.107]) by frasgout.his.huawei.com (SkyGuard) with ESMTPS id 4fgwn86D3YzHnGdQ; Thu, 26 Mar 2026 02:44:44 +0800 (CST) Received: from dubpeml500005.china.huawei.com (unknown [7.214.145.207]) by mail.maildlp.com (Postfix) with ESMTPS id ADC8A40587; Thu, 26 Mar 2026 02:45:20 +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:45:19 +0000 To: CC: , , , , , , , , , , , , Subject: [PATCH 4/9] hw/cxl: Carry backend metadata in DC extent records Date: Wed, 25 Mar 2026 18:42:52 +0000 Message-ID: <20260325184259.366-5-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: 1774464336133158500 Content-Type: text/plain; charset="utf-8" The lazy dc-regions-total-size flow needs more than DPA and length for each pending or committed extent. Later stages need to remember which backend was selected for the extent, which fixed window owns the mapping, and which region/offset the request came from. Extend CXLDCExtent and the helper APIs so add, copy, and release paths can carry that metadata alongside the range information. This is preparatory plumbing for the patches that map accepted extents into the fixed window and tear them down on release. Signed-off-by: Alireza Sanaee --- hw/cxl/cxl-mailbox-utils.c | 45 ++++++++++++++++++++++++++----------- hw/mem/cxl_type3.c | 23 ++++++++++++++----- include/hw/cxl/cxl_device.h | 21 +++++++++++++---- 3 files changed, 67 insertions(+), 22 deletions(-) diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c index c83b5f90d4..c5427adb3a 100644 --- a/hw/cxl/cxl-mailbox-utils.c +++ b/hw/cxl/cxl-mailbox-utils.c @@ -3525,20 +3525,26 @@ CXLDCRegion *cxl_find_dc_region(CXLType3Dev *ct3d, = uint64_t dpa, uint64_t len) } =20 void cxl_insert_extent_to_extent_list(CXLDCExtentList *list, + HostMemoryBackend *hm, + struct CXLFixedWindow *fw, uint64_t dpa, uint64_t len, uint8_t *tag, - uint16_t shared_seq) + uint16_t shared_seq, + int rid) { CXLDCExtent *extent; =20 extent =3D g_new0(CXLDCExtent, 1); + extent->hm =3D hm; + extent->fw =3D fw; extent->start_dpa =3D dpa; extent->len =3D len; if (tag) { memcpy(extent->tag, tag, 0x10); } extent->shared_seq =3D shared_seq; + extent->rid =3D rid; =20 QTAILQ_INSERT_TAIL(list, extent, node); } @@ -3556,17 +3562,21 @@ void cxl_remove_extent_from_extent_list(CXLDCExtent= List *list, * Return value: the extent group where the extent is inserted. */ CXLDCExtentGroup *cxl_insert_extent_to_extent_group(CXLDCExtentGroup *grou= p, + HostMemoryBackend *hos= t_mem, + struct CXLFixedWindow = *fw, uint64_t dpa, uint64_t len, uint8_t *tag, - uint16_t shared_seq) + uint16_t shared_seq, + int rid) { if (!group) { group =3D g_new0(CXLDCExtentGroup, 1); QTAILQ_INIT(&group->list); } - cxl_insert_extent_to_extent_list(&group->list, dpa, len, - tag, shared_seq); + cxl_insert_extent_to_extent_list(&group->list, + host_mem, fw, dpa, len, + tag, shared_seq, rid); return group; } =20 @@ -3747,7 +3757,9 @@ static CXLRetCode cmd_dcd_add_dyn_cap_rsp(const struc= t cxl_cmd *cmd, dpa =3D in->updated_entries[i].start_dpa; len =3D in->updated_entries[i].len; =20 - cxl_insert_extent_to_extent_list(extent_list, dpa, len, NULL, 0); + cxl_insert_extent_to_extent_list(extent_list, + NULL, NULL, dpa, len, + NULL, 0, 0); ct3d->dc.total_extent_count +=3D 1; ct3d->dc.nr_extents_accepted +=3D 1; ct3_set_region_block_backed(ct3d, dpa, len); @@ -3774,8 +3786,11 @@ static uint32_t copy_extent_list(CXLDCExtentList *ds= t, } =20 QTAILQ_FOREACH(ent, src, node) { - cxl_insert_extent_to_extent_list(dst, ent->start_dpa, ent->len, - ent->tag, ent->shared_seq); + cxl_insert_extent_to_extent_list(dst, + ent->hm, ent->fw, + ent->start_dpa, ent->len, + ent->tag, ent->shared_seq, + ent->rid); cnt++; } return cnt; @@ -3830,14 +3845,16 @@ static CXLRetCode cxl_dc_extent_release_dry_run(CXL= Type3Dev *ct3d, =20 if (len1) { cxl_insert_extent_to_extent_list(updated_list, - ent_start_dpa, - len1, NULL, 0); + NULL, NULL, + ent_start_dpa, le= n1, + NULL, 0, ent->rid= ); cnt_delta++; } if (len2) { cxl_insert_extent_to_extent_list(updated_list, - dpa + len, - len2, NULL, 0); + NULL, NULL, + dpa + len, len2, + NULL, 0, ent->rid= ); cnt_delta++; } =20 @@ -4310,9 +4327,11 @@ static CXLRetCode cmd_fm_initiate_dc_add(const struc= t cxl_cmd *cmd, for (i =3D 0; i < in->ext_count; i++) { CXLDCExtentRaw *ext =3D &in->extents[i]; =20 - group =3D cxl_insert_extent_to_extent_group(group, ext->st= art_dpa, + group =3D cxl_insert_extent_to_extent_group(group, + NULL, NULL, + ext->start_dpa, ext->len, ext->t= ag, - ext->shared_seq); + ext->shared_seq,= 0); } =20 cxl_extent_group_list_insert_tail(&ct3d->dc.extents_pending, g= roup); diff --git a/hw/mem/cxl_type3.c b/hw/mem/cxl_type3.c index 569184975f..bd32532c7a 100644 --- a/hw/mem/cxl_type3.c +++ b/hw/mem/cxl_type3.c @@ -2457,11 +2457,24 @@ static void qmp_cxl_process_dynamic_capacity_prescr= iptive(const char *path, memcpy(extents[i].tag, &uuid.data, 0x10); extents[i].shared_seq =3D 0; if (type =3D=3D DC_EVENT_ADD_CAPACITY) { - group =3D cxl_insert_extent_to_extent_group(group, - extents[i].start_dpa, - extents[i].len, - extents[i].tag, - extents[i].shared_se= q); + if (!dcd->dc.total_capacity_cmd) { + group =3D cxl_insert_extent_to_extent_group(group, + NULL, NULL, + extents[i].start= _dpa, + extents[i].len, + extents[i].tag, + extents[i].share= d_seq, + rid); + } else { + group =3D cxl_insert_extent_to_extent_group(group, + dcd->dc.host_dc, + dcd->dc.fw, + extents[i].start= _dpa, + extents[i].len, + extents[i].tag, + extents[i].share= d_seq, + rid); + } } =20 list =3D list->next; diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h index 630cf44e0e..a84b8ab358 100644 --- a/include/hw/cxl/cxl_device.h +++ b/include/hw/cxl/cxl_device.h @@ -10,6 +10,7 @@ #ifndef CXL_DEVICE_H #define CXL_DEVICE_H =20 +#include "hw/cxl/cxl.h" #include "hw/cxl/cxl_component.h" #include "hw/pci/pci_device.h" #include "hw/core/register.h" @@ -643,11 +644,14 @@ typedef struct CXLDCExtentRaw { } QEMU_PACKED CXLDCExtentRaw; =20 typedef struct CXLDCExtent { + HostMemoryBackend *hm; + struct CXLFixedWindow *fw; uint64_t start_dpa; uint64_t len; uint8_t tag[0x10]; uint16_t shared_seq; uint8_t rsvd[0x6]; + int rid; =20 QTAILQ_ENTRY(CXLDCExtent) node; } CXLDCExtent; @@ -780,6 +784,7 @@ struct CXLType3Dev { struct dynamic_capacity { HostMemoryBackend *host_dc; AddressSpace host_dc_as; + struct CXLFixedWindow *fw; /* * total_capacity is equivalent to the dynamic capability * memory region size. @@ -854,18 +859,26 @@ CXLDCRegion *cxl_find_dc_region(CXLType3Dev *ct3d, ui= nt64_t dpa, uint64_t len); =20 void cxl_remove_extent_from_extent_list(CXLDCExtentList *list, CXLDCExtent *extent); -void cxl_insert_extent_to_extent_list(CXLDCExtentList *list, uint64_t dpa, - uint64_t len, uint8_t *tag, - uint16_t shared_seq); +void cxl_insert_extent_to_extent_list(CXLDCExtentList *list, + HostMemoryBackend *hm, + struct CXLFixedWindow *fw, + uint64_t dpa, + uint64_t len, + uint8_t *tag, + uint16_t shared_seq, + int rid); bool test_any_bits_set(const unsigned long *addr, unsigned long nr, unsigned long size); bool cxl_extents_contains_dpa_range(CXLDCExtentList *list, uint64_t dpa, uint64_t len); CXLDCExtentGroup *cxl_insert_extent_to_extent_group(CXLDCExtentGroup *grou= p, + HostMemoryBackend *hos= t_mem, + struct CXLFixedWindow = *fw, uint64_t dpa, uint64_t len, uint8_t *tag, - uint16_t shared_seq); + uint16_t shared_seq, + int rid); void cxl_extent_group_list_insert_tail(CXLDCExtentGroupList *list, CXLDCExtentGroup *group); uint32_t cxl_extent_group_list_delete_front(CXLDCExtentGroupList *list); --=20 2.50.1 (Apple Git-155) From nobody Thu Apr 2 23:57:07 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=1774464399; cv=none; d=zohomail.com; s=zohoarc; b=WW3RkDebIO6NdI9G7oLy8ON+NkzfDslZtPM4eIgKlFW4/b+ZX7Db6F6584rSzwo3qtkIPvGr0qjcinTtngVNe2HssxucCSMIO3+ZxfXxmVRtGYHLT3P5Up6kBRUrwzcrPTEglfNpEwwC349V7LXxo9KC6tLpX/TRR5JOL4dBgnI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1774464399; 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=iMOcB1E/CaH6zgfZCMb2qU41U3RqXQkxvRaYwbmDJdE=; b=cn/g658giRPe/pbE6Gq8E26gyZapEEFQhcDevy0cyyHxLajO1KaZ0Fr75QEF4iq5d4o/koI45TU2Zr4OMIoEoBpKEnk9Wu/3hywxtImq56ftKnBPV+AHZVS1LlZ90So5bBpuVaUUm3+rgaG9KDv9DoIgFuN6OIKmxb1f2zw/8FA= 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 1774464399384986.9284057723147; Wed, 25 Mar 2026 11:46:39 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w5TFA-0004Mr-Us; Wed, 25 Mar 2026 14:46: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 1w5TEx-0004A4-9j for qemu-devel@nongnu.org; Wed, 25 Mar 2026 14:46:05 -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 1w5TEu-00083H-Mo for qemu-devel@nongnu.org; Wed, 25 Mar 2026 14:46:02 -0400 Received: from mail.maildlp.com (unknown [172.18.224.107]) by frasgout.his.huawei.com (SkyGuard) with ESMTPS id 4fgwnn6sp4zHnGjr; Thu, 26 Mar 2026 02:45:17 +0800 (CST) Received: from dubpeml500005.china.huawei.com (unknown [7.214.145.207]) by mail.maildlp.com (Postfix) with ESMTPS id C5BF540584; Thu, 26 Mar 2026 02:45:53 +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:45:52 +0000 To: CC: , , , , , , , , , , , , Subject: [PATCH 5/9] hw/cxl: Map lazy memory backend after host acceptance Date: Wed, 25 Mar 2026 18:42:53 +0000 Message-ID: <20260325184259.366-6-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: 1774464402312154100 Content-Type: text/plain; charset="utf-8" In the dc-regions-total-size flow, a requested extent is not backed when it is queued. It becomes usable only after the host accepts it with Add Dynamic Capacity Response. Use that response path to look up the first pending group's metadata for each accepted extent, enable the selected host backend, and move the backend and fixed-window references onto the committed extent list. The accepted range is then marked backed just like the non-lazy path. This wires host acceptance to the lazy backend lifecycle and leaves the fixed-window direct aliasing to the following patch. Signed-off-by: Alireza Sanaee --- hw/cxl/cxl-mailbox-utils.c | 76 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 73 insertions(+), 3 deletions(-) diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c index c5427adb3a..cc7be6e68c 100644 --- a/hw/cxl/cxl-mailbox-utils.c +++ b/hw/cxl/cxl-mailbox-utils.c @@ -3668,6 +3668,28 @@ static CXLRetCode cxl_detect_malformed_extent_list(C= XLType3Dev *ct3d, return CXL_MBOX_SUCCESS; } =20 +/* Find extent details (backend, window, tag, rid) in the first pending gr= oup */ +static bool cxl_extent_find_extent_detail(CXLDCExtentGroupList *list, + uint64_t start_dpa, uint64_t len, + uint8_t *tag, HostMemoryBackend = **hmb, + struct CXLFixedWindow **fw, int = *rid) +{ + CXLDCExtent *ent; + CXLDCExtentGroup *group =3D QTAILQ_FIRST(list); + + QTAILQ_FOREACH(ent, &group->list, node) { + if (ent->start_dpa =3D=3D start_dpa && ent->len =3D=3D len) { + *fw =3D ent->fw; + *hmb =3D ent->hm; + memcpy(tag, ent->tag, 0x10); + *rid =3D ent->rid; + return true; + } + } + + return false; +} + static CXLRetCode cxl_dcd_add_dyn_cap_rsp_dry_run(CXLType3Dev *ct3d, const CXLUpdateDCExtentListInPl *in) { @@ -3718,8 +3740,12 @@ static CXLRetCode cmd_dcd_add_dyn_cap_rsp(const stru= ct cxl_cmd *cmd, CXLUpdateDCExtentListInPl *in =3D (void *)payload_in; CXLType3Dev *ct3d =3D CXL_TYPE3(cci->d); CXLDCExtentList *extent_list =3D &ct3d->dc.extents; + struct CXLFixedWindow *fw; + HostMemoryBackend *hmb_dc; + uint8_t tag[0x10]; uint32_t i, num; uint64_t dpa, len; + int rid; CXLRetCode ret; =20 if (len_in < sizeof(*in)) { @@ -3756,10 +3782,54 @@ static CXLRetCode cmd_dcd_add_dyn_cap_rsp(const str= uct cxl_cmd *cmd, for (i =3D 0; i < in->num_entries_updated; i++) { dpa =3D in->updated_entries[i].start_dpa; len =3D in->updated_entries[i].len; + if (ct3d->dc.total_capacity_cmd) { + bool found; + MemoryRegion *mr; + + found =3D cxl_extent_find_extent_detail(&ct3d->dc.extents_pend= ing, + dpa, len, tag, + &hmb_dc, &fw, &rid); + + /* + * Host accepted an extent where device lacks details including + * wrong DPA or wrong length. + */ + if (!found) { + qemu_log_mask(LOG_GUEST_ERROR, + "Could not find the extent detail for DPA 0x= %" + PRIx64 " LEN 0x%" PRIx64 "\n", dpa, len); + return CXL_MBOX_INVALID_PA; + } + + /* The host memory backend should not be already mapped */ + if (host_memory_backend_is_mapped(hmb_dc)) { + qemu_log_mask(LOG_GUEST_ERROR, + "The host memory backend for DPA 0x%" PRIx64 + " LEN 0x%" PRIx64 " is already mapped\n", + dpa, len); + return CXL_MBOX_INVALID_PA; + } =20 - cxl_insert_extent_to_extent_list(extent_list, - NULL, NULL, dpa, len, - NULL, 0, 0); + mr =3D host_memory_backend_get_memory(hmb_dc); + if (!mr) { + qemu_log_mask(LOG_GUEST_ERROR, + "Could not get memory region from " + "host memory backend\n"); + return CXL_MBOX_INVALID_PA; + } + + memory_region_set_nonvolatile(mr, false); + memory_region_set_enabled(mr, true); + host_memory_backend_set_mapped(hmb_dc, true); + + cxl_insert_extent_to_extent_list(extent_list, + hmb_dc, fw, dpa, len, + NULL, 0, rid); + } else { + cxl_insert_extent_to_extent_list(extent_list, + NULL, NULL, dpa, len, + NULL, 0, -1); + } ct3d->dc.total_extent_count +=3D 1; ct3d->dc.nr_extents_accepted +=3D 1; ct3_set_region_block_backed(ct3d, dpa, len); --=20 2.50.1 (Apple Git-155) From nobody Thu Apr 2 23:57:07 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=1774464399; cv=none; d=zohomail.com; s=zohoarc; b=eXqUFWHm6QQmS2QTFg83wPcA6x3r3D8DCIMuMTTnQrDCgMZ8L/8mF0ggzs5tmnh4ktB1dyo3kBsKchBQ5yiyOyo0NH2yAUIBrWMxcUv1KaFjAhuCEqftTtx4acSqJi7UQkd+ReKDb67ezXMgCBzH7GMNZeGADozMXQRW3kOgfI8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1774464399; 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=qMDbirI+NpYD8n6zJwGiCFaH03SCZUG3odDkozs9owE=; b=a5Vd+M4P+LKlwL0n8wc70RTMj+7+sAIy3PCPfDTZUpFKxaqgsvLLF+I1TVN94g7Ok51kiGzmyDE7eEjqMSPOckHEOUB73xHJ0g5mLc86OoVsz99iR/UKSgZdU7yGsLtci6hS8Enu/ZOUZPLh3h9X7c0yKoCn+fU7qUBIN1DJsWA= 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 1774464399765665.7674982787697; Wed, 25 Mar 2026 11:46:39 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w5TFP-0004kk-EE; Wed, 25 Mar 2026 14:46:31 -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 1w5TFN-0004ew-SB for qemu-devel@nongnu.org; Wed, 25 Mar 2026 14:46:29 -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 1w5TFL-00086t-Na for qemu-devel@nongnu.org; Wed, 25 Mar 2026 14:46:29 -0400 Received: from mail.maildlp.com (unknown [172.18.224.107]) by frasgout.his.huawei.com (SkyGuard) with ESMTPS id 4fgwpQ3lhYzHnGdQ; Thu, 26 Mar 2026 02:45:50 +0800 (CST) Received: from dubpeml500005.china.huawei.com (unknown [7.214.145.207]) by mail.maildlp.com (Postfix) with ESMTPS id 5A88740584; Thu, 26 Mar 2026 02:46:26 +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:46:25 +0000 To: CC: , , , , , , , , , , , , Subject: [PATCH 6/9] hw/cxl: Create direct fixed-window aliases for accepted extents Date: Wed, 25 Mar 2026 18:42:54 +0000 Message-ID: <20260325184259.366-7-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: 1774464400402158500 Content-Type: text/plain; charset="utf-8" For devices using dc-regions-total-size, the fallback read/write path still routes through host_dc_as, but accepted extents are backed by individual host memory backends rather than a single preconfigured address space. Install aliases into the owning fixed window so accepted dynamic-capacity memory is reachable through the normal CXL decoder path. Record the non-interleaved decoder window discovered during HDM setup, reserve per-device alias slots for lazy DC extents, and create an alias from the accepted backend into that window when Add Dynamic Capacity Response commits the extent. This is scoped to the current non-interleaved direct-mapping model and uses a small fixed pool of alias slots for now. Signed-off-by: Alireza Sanaee --- hw/cxl/cxl-host.c | 6 ++++ hw/cxl/cxl-mailbox-utils.c | 61 +++++++++++++++++++++++++++++-------- hw/mem/cxl_type3.c | 6 ++-- include/hw/cxl/cxl_device.h | 18 +++++++++-- 4 files changed, 75 insertions(+), 16 deletions(-) diff --git a/hw/cxl/cxl-host.c b/hw/cxl/cxl-host.c index 079b27133b..4647754cc9 100644 --- a/hw/cxl/cxl-host.c +++ b/hw/cxl/cxl-host.c @@ -300,6 +300,7 @@ static void cxl_fmws_direct_passthrough_setup(CXLDirect= PTState *state, offset =3D state->dpa_base - vmr_size; } } + if (!mr) { return; } @@ -358,10 +359,15 @@ static int cxl_fmws_direct_passthrough(Object *obj, v= oid *opaque) =20 /* Verify not interleaved */ if (!cxl_cfmws_find_device(fw, state->decoder_base, false)) { + state->ct3d->direct_mr_enabled =3D false; return 0; } + state->ct3d->direct_mr_enabled =3D true; =20 cxl_fmws_direct_passthrough_setup(state, fw); + state->ct3d->dc.fw =3D fw; + state->ct3d->dc.dc_decoder_window.base =3D state->decoder_base; + state->ct3d->dc.dc_decoder_window.size =3D state->decoder_size; =20 return 0; } diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c index cc7be6e68c..4684c33ba1 100644 --- a/hw/cxl/cxl-mailbox-utils.c +++ b/hw/cxl/cxl-mailbox-utils.c @@ -3531,7 +3531,8 @@ void cxl_insert_extent_to_extent_list(CXLDCExtentList= *list, uint64_t len, uint8_t *tag, uint16_t shared_seq, - int rid) + int rid, + uint64_t offset) { CXLDCExtent *extent; =20 @@ -3540,6 +3541,7 @@ void cxl_insert_extent_to_extent_list(CXLDCExtentList= *list, extent->fw =3D fw; extent->start_dpa =3D dpa; extent->len =3D len; + extent->offset =3D offset; if (tag) { memcpy(extent->tag, tag, 0x10); } @@ -3568,7 +3570,8 @@ CXLDCExtentGroup *cxl_insert_extent_to_extent_group(C= XLDCExtentGroup *group, uint64_t len, uint8_t *tag, uint16_t shared_seq, - int rid) + int rid, + uint64_t offset) { if (!group) { group =3D g_new0(CXLDCExtentGroup, 1); @@ -3576,7 +3579,7 @@ CXLDCExtentGroup *cxl_insert_extent_to_extent_group(C= XLDCExtentGroup *group, } cxl_insert_extent_to_extent_list(&group->list, host_mem, fw, dpa, len, - tag, shared_seq, rid); + tag, shared_seq, rid, offset); return group; } =20 @@ -3672,7 +3675,8 @@ static CXLRetCode cxl_detect_malformed_extent_list(CX= LType3Dev *ct3d, static bool cxl_extent_find_extent_detail(CXLDCExtentGroupList *list, uint64_t start_dpa, uint64_t len, uint8_t *tag, HostMemoryBackend = **hmb, - struct CXLFixedWindow **fw, int = *rid) + struct CXLFixedWindow **fw, int = *rid, + uint64_t *offset) { CXLDCExtent *ent; CXLDCExtentGroup *group =3D QTAILQ_FIRST(list); @@ -3683,6 +3687,7 @@ static bool cxl_extent_find_extent_detail(CXLDCExtent= GroupList *list, *hmb =3D ent->hm; memcpy(tag, ent->tag, 0x10); *rid =3D ent->rid; + *offset =3D ent->offset; return true; } } @@ -3744,7 +3749,7 @@ static CXLRetCode cmd_dcd_add_dyn_cap_rsp(const struc= t cxl_cmd *cmd, HostMemoryBackend *hmb_dc; uint8_t tag[0x10]; uint32_t i, num; - uint64_t dpa, len; + uint64_t dpa, len, offset; int rid; CXLRetCode ret; =20 @@ -3783,12 +3788,14 @@ static CXLRetCode cmd_dcd_add_dyn_cap_rsp(const str= uct cxl_cmd *cmd, dpa =3D in->updated_entries[i].start_dpa; len =3D in->updated_entries[i].len; if (ct3d->dc.total_capacity_cmd) { + int mr_idx =3D -1; bool found; MemoryRegion *mr; =20 found =3D cxl_extent_find_extent_detail(&ct3d->dc.extents_pend= ing, dpa, len, tag, - &hmb_dc, &fw, &rid); + &hmb_dc, &fw, &rid, + &offset); =20 /* * Host accepted an extent where device lacks details including @@ -3822,13 +3829,38 @@ static CXLRetCode cmd_dcd_add_dyn_cap_rsp(const str= uct cxl_cmd *cmd, memory_region_set_enabled(mr, true); host_memory_backend_set_mapped(hmb_dc, true); =20 + /* Optional direct alias mapping into fixed memory window */ + if (ct3d->direct_mr_enabled) { + uint32_t full_mask =3D (1u << CXL_DC_MAX_DIRECT_MR) - 1; + if ((ct3d->dc.direct_mr_bitmap & full_mask) =3D=3D full_ma= sk) { + qemu_log_mask(LOG_GUEST_ERROR, + "Out of direct mapping slots\n"); + return CXL_MBOX_RESOURCES_EXHAUSTED; + } + mr_idx =3D ctz32(~ct3d->dc.direct_mr_bitmap); + g_autofree char *direct_mapping_name =3D + g_strdup_printf("cxl-direct-mapping-%d", mr_idx); + hwaddr region_offset =3D dpa - ct3d->dc.regions[rid].base; + MemoryRegion *dr_dc_mr =3D &ct3d->dc.dc_direct_mr[mr_idx]; + + memory_region_init_alias(dr_dc_mr, OBJECT(ct3d), + direct_mapping_name, mr, + region_offset, + ct3d->dc.dc_decoder_window.size); + memory_region_add_subregion(&fw->mr, + ct3d->dc.dc_decoder_window.base - fw->base + offset, + dr_dc_mr); + + ct3d->dc.direct_mr_bitmap |=3D (1u << mr_idx); + } + cxl_insert_extent_to_extent_list(extent_list, hmb_dc, fw, dpa, len, - NULL, 0, rid); + tag, 0, rid, offset); } else { cxl_insert_extent_to_extent_list(extent_list, NULL, NULL, dpa, len, - NULL, 0, -1); + NULL, 0, -1, (uint64_t)-1); } ct3d->dc.total_extent_count +=3D 1; ct3d->dc.nr_extents_accepted +=3D 1; @@ -3860,7 +3892,7 @@ static uint32_t copy_extent_list(CXLDCExtentList *dst, ent->hm, ent->fw, ent->start_dpa, ent->len, ent->tag, ent->shared_seq, - ent->rid); + ent->rid, ent->offset); cnt++; } return cnt; @@ -3917,14 +3949,18 @@ static CXLRetCode cxl_dc_extent_release_dry_run(CXL= Type3Dev *ct3d, cxl_insert_extent_to_extent_list(updated_list, NULL, NULL, ent_start_dpa, le= n1, - NULL, 0, ent->rid= ); + ent->tag, 0, + ent->rid, + ent->offset); cnt_delta++; } if (len2) { cxl_insert_extent_to_extent_list(updated_list, NULL, NULL, dpa + len, len2, - NULL, 0, ent->rid= ); + ent->tag, 0, + ent->rid, + ent->offset); cnt_delta++; } =20 @@ -4401,7 +4437,8 @@ static CXLRetCode cmd_fm_initiate_dc_add(const struct= cxl_cmd *cmd, NULL, NULL, ext->start_dpa, ext->len, ext->t= ag, - ext->shared_seq,= 0); + ext->shared_seq,= 0, + (uint64_t)-1); } =20 cxl_extent_group_list_insert_tail(&ct3d->dc.extents_pending, g= roup); diff --git a/hw/mem/cxl_type3.c b/hw/mem/cxl_type3.c index bd32532c7a..e13826eb0b 100644 --- a/hw/mem/cxl_type3.c +++ b/hw/mem/cxl_type3.c @@ -2464,7 +2464,8 @@ static void qmp_cxl_process_dynamic_capacity_prescrip= tive(const char *path, extents[i].len, extents[i].tag, extents[i].share= d_seq, - rid); + rid, + offset); } else { group =3D cxl_insert_extent_to_extent_group(group, dcd->dc.host_dc, @@ -2473,7 +2474,8 @@ static void qmp_cxl_process_dynamic_capacity_prescrip= tive(const char *path, extents[i].len, extents[i].tag, extents[i].share= d_seq, - rid); + rid, + offset); } } =20 diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h index a84b8ab358..1e904d7b48 100644 --- a/include/hw/cxl/cxl_device.h +++ b/include/hw/cxl/cxl_device.h @@ -634,6 +634,7 @@ typedef struct CXLMemSparingWriteAttrs { #define CXL_MEMDEV_SOFT_SPARING_SUPPORT_FLAG BIT(2) =20 #define DCD_MAX_NUM_REGION 8 +#define CXL_DC_MAX_DIRECT_MR 4 =20 typedef struct CXLDCExtentRaw { uint64_t start_dpa; @@ -652,6 +653,7 @@ typedef struct CXLDCExtent { uint16_t shared_seq; uint8_t rsvd[0x6]; int rid; + uint64_t offset; =20 QTAILQ_ENTRY(CXLDCExtent) node; } CXLDCExtent; @@ -720,6 +722,7 @@ struct CXLType3Dev { /* State */ MemoryRegion direct_mr[CXL_HDM_DECODER_COUNT]; CXLFixedWindow *direct_mr_fw[CXL_HDM_DECODER_COUNT]; + bool direct_mr_enabled; AddressSpace hostvmem_as; AddressSpace hostpmem_as; CXLComponentState cxl_cstate; @@ -785,6 +788,14 @@ struct CXLType3Dev { HostMemoryBackend *host_dc; AddressSpace host_dc_as; struct CXLFixedWindow *fw; + uint32_t direct_mr_bitmap; + /* + * dc_decoder_window represents the CXL Decoder Window + */ + struct decoder_window { + hwaddr base; + hwaddr size; + } dc_decoder_window; /* * total_capacity is equivalent to the dynamic capability * memory region size. @@ -799,6 +810,7 @@ struct CXLType3Dev { =20 uint8_t num_regions; /* 0-8 regions */ CXLDCRegion regions[DCD_MAX_NUM_REGION]; + MemoryRegion dc_direct_mr[CXL_DC_MAX_DIRECT_MR]; } dc; =20 struct CXLSanitizeInfo *media_op_sanitize; @@ -866,7 +878,8 @@ void cxl_insert_extent_to_extent_list(CXLDCExtentList *= list, uint64_t len, uint8_t *tag, uint16_t shared_seq, - int rid); + int rid, + uint64_t offset); bool test_any_bits_set(const unsigned long *addr, unsigned long nr, unsigned long size); bool cxl_extents_contains_dpa_range(CXLDCExtentList *list, @@ -878,7 +891,8 @@ CXLDCExtentGroup *cxl_insert_extent_to_extent_group(CXL= DCExtentGroup *group, uint64_t len, uint8_t *tag, uint16_t shared_seq, - int rid); + int rid, + uint64_t offset); void cxl_extent_group_list_insert_tail(CXLDCExtentGroupList *list, CXLDCExtentGroup *group); uint32_t cxl_extent_group_list_delete_front(CXLDCExtentGroupList *list); --=20 2.50.1 (Apple Git-155) From nobody Thu Apr 2 23:57:07 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=1774464439; cv=none; d=zohomail.com; s=zohoarc; b=VGy3++U6cgaQx9mgwD8C7g7S7A6ZdssEU4zk7K0YjC89tYzQeNn7ZBQ3ITKFdk7L+apI36dOpwykx64bIg1ZtDl2ury1j5lrBmjvu6DElp/Wwf1G8f3kbPa6ZsT3AIkldu8+9na6GVBiS52E9UTUtQntgA7trSVwKrLWxzN3xJ4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1774464439; 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=EfL7rxb6cEgTy44navRvPg8XcvCX5wNjS0vQYhVZZ3c=; b=b4/QsdKySwaVsFrT24OB2TrasXJBYIwTBaMpPWPJmfen0PuC1TZJpjFxXVL/B9/npUNJGY9BjuztgJKp/sx1MUVncLXQM16ycfH2DkG0r3+XZnYSj7CFdQheA/qwutboTbZx57C7nhBHT6S+Y6pNSatqjgV1yb7Vwe0oYwpRTQA= 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 1774464439328870.4334192926625; Wed, 25 Mar 2026 11:47:19 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w5TFv-0005LD-Sc; Wed, 25 Mar 2026 14:47:03 -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 1w5TFu-0005Ks-N6 for qemu-devel@nongnu.org; Wed, 25 Mar 2026 14:47:02 -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 1w5TFs-0008As-9C for qemu-devel@nongnu.org; Wed, 25 Mar 2026 14:47:02 -0400 Received: from mail.maildlp.com (unknown [172.18.224.107]) by frasgout.his.huawei.com (SkyGuard) with ESMTPS id 4fgwq31L7bzHnGdQ; Thu, 26 Mar 2026 02:46:23 +0800 (CST) Received: from dubpeml500005.china.huawei.com (unknown [7.214.145.207]) by mail.maildlp.com (Postfix) with ESMTPS id F3DB240587; Thu, 26 Mar 2026 02:46:58 +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:46:57 +0000 To: CC: , , , , , , , , , , , , Subject: [PATCH 7/9] hw/cxl: Add release-time teardown for direct-mapped extents Date: Wed, 25 Mar 2026 18:42:55 +0000 Message-ID: <20260325184259.366-8-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: 1774464440980154100 Content-Type: text/plain; charset="utf-8" Consolidate teardown into the release path so all cleanup flows through a single place. When an extent is removed, tear down any direct alias tied to it and unmap a lazy-mode tagged backend before dropping the extent record. Partial release of backend-backed extents is rejected, since those backends are tracked one-per-extent and cannot be split. Signed-off-by: Alireza Sanaee --- hw/cxl/cxl-mailbox-utils.c | 103 +++++++++++++++++++++++++++++------- hw/mem/cxl_type3.c | 37 ++++++++++++- include/hw/cxl/cxl_device.h | 9 +++- 3 files changed, 126 insertions(+), 23 deletions(-) diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c index 4684c33ba1..9853740994 100644 --- a/hw/cxl/cxl-mailbox-utils.c +++ b/hw/cxl/cxl-mailbox-utils.c @@ -3532,7 +3532,8 @@ void cxl_insert_extent_to_extent_list(CXLDCExtentList= *list, uint8_t *tag, uint16_t shared_seq, int rid, - uint64_t offset) + uint64_t offset, + int direct_window_idx) { CXLDCExtent *extent; =20 @@ -3547,6 +3548,7 @@ void cxl_insert_extent_to_extent_list(CXLDCExtentList= *list, } extent->shared_seq =3D shared_seq; extent->rid =3D rid; + extent->direct_window_idx =3D direct_window_idx; =20 QTAILQ_INSERT_TAIL(list, extent, node); } @@ -3571,7 +3573,8 @@ CXLDCExtentGroup *cxl_insert_extent_to_extent_group(C= XLDCExtentGroup *group, uint8_t *tag, uint16_t shared_seq, int rid, - uint64_t offset) + uint64_t offset, + int direct_window_idx) { if (!group) { group =3D g_new0(CXLDCExtentGroup, 1); @@ -3579,7 +3582,8 @@ CXLDCExtentGroup *cxl_insert_extent_to_extent_group(C= XLDCExtentGroup *group, } cxl_insert_extent_to_extent_list(&group->list, host_mem, fw, dpa, len, - tag, shared_seq, rid, offset); + tag, shared_seq, rid, offset, + direct_window_idx); return group; } =20 @@ -3695,6 +3699,25 @@ static bool cxl_extent_find_extent_detail(CXLDCExten= tGroupList *list, return false; } =20 +static void cxl_unmap_extent_backend(CXLDCExtent *ent) +{ + MemoryRegion *mr; + + if (!ent->hm) { + return; + } + + mr =3D host_memory_backend_get_memory(ent->hm); + if (!mr) { + qemu_log_mask(LOG_GUEST_ERROR, + "Could not get memory region from host memory backen= d\n"); + return; + } + + memory_region_set_enabled(mr, false); + host_memory_backend_set_mapped(ent->hm, false); +} + static CXLRetCode cxl_dcd_add_dyn_cap_rsp_dry_run(CXLType3Dev *ct3d, const CXLUpdateDCExtentListInPl *in) { @@ -3856,11 +3879,12 @@ static CXLRetCode cmd_dcd_add_dyn_cap_rsp(const str= uct cxl_cmd *cmd, =20 cxl_insert_extent_to_extent_list(extent_list, hmb_dc, fw, dpa, len, - tag, 0, rid, offset); + tag, 0, rid, offset, mr_idx); } else { cxl_insert_extent_to_extent_list(extent_list, NULL, NULL, dpa, len, - NULL, 0, -1, (uint64_t)-1); + NULL, 0, -1, + (uint64_t)-1, -1); } ct3d->dc.total_extent_count +=3D 1; ct3d->dc.nr_extents_accepted +=3D 1; @@ -3892,7 +3916,8 @@ static uint32_t copy_extent_list(CXLDCExtentList *dst, ent->hm, ent->fw, ent->start_dpa, ent->len, ent->tag, ent->shared_seq, - ent->rid, ent->offset); + ent->rid, ent->offset, + ent->direct_window_idx); cnt++; } return cnt; @@ -3900,6 +3925,7 @@ static uint32_t copy_extent_list(CXLDCExtentList *dst, =20 static CXLRetCode cxl_dc_extent_release_dry_run(CXLType3Dev *ct3d, const CXLUpdateDCExtentListInPl *in, CXLDCExtentList *updated_list, + CXLDCExtentList *updated_removed_list, uint32_t *updated_list_size) { CXLDCExtent *ent, *ent_next; @@ -3909,6 +3935,9 @@ static CXLRetCode cxl_dc_extent_release_dry_run(CXLTy= pe3Dev *ct3d, CXLRetCode ret =3D CXL_MBOX_SUCCESS; =20 QTAILQ_INIT(updated_list); + if (updated_removed_list) { + QTAILQ_INIT(updated_removed_list); + } copy_extent_list(updated_list, &ct3d->dc.extents); =20 for (i =3D 0; i < in->num_entries_updated; i++) { @@ -3942,25 +3971,44 @@ static CXLRetCode cxl_dc_extent_release_dry_run(CXL= Type3Dev *ct3d, } len_done =3D ent_len - len1 - len2; =20 + /* + * Tagged backends are mapped one-backend-per-extent. + * Partial release would leave a backend-backed extent + * behind without a clean backend lifecycle. + */ + if (ent->hm && (len1 || len2)) { + ret =3D CXL_MBOX_INVALID_INPUT; + goto free_and_exit; + } + + /* Cannot split extents with direct window mapping */ + if (ent->direct_window_idx >=3D 0 && (len1 || len2)) { + ret =3D CXL_MBOX_INVALID_INPUT; + goto free_and_exit; + } + + if (updated_removed_list) { + cxl_insert_extent_to_extent_list( + updated_removed_list, ent->hm, ent->fw, + ent->start_dpa, ent->len, ent->tag, ent->share= d_seq, + ent->rid, ent->offset, ent->direct_window_idx); + } + cxl_remove_extent_from_extent_list(updated_list, ent); cnt_delta--; =20 if (len1) { - cxl_insert_extent_to_extent_list(updated_list, - NULL, NULL, - ent_start_dpa, le= n1, - ent->tag, 0, - ent->rid, - ent->offset); + cxl_insert_extent_to_extent_list( + updated_list, NULL, NULL, + ent_start_dpa, len1, ent->tag, 0, + ent->rid, ent->offset, ent->direct_window_idx); cnt_delta++; } if (len2) { - cxl_insert_extent_to_extent_list(updated_list, - NULL, NULL, - dpa + len, len2, - ent->tag, 0, - ent->rid, - ent->offset); + cxl_insert_extent_to_extent_list( + updated_list, NULL, NULL, + dpa + len, len2, ent->tag, 0, + ent->rid, ent->offset, ent->direct_window_idx); cnt_delta++; } =20 @@ -4002,6 +4050,7 @@ static CXLRetCode cmd_dcd_release_dyn_cap(const struc= t cxl_cmd *cmd, CXLUpdateDCExtentListInPl *in =3D (void *)payload_in; CXLType3Dev *ct3d =3D CXL_TYPE3(cci->d); CXLDCExtentList updated_list; + CXLDCExtentList updated_removed_list; CXLDCExtent *ent, *ent_next; uint32_t updated_list_size; CXLRetCode ret; @@ -4025,11 +4074,26 @@ static CXLRetCode cmd_dcd_release_dyn_cap(const str= uct cxl_cmd *cmd, } =20 ret =3D cxl_dc_extent_release_dry_run(ct3d, in, &updated_list, + &updated_removed_list, &updated_list_size); if (ret !=3D CXL_MBOX_SUCCESS) { return ret; } =20 + if (ct3d->direct_mr_enabled) { + /* Remove memory alias for the removed extents */ + QTAILQ_FOREACH_SAFE(ent, &updated_removed_list, node, ent_next) { + cxl_remove_memory_alias(ct3d, ent->fw, ent->direct_window_idx); + cxl_unmap_extent_backend(ent); + cxl_remove_extent_from_extent_list(&updated_removed_list, ent); + } + } else { + QTAILQ_FOREACH_SAFE(ent, &updated_removed_list, node, ent_next) { + cxl_unmap_extent_backend(ent); + cxl_remove_extent_from_extent_list(&updated_removed_list, ent); + } + } + /* * If the dry run release passes, the returned updated_list will * be the updated extent list and we just need to clear the extents @@ -4438,7 +4502,7 @@ static CXLRetCode cmd_fm_initiate_dc_add(const struct= cxl_cmd *cmd, ext->start_dpa, ext->len, ext->t= ag, ext->shared_seq,= 0, - (uint64_t)-1); + (uint64_t)-1, -1= ); } =20 cxl_extent_group_list_insert_tail(&ct3d->dc.extents_pending, g= roup); @@ -4520,6 +4584,7 @@ static CXLRetCode cmd_fm_initiate_dc_release(const st= ruct cxl_cmd *cmd, rc =3D cxl_dc_extent_release_dry_run(ct3d, list, &updated_list, + NULL, &updated_list_size); if (rc) { return rc; diff --git a/hw/mem/cxl_type3.c b/hw/mem/cxl_type3.c index e13826eb0b..6b73d58358 100644 --- a/hw/mem/cxl_type3.c +++ b/hw/mem/cxl_type3.c @@ -2465,7 +2465,8 @@ static void qmp_cxl_process_dynamic_capacity_prescrip= tive(const char *path, extents[i].tag, extents[i].share= d_seq, rid, - offset); + offset, + 0); } else { group =3D cxl_insert_extent_to_extent_group(group, dcd->dc.host_dc, @@ -2475,7 +2476,8 @@ static void qmp_cxl_process_dynamic_capacity_prescrip= tive(const char *path, extents[i].tag, extents[i].share= d_seq, rid, - offset); + offset, + 0); } } =20 @@ -2541,6 +2543,37 @@ void qmp_cxl_release_dynamic_capacity(const char *pa= th, uint16_t host_id, } } =20 +void cxl_remove_memory_alias(CXLType3Dev *dcd, struct CXLFixedWindow *fw, + int hdm_id) +{ + MemoryRegion *mr; + + if (hdm_id < 0 || hdm_id >=3D CXL_DC_MAX_DIRECT_MR) { + qemu_log_mask(LOG_GUEST_ERROR, + "Invalid direct window index %d\n", hdm_id); + return; + } + + if (dcd->dc.total_capacity_cmd > 0) { + mr =3D &dcd->dc.dc_direct_mr[hdm_id]; + } else { + qemu_log_mask(LOG_GUEST_ERROR, + "No dynamic capacity command support, " + "cannot remove memory region alias\n"); + return; + } + + if (!fw) { + qemu_log_mask(LOG_GUEST_ERROR, + "Cannot remove memory region alias " + "without a valid fixed window\n"); + return; + } + + memory_region_del_subregion(&fw->mr, mr); + dcd->dc.direct_mr_bitmap &=3D ~(1u << hdm_id); +} + static void ct3_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc =3D DEVICE_CLASS(oc); diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h index 1e904d7b48..42db9c7ce4 100644 --- a/include/hw/cxl/cxl_device.h +++ b/include/hw/cxl/cxl_device.h @@ -654,6 +654,7 @@ typedef struct CXLDCExtent { uint8_t rsvd[0x6]; int rid; uint64_t offset; + int direct_window_idx; =20 QTAILQ_ENTRY(CXLDCExtent) node; } CXLDCExtent; @@ -879,7 +880,8 @@ void cxl_insert_extent_to_extent_list(CXLDCExtentList *= list, uint8_t *tag, uint16_t shared_seq, int rid, - uint64_t offset); + uint64_t offset, + int direct_window_idx); bool test_any_bits_set(const unsigned long *addr, unsigned long nr, unsigned long size); bool cxl_extents_contains_dpa_range(CXLDCExtentList *list, @@ -892,7 +894,8 @@ CXLDCExtentGroup *cxl_insert_extent_to_extent_group(CXL= DCExtentGroup *group, uint8_t *tag, uint16_t shared_seq, int rid, - uint64_t offset); + uint64_t offset, + int direct_window_idx); void cxl_extent_group_list_insert_tail(CXLDCExtentGroupList *list, CXLDCExtentGroup *group); uint32_t cxl_extent_group_list_delete_front(CXLDCExtentGroupList *list); @@ -900,6 +903,8 @@ void ct3_set_region_block_backed(CXLType3Dev *ct3d, uin= t64_t dpa, uint64_t len); void ct3_clear_region_block_backed(CXLType3Dev *ct3d, uint64_t dpa, uint64_t len); +void cxl_remove_memory_alias(CXLType3Dev *dcd, struct CXLFixedWindow *fw, + int hdm_id); bool ct3_test_region_block_backed(CXLType3Dev *ct3d, uint64_t dpa, uint64_t len); void cxl_assign_event_header(CXLEventRecordHdr *hdr, --=20 2.50.1 (Apple Git-155) From nobody Thu Apr 2 23:57:07 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=1774464488; cv=none; d=zohomail.com; s=zohoarc; b=UG8Bvz8E/d9cTBtK9Hlcquh2SNnAFThiVgefYOqMbCUFtPN/q2omt1GHO5VnCOFQJbxbtRWScqFzjutaAKBYbLnTAE5ZFhwhoRczahcoYZBlxcdt+cOyulbV5RaONzdmZxOt/5+eJxE7Pk6AlCj/N2T3kiZXgc+cw/ea5enQBEk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1774464488; 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=LJlM3XQDm5zh3qHps6l3LDkzsRrdD4whBIZi4cOg2cs=; b=iWle20cqWCoW3J3sxC/4JdmR3QMPDjO/wD5KwbLcFxm010DUg3dR3jRqHJvZ8kb9xvhVvL67DQajWznpf3rbl1EyUx3GugVY2wThOJTjc/53LGISNcfOc1+RY+ptEqHszWhhwE9cAHKbumJiJ/5rG4ZKdHTo5ujd/DIDh1Uh6Oc= 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 1774464488320907.0029385827119; Wed, 25 Mar 2026 11:48:08 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w5TGV-0005lj-TL; Wed, 25 Mar 2026 14:47:39 -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 1w5TGR-0005kC-Ht for qemu-devel@nongnu.org; Wed, 25 Mar 2026 14:47:36 -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 1w5TGP-0000Ec-Ro for qemu-devel@nongnu.org; Wed, 25 Mar 2026 14:47:35 -0400 Received: from mail.maildlp.com (unknown [172.18.224.83]) by frasgout.his.huawei.com (SkyGuard) with ESMTPS id 4fgwrC0wMtzJ46DS; Thu, 26 Mar 2026 02:47:23 +0800 (CST) Received: from dubpeml500005.china.huawei.com (unknown [7.214.145.207]) by mail.maildlp.com (Postfix) with ESMTPS id 16DA640086; Thu, 26 Mar 2026 02:47:32 +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:47:30 +0000 To: CC: , , , , , , , , , , , , Subject: [PATCH 8/9] hw/cxl: Add tag-based dynamic-capacity release support Date: Wed, 25 Mar 2026 18:42:56 +0000 Message-ID: <20260325184259.366-9-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: 1774464489614154100 Content-Type: text/plain; charset="utf-8" Add support for the tag-based dynamic-capacity release policy via the QMP interface. The new path scans committed extents, selects those whose stored tag matches the requested UUID, and emits a Release Dynamic Capacity event for each matching range. This is intentionally scoped to tag-driven selection. Prescriptive release handling and the underlying extent teardown stay in the existing paths. Signed-off-by: Alireza Sanaee --- hw/mem/cxl_type3.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/hw/mem/cxl_type3.c b/hw/mem/cxl_type3.c index 6b73d58358..d5fa8a530a 100644 --- a/hw/mem/cxl_type3.c +++ b/hw/mem/cxl_type3.c @@ -2492,6 +2492,63 @@ static void qmp_cxl_process_dynamic_capacity_prescri= ptive(const char *path, cxl_create_dc_event_records_for_extents(dcd, type, extents, num_extent= s); } =20 +static void qmp_cxl_process_dynamic_capacity_tag_based(const char *path, + uint16_t hid, CXLDCEventType type, uint8_t rid, const char *tag, + CxlDynamicCapacityExtentList *records, Error **errp) +{ + Object *obj; + CXLType3Dev *dcd; + CXLDCExtentList *list =3D NULL; + CXLDCExtent *ent; + g_autofree CXLDCExtentRaw *extents =3D NULL; + + obj =3D object_resolve_path_type(path, TYPE_CXL_TYPE3, NULL); + if (!obj) { + error_setg(errp, "Unable to resolve CXL type 3 device"); + return; + } + + dcd =3D CXL_TYPE3(obj); + if (!dcd->dc.num_regions) { + error_setg(errp, "No dynamic capacity support from the device"); + return; + } + + if (rid >=3D dcd->dc.num_regions) { + error_setg(errp, "region id is too large"); + return; + } + + QemuUUID uuid_req; + qemu_uuid_parse(tag, &uuid_req); + + list =3D &dcd->dc.extents; + size_t cap =3D 8, n =3D 0; + extents =3D g_new0(CXLDCExtentRaw, cap); + QTAILQ_FOREACH(ent, list, node) { + QemuUUID uuid_ext; + memcpy(&uuid_ext.data, ent->tag, sizeof(ent->tag)); + if (!qemu_uuid_is_equal(&uuid_req, &uuid_ext)) { + continue; + } + + if (n =3D=3D cap) { + cap *=3D 2; + extents =3D g_renew(CXLDCExtentRaw, extents, cap); + } + + extents[n++] =3D (CXLDCExtentRaw){ .start_dpa =3D ent->start_dpa, + .len =3D ent->len, + .shared_seq =3D 0 }; + } + + if (n =3D=3D 0) { + return; + } + extents =3D g_renew(CXLDCExtentRaw, extents, n); + cxl_create_dc_event_records_for_extents(dcd, type, extents, n); +} + void qmp_cxl_add_dynamic_capacity(const char *path, uint16_t host_id, CxlExtentSelectionPolicy sel_policy, uint8_t region, const char *tag, @@ -2537,6 +2594,10 @@ void qmp_cxl_release_dynamic_capacity(const char *pa= th, uint16_t host_id, region, tag, extents, errp); return; + case CXL_EXTENT_REMOVAL_POLICY_TAG_BASED: + qmp_cxl_process_dynamic_capacity_tag_based(path, host_id, type, re= gion, + tag, extents, errp); + return; default: error_setg(errp, "Removal policy not supported"); return; --=20 2.50.1 (Apple Git-155) From nobody Thu Apr 2 23:57:07 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=1774464499; cv=none; d=zohomail.com; s=zohoarc; b=HcTkCjoOE4/IOUJrzn8aRhwUAwaErWnVXg918MgbsXYwR5NM5dfge02XYC7XMbiShgFmhxhNCw/DhMpip8nk1JafNZE8cESmg6EIeBLdOPxMl3gyEN4gKP7ZszpqqsZsh6W1bFZZoZYYrBJK2vY43ra0wNj5U4O9qKrz6WCxmG8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1774464499; 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=SQ5qY4cvFL2wn5x2AFqqEApLWBg/gQwDSv/uF7LJUf0=; b=afFb1VQlDxsWs8exAXwxq3sKb1zrNftcrhHayA4ik4tB4H5AjR8cxrfJ5wZqy/OVPRU8WJrne32VsYN6dqbUJ9piAc5WTlI6Km3PAU1moMCHrH2upRmfjYfiJAR9EXQdYVKV4BvG99oVDGGd/nmQVQhmmGE83qqVoIgvTgTv5IM= 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 1774464499829653.9417636085069; Wed, 25 Mar 2026 11:48:19 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w5TH4-00068g-Qp; Wed, 25 Mar 2026 14:48:14 -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 1w5TH0-00063s-Ts for qemu-devel@nongnu.org; Wed, 25 Mar 2026 14:48:11 -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 1w5TGw-0000Jm-IY for qemu-devel@nongnu.org; Wed, 25 Mar 2026 14:48:10 -0400 Received: from mail.maildlp.com (unknown [172.18.224.150]) by frasgout.his.huawei.com (SkyGuard) with ESMTPS id 4fgwrq2fRtzJ469d; Thu, 26 Mar 2026 02:47:55 +0800 (CST) Received: from dubpeml500005.china.huawei.com (unknown [7.214.145.207]) by mail.maildlp.com (Postfix) with ESMTPS id 5254F4056B; Thu, 26 Mar 2026 02:48:04 +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:48:03 +0000 To: CC: , , , , , , , , , , , , Subject: [PATCH 9/9] hw/cxl: Add QMP status query for dynamic-capacity extent release Date: Wed, 25 Mar 2026 18:42:57 +0000 Message-ID: <20260325184259.366-10-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: 1774464500816158500 Content-Type: text/plain; charset="utf-8" Add a small status query so orchestration layers can check whether a tagged extent is still pending, committed, or no longer present after a release request. Introduce the ExtentStatus QAPI struct and the cxl-release-dynamic-capacity-status command. Signed-off-by: Alireza Sanaee --- hw/mem/cxl_type3.c | 85 ++++++++++++++++++++++++++++++++++++++++ hw/mem/cxl_type3_stubs.c | 10 +++++ qapi/cxl.json | 46 ++++++++++++++++++++++ 3 files changed, 141 insertions(+) diff --git a/hw/mem/cxl_type3.c b/hw/mem/cxl_type3.c index d5fa8a530a..8999b36e61 100644 --- a/hw/mem/cxl_type3.c +++ b/hw/mem/cxl_type3.c @@ -2635,6 +2635,91 @@ void cxl_remove_memory_alias(CXLType3Dev *dcd, struc= t CXLFixedWindow *fw, dcd->dc.direct_mr_bitmap &=3D ~(1u << hdm_id); } =20 +/* + * This function allows for a simple check to make sure that + * our extent is removed. It can be used by an orchestration layer. + */ +ExtentStatus * +qmp_cxl_release_dynamic_capacity_status(const char *path, + uint16_t hid, uint8_t rid, + const char *tag, + Error **errp) +{ + Object *obj; + CXLType3Dev *dcd; + CXLDCExtentList *list =3D NULL; + CXLDCExtent *ent; + QemuUUID uuid_req; + ExtentStatus *res; + + obj =3D object_resolve_path_type(path, TYPE_CXL_TYPE3, NULL); + if (!obj) { + error_setg(errp, "Unable to resolve CXL type 3 device"); + return NULL; + } + + dcd =3D CXL_TYPE3(obj); + if (!dcd->dc.num_regions) { + error_setg(errp, "No dynamic capacity support from the device"); + return NULL; + } + + if (rid >=3D dcd->dc.num_regions) { + error_setg(errp, "Region id is too large"); + return NULL; + } + + if (!tag) { + error_setg(errp, "Tag must be valid"); + return NULL; + } + + list =3D &dcd->dc.extents; + qemu_uuid_parse(tag, &uuid_req); + res =3D g_new0(ExtentStatus, 1); + + /* Check committed extents */ + QTAILQ_FOREACH(ent, list, node) { + QemuUUID uuid_ext; + g_autofree char *uuid_str =3D NULL; + memcpy(&uuid_ext.data, ent->tag, sizeof(ent->tag)); + if (qemu_uuid_is_equal(&uuid_req, &uuid_ext)) { + uuid_str =3D qemu_uuid_unparse_strdup(&uuid_ext); + res->status =3D g_strdup("Committed"); + res->message =3D + g_strdup_printf("Found committed extent with tag %s dpa 0x= %" + PRIx64 " len 0x%" PRIx64, + uuid_str, ent->start_dpa, ent->len); + return res; + } + } + + /* Check pending extents (not yet committed by kernel) */ + { + CXLDCExtentGroup *group; + QTAILQ_FOREACH(group, &dcd->dc.extents_pending, node) { + QTAILQ_FOREACH(ent, &group->list, node) { + QemuUUID uuid_ext; + g_autofree char *uuid_str =3D NULL; + memcpy(&uuid_ext.data, ent->tag, sizeof(ent->tag)); + if (qemu_uuid_is_equal(&uuid_req, &uuid_ext)) { + uuid_str =3D qemu_uuid_unparse_strdup(&uuid_ext); + res->status =3D g_strdup("Pending"); + res->message =3D + g_strdup_printf("Found pending extent with tag %s" + " dpa 0x%" PRIx64 " len 0x%" PRIx6= 4, + uuid_str, ent->start_dpa, ent->len= ); + return res; + } + } + } + } + + res->status =3D g_strdup("Released"); + res->message =3D g_strdup_printf("Tag %s released or not found", tag); + return res; +} + static void ct3_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc =3D DEVICE_CLASS(oc); diff --git a/hw/mem/cxl_type3_stubs.c b/hw/mem/cxl_type3_stubs.c index 98292a931c..17f9414142 100644 --- a/hw/mem/cxl_type3_stubs.c +++ b/hw/mem/cxl_type3_stubs.c @@ -127,3 +127,13 @@ void qmp_cxl_release_dynamic_capacity(const char *path= , uint16_t host_id, { error_setg(errp, "CXL Type 3 support is not compiled in"); } + +ExtentStatus *qmp_cxl_release_dynamic_capacity_status(const char *path, + uint16_t host_id, + uint8_t region, + const char *tag, + Error **errp) +{ + error_setg(errp, "CXL Type 3 support is not compiled in"); + return NULL; +} diff --git a/qapi/cxl.json b/qapi/cxl.json index 81d6198ba0..53325ba530 100644 --- a/qapi/cxl.json +++ b/qapi/cxl.json @@ -636,3 +636,49 @@ }, 'features': [ 'unstable' ] } + +## +# @ExtentStatus: +# This is an object that describes the status of an extent. +# +# @status: String indicating the overall result, e.g. "success". +# @message: Human-readable description of the outcome. +# +# Since: 9.1 +## +{ 'struct': 'ExtentStatus', + 'data': { 'status': 'str', 'message': 'str' } +} + +## +# @cxl-release-dynamic-capacity-status: +# +# This commands checks if an extent tag has been released or not. +# +# @path: path to the CXL Dynamic Capacity Device in the QOM tree. +# +# @host-id: The "Host ID" field as defined in Compute Express Link +# (CXL) Specification, Revision 3.1, Table 7-71. +# +# @region: The "Region Number" field as defined in Compute Express +# Link Specification, Revision 3.1, Table 7-71. Valid range +# is from 0-7. +# +# @tag: The "Tag" field as defined in Compute Express Link (CXL) +# Specification, Revision 3.1, Table 7-71. +# +# Features: +# +# @unstable: For now this command is subject to change. +# +# Since: 9.1 +## +{ 'command': 'cxl-release-dynamic-capacity-status', + 'data': { 'path': 'str', + 'host-id': 'uint16', + 'region': 'uint8', + 'tag': 'str' + }, + 'features': [ 'unstable' ], + 'returns': 'ExtentStatus' +} --=20 2.50.1 (Apple Git-155)