From nobody Fri Oct 2 03:40:52 2026 Received: from MW6PR02CU001.outbound.protection.outlook.com (mail-westus2azon11012053.outbound.protection.outlook.com [52.101.48.53]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8EFD73DE44C; Wed, 5 Aug 2026 07:42:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.48.53 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785915733; cv=fail; b=baoA2fH3PEFyGE5g0tGDoFtSRDSgJQM8YCZnz8ZjOJePIMMjs5p5tx/g1utZs9O3th+ZVBDotzUxL4JFBz1t4EpGzRqOYwyO5x6z/bm3twVPH2ORilWHFNI8MWj7VmZHeg2nVyT7mey45ShchxVvMCp9GWdU/Nv6IQm6DDB8/co= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785915733; c=relaxed/simple; bh=j6hM3nHHW+wy+aPdDMCOurAiwyXpxMzfufChIz/y9CU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=ldn9ksDE6U8gFpB5NY+acVZ0Th67JskTw0sjHk+f+gE+3loy2DZpTQa4F7V/wkll8x6zpQtadvXDkQCLOqUOz3BVtUBkJ3FhO5SZPZHTUDMDALXEGB3CPV6emaJxu9ZXGxIddM/aYNZU25NzPM679NG3wd9LZgjmSwgWNyXyQXA= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=nvidia.com; spf=fail smtp.mailfrom=nvidia.com; dkim=pass (2048-bit key) header.d=Nvidia.com header.i=@Nvidia.com header.b=OvgAU49z; arc=fail smtp.client-ip=52.101.48.53 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=nvidia.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=nvidia.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=Nvidia.com header.i=@Nvidia.com header.b="OvgAU49z" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=f8cuPGiQ6SWepy9XvWJrQG1CJbf9XXwkhyTs5QQ6w71GnuKzjgiMyotHiF0TCN6RXtZryLqLsqxGSlTRDFvvVjjFMKxUr5AisskVNQL9WIvUhIsjOdOs8fpaQTqlk3sLcsdjAGoCXY+mc24XkG4Khp9o6bnk4q2jpNs3XYmZpuJxisxThez4gdk0FJ8+FUW8XIgCANXNyiQPmE8D0xecRb9ZiH6lm14Jm9EcF5SH12W93KX9iiOBGA5uGXWBuLzPs5yb1S9c4MHUw85KZbyYANLlaQGUJyUuRNP358pcsOLWLhsOArep+9F3+v3lVrTiVqQP2I3XOVxhceyU68uQvA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=OadVr7LWfCyKIqXNGVTlgCDbDmYGh2JVTaimHxjWWwA=; b=AG+h27891tz4Gz9YkOZgyTQ9kevCqPX/Blrgrkq2HZCyGkLIhWx2SnipJkWSjJ41RRtU1t+cZNQBxQ5w3zXATylx28r23PTtj9ug7Zvcg0GDufh0soG9Akz9er+WBCmlgl4WubxvI8X7okoTllj8qmTv3BFxoBKFM/ID6s0KIHdS6BglHC/ZnMbrkpaYeN/8lzVlmjSfT3qvBVaM8PY3KXkwZL7u6CB+FHX6yRRj+6v0/JfZf8ikr1ILYFRlx4rMKbpNUSsU+NmdNR3ZFcuEPTxfN3I+jqQ3TjJgKVO7UlgAoYtxJHIlAFnOHBjJs9M8B5JG2/7C7eCEnXZItnyQ1g== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nvidia.com; dmarc=pass action=none header.from=nvidia.com; dkim=pass header.d=nvidia.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=OadVr7LWfCyKIqXNGVTlgCDbDmYGh2JVTaimHxjWWwA=; b=OvgAU49zS3N1N2+CImswHTni4KjC1W8dGt4desPBP0Ddi5J17fmFsbxCThcKBiLnp01IHLtNPeUxRMpI4CWID+Jnbkw16L8EoNPWTIMBi+Q6NHBPTJDVSdv0qThpnHu3pOUaGUcjanwJWXDa0HPYcOR6RH724RZvYrsbdyj1eTZLzjRNq9SDk+BbqnPRPhovsRIdtWJRh5RYM9hARUUiov4ScSEC11myiYPZ+MuaXLvCcNHKzU5WwmG3amXdNmTlkP8qpOyyvKYEqfHXk79qWIVG8l7veMprl5XDbq4/D6c+/IZqnXqBKb2+DruAsW7qTHgOtE7QET1EUv6Ip49LBQ== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nvidia.com; Received: from MW2PR12MB2380.namprd12.prod.outlook.com (2603:10b6:907:4::32) by LV2PR12MB5966.namprd12.prod.outlook.com (2603:10b6:408:171::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.270.20; Wed, 5 Aug 2026 07:42:07 +0000 Received: from MW2PR12MB2380.namprd12.prod.outlook.com ([fe80::90d:c5c:6a5e:94a5]) by MW2PR12MB2380.namprd12.prod.outlook.com ([fe80::90d:c5c:6a5e:94a5%4]) with mapi id 15.21.0270.017; Wed, 5 Aug 2026 07:42:06 +0000 From: Richard Cheng To: dave@stgolabs.net, jic23@kernel.org, dave.jiang@intel.com, alison.schofield@intel.com, vishal.l.verma@intel.com, djbw@kernel.org Cc: iweiny@kernel.org, ming.li@zohomail.com, gourry@gourry.net, rrichter@amd.com, linux-cxl@vger.kernel.org, linux-kernel@vger.kernel.org, newtonl@nvidia.com, kristinc@nvidia.com, kaihengf@nvidia.com, kobak@nvidia.com, Richard Cheng Subject: [RFC PATCH 1/3] cxl/region: Reset software-created regions on memdev detach Date: Wed, 5 Aug 2026 15:40:40 +0800 Message-ID: <20260805074042.30173-2-icheng@nvidia.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20260805074042.30173-1-icheng@nvidia.com> References: <20260805074042.30173-1-icheng@nvidia.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: SI1PR02CA0006.apcprd02.prod.outlook.com (2603:1096:4:1f7::11) To MW2PR12MB2380.namprd12.prod.outlook.com (2603:10b6:907:4::32) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: MW2PR12MB2380:EE_|LV2PR12MB5966:EE_ X-MS-Office365-Filtering-Correlation-Id: 5ad7bc95-1e88-48a3-0b74-08def2c50b5b X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|23010399003|1800799024|376014|7416014|366016|10067099003|56012099006|11063799006|3023799007|18002099003|22082099003; X-Microsoft-Antispam-Message-Info: YS6H+pf1Tl4YdXzFoToqCO1+1TxW+ln1yriGe26bJEWFPF1Gb2/UxdphjCYio2eLZoR2MZkibWkcCdBLy5xyz/WjT0dYmxCuqqO5OJxJnOiEOt5diZjHQFCF7kswu6+KduoEIkvoxBLjBv2OdxL5Et6BPLuj6/nleOeQeVnrmk2C499DDFF7EcmPCbaCic8m9QpHYPjLvbeA5kJpCpMxCo1Gc2KSYUbXU21wlo2CqLfIiO3oFlijl347/qfo5S/+SNuih6pf7akjdrsCZ9x47oaivtSc01cGsdWBxii9N8EV2Z9JcvWvQkuRQWN0vwn+3JEuy9qBKmTMN8dW63hm5joQRcNii+uJn64xAJK4TeQFurk7kcKUJtvaWh7lHaQnuNIGmtgm04Mb6hF1P0SubIx9Qg5xbS2mFm/07nlpOay1yjZynn1BiF/ItUIDrf1Pm99ngZymkOudd6Cfbzp9exd+DXhvgZVqYuM573T2mjulkIFbblj+KWMrdDBUgzhwqji6hLe8Qsie6QIVYuL9vC5r1jJVSgaw8wqB/6NtzAIk1ReAYvlQY3A/5dxfOy94pLIlkV4NukAwTVaWxYD4mF3Cb0HXSLtkqaSuijo6SFQA1faNDpAHLd2j1sBzp5f5PwEvX6coo575Xd7eRJ7k2OLBhM3VZIV45ta1o9/yQ8A= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:MW2PR12MB2380.namprd12.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(23010399003)(1800799024)(376014)(7416014)(366016)(10067099003)(56012099006)(11063799006)(3023799007)(18002099003)(22082099003);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?kvUsQ4hfWyZV0aP0/1Ent7aUC9FfndjZSpfSiiMkstvCl231nrBwZrBoTzUI?= =?us-ascii?Q?+07MrXjmT7N8BWgLE4cHHN2QQMJB7QoTdPypMyEkLt9c28RtKNTy3qCLa7Ua?= =?us-ascii?Q?MZ6Q3WGaUpzHhqiAhLJ5p+h3DItgtMnyTGoxufsKzyXeDYdAD1DOIuH0zslT?= =?us-ascii?Q?WDrQb2HiX3BLHDrQa8CM2mXLr9/aIAlxHBtsJVN5r3htTHwaEKo2PMZuyghz?= =?us-ascii?Q?7dtkPoPudn3krBAZ+4zJWeI+Rit0MS2LemrHGT0Kyag+vNqvWxNVps9VOVY4?= =?us-ascii?Q?OsKiD0iWCYDgqcv50FtPnY5h8kRGQp45dR3oV1vPDqRD2cVtsnBf4xd40we3?= =?us-ascii?Q?oZqEWWOv2S41MieFHESd/TW11UxzDslGpH3DyZGUG8Yia92frhZyWhxy23JG?= =?us-ascii?Q?9dbx2fM4hPZuXk0FlyZIUCQPUgpYQKQ7V4clz/MufGwm0KKuscvqmXxH1ZFH?= =?us-ascii?Q?/nM7IO+8qjG7fT+vPTuVzbqX3Mxcjyreq5vLytp7Jr3YyOsqsbCHcMVkoCV9?= =?us-ascii?Q?FaC+elW/IJ8HO+HoH6Izkp586mfPsLI13HRYS3UwhL6d7YTGBR3CGh7psIyW?= =?us-ascii?Q?r1SiGI4SFBcWwhHWPF98KhVSAAHNKPAJiLEGDmFChwB0AxRNbkvaOyo0kj93?= =?us-ascii?Q?i/+cwq4f06CW/wMAOQd9hWCDhrkgzyYudbD9hcZcJOnC3uXnwOVrKjtdYaQK?= =?us-ascii?Q?RRuj+3NJNT2KUXqBclxdYSWapPfqyWCxKD6MsVufyDPBv1v57mrv6JI/j6GR?= =?us-ascii?Q?v/p9kdvy9DZKSDv5/CIaAPJ29aosNjreP1j8DeokLZrOi060oWhs7ZIcxtdS?= =?us-ascii?Q?XFStawl4/JLYPcY0HtDRDPman5ttfuDzRFh09JKf1yrgzZykWTtZcxZJVOvw?= =?us-ascii?Q?X0vFdNxkyJGgWO6tuKRfFO8Xi0yIqJSpoH8CIXhApooSx9BP+MAGXSgfzVhl?= =?us-ascii?Q?1Q3HB86EOgZduFNGImHIPz24TsfvNOM/yE1sgrnfy5OqKrrn2XaMAMdHFpej?= =?us-ascii?Q?697UvESf8v84rpDXN7PWzLIVhR8YIaESwr7RuyB3Rb3ypV4yxxviMyh3ua9T?= =?us-ascii?Q?aPYTZHoV6LTxNrl+89hTrJK6SFduYFaJcQHW9pbKqB93xXm7l9ItHKlyZrKn?= =?us-ascii?Q?qqVAIPnvEcivDvpft1sQ0Vfh1c4ekV7mIu32YI1/wWY8msmR8FPM4uA10eKI?= =?us-ascii?Q?dQ25iLmiF+r5BlQaf+T2HkI/en1Xv7hGU1h1CVuEpUO32loGEkSxugd61zVU?= =?us-ascii?Q?hlGpZdEGn9S9cCFuPWevur/tEXI0yTXyu6j7tZj1p0kG0LUIm+5zAm3Cqfnm?= =?us-ascii?Q?DA1FVPgptMHGsEE8Ay+UWMhUDfi8Eh+YYoh4NJWt7oauEvWGw3HD8i6+yfwk?= =?us-ascii?Q?OUSvS94vYjnywvFT+qQDmni9F1dcGMj6Nv5b4qBGF2+RiQBVU1eDhQwaCnBZ?= =?us-ascii?Q?0J4d+zjiTiAQPg3M4DWfNVjWnXQmQ6uAZwdj0S5N3MQ7aN9ECiIOcIJjG805?= =?us-ascii?Q?qeSmoHl2Cy6y3BrCNVlOb3Z+eSXGt71wpfzVCz5NznFkBeP4d2rkOV05X7VX?= =?us-ascii?Q?s5t7LVq7lz6L1d6df6UlrnPxYF4jNfsw6FXqQa5scBybJtym+0E3Nx3ZtZdd?= =?us-ascii?Q?j3uh6ARtk2WkDx1UyvY/pUwHr/Td1XRpkTMgzBAy2oVL4Jjz+zf62ntrX9mh?= =?us-ascii?Q?k6/nRgi/vNu/quYSPKFZzRhEZyJrNPoCc4k92gmaWGh2DfqQXqRp/q1L6WK8?= =?us-ascii?Q?4vzuvjmocg=3D=3D?= X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-Network-Message-Id: 5ad7bc95-1e88-48a3-0b74-08def2c50b5b X-MS-Exchange-CrossTenant-AuthSource: MW2PR12MB2380.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 05 Aug 2026 07:42:06.4081 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: hhDcmzRx5Q2H9NITGMGXuylIzSFv5dptZ9LACtOd0nhMVuj1io16hMa8Ae8pFDa2cTo8BexD2g2ok5T9tkiviQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: LV2PR12MB5966 Content-Type: text/plain; charset="utf-8" A memdev attach provider locks its region to prevent userspace disposition. Future software-created Type-2 regions inherit that lock, causing the existing reset path to treat them like FW-owned or HW-locked regions and leave their decoder programming behind when the provider detaches. Pass a managed-detach context through region teardown. In that context, allow reset only when the region is non-AUTO, owned by a memdev attach provider, and has no HW-locked decoder in its path. This narrowly permits the provider to reset its own software-created region without changing generic teardown behavior. Generic teardown remains unchanged, while FW-discovered AUTO regions and genuinely locked decoders remain protected. Signed-off-by: Richard Cheng --- drivers/cxl/core/region.c | 112 +++++++++++++++++++++++++++++++------- 1 file changed, 91 insertions(+), 21 deletions(-) diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c index 1e211542b6b6..7fcaddc61180 100644 --- a/drivers/cxl/core/region.c +++ b/drivers/cxl/core/region.c @@ -39,6 +39,7 @@ static nodemask_t nodemask_region_seen =3D NODE_MASK_NONE; =20 static struct cxl_region *to_cxl_region(struct device *dev); +static bool cxl_region_has_memdev_attach(struct cxl_region *cxlr); =20 #define __ACCESS_ATTR_RO(_level, _name) { \ .attr =3D { .name =3D __stringify(_name), .mode =3D 0444 }, \ @@ -222,6 +223,45 @@ static struct cxl_region_ref *cxl_rr_load(struct cxl_p= ort *port, return xa_load(&port->regions, (unsigned long)cxlr); } =20 +static bool cxl_region_has_locked_decoder(struct cxl_region *cxlr) +{ + struct cxl_region_params *p =3D &cxlr->params; + int i; + + lockdep_assert_held_write(&cxl_rwsem.region); + + if (cxlr->cxlrd->cxlsd.cxld.flags & CXL_DECODER_F_LOCK) + return true; + + for (i =3D 0; i < p->interleave_ways; i++) { + struct cxl_endpoint_decoder *cxled =3D p->targets[i]; + struct cxl_memdev *cxlmd =3D cxled_to_memdev(cxled); + struct cxl_port *iter =3D cxled_to_port(cxled); + struct cxl_dev_state *cxlds =3D cxlmd->cxlds; + struct cxl_ep *ep; + + if (cxled->cxld.flags & CXL_DECODER_F_LOCK) + return true; + + if (cxlds->rcd) + continue; + + while (!is_cxl_root(to_cxl_port(iter->dev.parent))) + iter =3D to_cxl_port(iter->dev.parent); + + for (ep =3D cxl_ep_load(iter, cxlmd); iter; + iter =3D ep->next, ep =3D cxl_ep_load(iter, cxlmd)) { + struct cxl_region_ref *cxl_rr; + + cxl_rr =3D cxl_rr_load(iter, cxlr); + if (cxl_rr->decoder->flags & CXL_DECODER_F_LOCK) + return true; + } + } + + return false; +} + static int cxl_region_invalidate_memregion(struct cxl_region *cxlr) { if (!cpu_cache_has_invalidate_memregion()) { @@ -243,12 +283,27 @@ static int cxl_region_invalidate_memregion(struct cxl= _region *cxlr) return 0; } =20 -static void cxl_region_decode_reset(struct cxl_region *cxlr, int count) +enum cxl_region_reset_context { + CXL_REGION_RESET_DEFAULT, + CXL_REGION_RESET_MANAGED_DETACH, +}; + +static void cxl_region_decode_reset(struct cxl_region *cxlr, int count, + enum cxl_region_reset_context context) { struct cxl_region_params *p =3D &cxlr->params; int i; =20 - if (test_bit(CXL_REGION_F_LOCK, &cxlr->flags)) + /* + * An attach provider locks a region against userspace disposition, but + * a non-auto attach-owned region is software-owned and needs reset on + * managed detach, unless its decoder path has a genuine hardware lock. + */ + if (test_bit(CXL_REGION_F_LOCK, &cxlr->flags) && + (context !=3D CXL_REGION_RESET_MANAGED_DETACH || + test_bit(CXL_REGION_F_AUTO, &cxlr->flags) || + !cxl_region_has_memdev_attach(cxlr) || + cxl_region_has_locked_decoder(cxlr))) return; =20 /* @@ -350,7 +405,7 @@ static int cxl_region_decode_commit(struct cxl_region *= cxlr) =20 err: /* undo the targets that were successfully committed */ - cxl_region_decode_reset(cxlr, i); + cxl_region_decode_reset(cxlr, i, CXL_REGION_RESET_DEFAULT); return rc; } =20 @@ -449,7 +504,8 @@ static ssize_t commit_store(struct device *dev, struct = device_attribute *attr, * thread already handled this reset. */ if (p->state =3D=3D CXL_CONFIG_RESET_PENDING) { - cxl_region_decode_reset(cxlr, p->interleave_ways); + cxl_region_decode_reset(cxlr, p->interleave_ways, + CXL_REGION_RESET_DEFAULT); p->state =3D CXL_CONFIG_ACTIVE; } =20 @@ -2268,7 +2324,8 @@ static void cxl_cancel_auto_attach(struct cxl_endpoin= t_decoder *cxled) static struct cxl_region * __cxl_decoder_detach(struct cxl_region *cxlr, struct cxl_endpoint_decoder *cxled, int pos, - enum cxl_detach_mode mode) + enum cxl_detach_mode mode, + enum cxl_region_reset_context context) { struct cxl_region_params *p; =20 @@ -2299,7 +2356,8 @@ __cxl_decoder_detach(struct cxl_region *cxlr, cxled->part =3D -1; =20 if (p->state > CXL_CONFIG_ACTIVE) { - cxl_region_decode_reset(cxlr, p->interleave_ways); + cxl_region_decode_reset(cxlr, p->interleave_ways, + context); p->state =3D CXL_CONFIG_ACTIVE; } =20 @@ -2340,23 +2398,25 @@ __cxl_decoder_detach(struct cxl_region *cxlr, * * When the detachment finds a region release the region driver. */ -int cxl_decoder_detach(struct cxl_region *cxlr, - struct cxl_endpoint_decoder *cxled, int pos, - enum cxl_detach_mode mode) +static int cxl_decoder_detach_context( + struct cxl_region *cxlr, struct cxl_endpoint_decoder *cxled, int pos, + enum cxl_detach_mode mode, enum cxl_region_reset_context context) { struct cxl_region *detach; =20 /* when the decoder is being destroyed lock unconditionally */ if (mode =3D=3D DETACH_INVALIDATE) { guard(rwsem_write)(&cxl_rwsem.region); - detach =3D __cxl_decoder_detach(cxlr, cxled, pos, mode); + detach =3D __cxl_decoder_detach(cxlr, cxled, pos, mode, + context); } else { int rc; =20 ACQUIRE(rwsem_write_kill, rwsem)(&cxl_rwsem.region); if ((rc =3D ACQUIRE_ERR(rwsem_write_kill, &rwsem))) return rc; - detach =3D __cxl_decoder_detach(cxlr, cxled, pos, mode); + detach =3D __cxl_decoder_detach(cxlr, cxled, pos, mode, + context); } =20 if (detach) { @@ -2366,6 +2426,14 @@ int cxl_decoder_detach(struct cxl_region *cxlr, return 0; } =20 +int cxl_decoder_detach(struct cxl_region *cxlr, + struct cxl_endpoint_decoder *cxled, int pos, + enum cxl_detach_mode mode) +{ + return cxl_decoder_detach_context(cxlr, cxled, pos, mode, + CXL_REGION_RESET_DEFAULT); +} + static int __attach_target(struct cxl_region *cxlr, struct cxl_endpoint_decoder *cxled, int pos, unsigned int state) @@ -2398,9 +2466,10 @@ static int attach_target(struct cxl_region *cxlr, return rc; } =20 -static int detach_target(struct cxl_region *cxlr, int pos) +static int detach_target(struct cxl_region *cxlr, int pos, + enum cxl_region_reset_context context) { - return cxl_decoder_detach(cxlr, NULL, pos, DETACH_ONLY); + return cxl_decoder_detach_context(cxlr, NULL, pos, DETACH_ONLY, context); } =20 static size_t store_targetN(struct cxl_region *cxlr, const char *buf, int = pos, @@ -2409,7 +2478,7 @@ static size_t store_targetN(struct cxl_region *cxlr, = const char *buf, int pos, int rc; =20 if (sysfs_streq(buf, "\n")) - rc =3D detach_target(cxlr, pos); + rc =3D detach_target(cxlr, pos, CXL_REGION_RESET_DEFAULT); else { struct device *dev; =20 @@ -2559,7 +2628,8 @@ static struct cxl_region *to_cxl_region(struct device= *dev) return container_of(dev, struct cxl_region, dev); } =20 -static void unregister_region(struct cxl_region *cxlr) +static void unregister_region(struct cxl_region *cxlr, + enum cxl_region_reset_context context) { struct cxl_root_decoder *cxlrd =3D to_cxl_root_decoder(cxlr->dev.parent); struct cxl_region_params *p =3D &cxlr->params; @@ -2574,7 +2644,7 @@ static void unregister_region(struct cxl_region *cxlr) * region parameters. */ for (i =3D 0; i < p->interleave_ways; i++) - detach_target(cxlr, i); + detach_target(cxlr, i, context); =20 cxlr->hpa_range =3D DEFINE_RANGE(0, -1); =20 @@ -2589,7 +2659,7 @@ static void endpoint_unregister_region(void *_cxlr) =20 guard(mutex)(&cxlrd->regions_lock); if (xa_load(&cxlrd->regions, cxlr->id)) - unregister_region(cxlr); + unregister_region(cxlr, CXL_REGION_RESET_MANAGED_DETACH); put_device(&cxlr->dev); } =20 @@ -2717,7 +2787,7 @@ void kill_regions(struct cxl_root_decoder *cxlrd) /* no more region creation */ cxlrd->dead =3D true; xa_for_each(&cxlrd->regions, index, cxlr) - unregister_region(cxlr); + unregister_region(cxlr, CXL_REGION_RESET_DEFAULT); } =20 /** @@ -2760,7 +2830,7 @@ static struct cxl_region *devm_cxl_add_region(struct = cxl_root_decoder *cxlrd, =20 rc =3D xa_insert(&cxlrd->regions, cxlr->id, cxlr, GFP_KERNEL); if (rc) { - unregister_region(cxlr); + unregister_region(cxlr, CXL_REGION_RESET_DEFAULT); return ERR_PTR(rc); } =20 @@ -2893,7 +2963,7 @@ static ssize_t delete_region_store(struct device *dev, if (!cxlr || !sysfs_streq(buf, dev_name(&cxlr->dev))) return -ENODEV; =20 - unregister_region(cxlr); + unregister_region(cxlr, CXL_REGION_RESET_DEFAULT); =20 return len; } @@ -3781,7 +3851,7 @@ static struct cxl_region *construct_region(struct cxl= _root_decoder *cxlrd, =20 rc =3D __construct_region(cxlr, ctx); if (rc) { - unregister_region(cxlr); + unregister_region(cxlr, CXL_REGION_RESET_DEFAULT); return ERR_PTR(rc); } =20 --=20 2.43.0 From nobody Fri Oct 2 03:40:52 2026 Received: from BL2PR02CU003.outbound.protection.outlook.com (mail-eastusazon11011045.outbound.protection.outlook.com [52.101.52.45]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 687231A6836; Wed, 5 Aug 2026 07:42:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.52.45 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785915766; cv=fail; b=Y/RHMwr987g5AWamr9seo2JtrtiKXUsz8vFRe3cat//HdXZwxePnM79R0O6uvek1JbEymvsuPnCjl0mZEVIuS9HapviN8sv2UyfXECAvtfXSNqMgO27nITmUy5FVLi51j04QR4F/yQcZt+PtGQ35a13qX74Mb8hCsgTlZVxhrKw= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785915766; c=relaxed/simple; bh=KP3dzmNNzusEoHhBBJbG4Bk6EiuiAIjMN9VqE6VmTDA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=GRBq9oM5zUmEH5B6Ix0gLLViQRkGLResC1sGWYqhTkpg09xROkHueY3kKNoL5KjzTsaoA8kHucN/Oh9hQpLHcmtsqx42V7n/VEGICsYyravyStaB0CzPH7F1tYCVbJSsHDDg5tz1R7RIkLwmz2ved4AHhmDKLFhCtXKVWeSXxVY= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=nvidia.com; spf=fail smtp.mailfrom=nvidia.com; dkim=pass (2048-bit key) header.d=Nvidia.com header.i=@Nvidia.com header.b=uYdPAZ2J; arc=fail smtp.client-ip=52.101.52.45 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=nvidia.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=nvidia.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=Nvidia.com header.i=@Nvidia.com header.b="uYdPAZ2J" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=YP+d/aqbANxYNcsOvU4DHt+gnkslFaba9pwixtaRf3TPuB3OaHZbntBzNO4kqxtvaMfG4l+9L0rjdeEh7qFBdtL5ymPErQKrmRPdifZhzmINjjsyoctqOgVhOjxGpR44ypRXj0Uzs6txgleDWMJ1aARb3jIEcLKds7/857Zh1ZMofTwUogiFVKclC1ON5Qwb0C3R4aPfYwOWw4Wgi+tF9d++243q78Rr4no44sYA8eu3qEkr2cVbJNrCSlrZvRF1coDfTfnOCTZS6Hb6mDqmQlxdlbPU1+t5kgn2fba/UFIUWtzEOyRmtBWgu7pfBWmsaoQTNEHlzzlZ+A4j4qG0hQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=hHRBwOggPoMUs34nxjUN6DWfnq5WVb4zwVPYOdxeDdk=; b=bEcRCRwITHHcjjQA+ooE7jDAj0GrXi9flf4zQJxQjFCuG3o8zlpYot+u2VxR8YBWIQhdlbehY19qsGxL9LI8YDOJYD0VVT7QksyfW0knd26AWRzzavKCeGj3WmI7GiUCZySU/7DgXck5Ww9D80ArtJkyUTP3g0IGn4HWtKAyWjmkvj+6EwqrSduPk6f7+MwD80R37cgDcAFoa3mEqJeyz0IMniukxxVnT2ToE0aAio6H994OKqka7SKbsOurqsOqWSbWeklPbgLnAjwsIwONa66K+rbvEVG6aCy2fhR4UQ8UPI+gzg7FJ/nrsplnxXAwcTAqnWIvrJ9k84q09xCVIg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nvidia.com; dmarc=pass action=none header.from=nvidia.com; dkim=pass header.d=nvidia.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=hHRBwOggPoMUs34nxjUN6DWfnq5WVb4zwVPYOdxeDdk=; b=uYdPAZ2Jstd9UCT3oT+6s3mVPa3wVxD+CAKgeEsxAN0DSIXlN2PbuXrBWalzkPw3nQw3cUlA2FuWAILX2D1HYEzur00Nhwel1hLXcVvR6LvBOrJn0/wECFGHwf+cpvT90nglarzZDtU8wGlIL2FQpXOoZ6kkqO0gieSp6dvXsgaEaygQR017g9ggX0Tp2kQMcl2ymGepZ06Yu2O3/en9UO+YW6Yp8uejsT+JLd3TPmRrSadm79m5jaMwET2MSfoQ4sVXbGXvr2DDNFAdUnWsJqCcpBM1CRXLvRpES2rzZULIK3v9LmzktaC96LXknr43Dk2MwbhhLKC3mLSWPH+utw== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nvidia.com; Received: from MW2PR12MB2380.namprd12.prod.outlook.com (2603:10b6:907:4::32) by LV2PR12MB5966.namprd12.prod.outlook.com (2603:10b6:408:171::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.270.20; Wed, 5 Aug 2026 07:42:38 +0000 Received: from MW2PR12MB2380.namprd12.prod.outlook.com ([fe80::90d:c5c:6a5e:94a5]) by MW2PR12MB2380.namprd12.prod.outlook.com ([fe80::90d:c5c:6a5e:94a5%4]) with mapi id 15.21.0270.017; Wed, 5 Aug 2026 07:42:38 +0000 From: Richard Cheng To: dave@stgolabs.net, jic23@kernel.org, dave.jiang@intel.com, alison.schofield@intel.com, vishal.l.verma@intel.com, djbw@kernel.org Cc: iweiny@kernel.org, ming.li@zohomail.com, gourry@gourry.net, rrichter@amd.com, linux-cxl@vger.kernel.org, linux-kernel@vger.kernel.org, newtonl@nvidia.com, kristinc@nvidia.com, kaihengf@nvidia.com, kobak@nvidia.com, Richard Cheng Subject: [RFC PATCH 2/3] cxl/region: Auto-create a region for memdev attach Date: Wed, 5 Aug 2026 15:40:41 +0800 Message-ID: <20260805074042.30173-3-icheng@nvidia.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20260805074042.30173-1-icheng@nvidia.com> References: <20260805074042.30173-1-icheng@nvidia.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: SI2PR06CA0001.apcprd06.prod.outlook.com (2603:1096:4:186::21) To MW2PR12MB2380.namprd12.prod.outlook.com (2603:10b6:907:4::32) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: MW2PR12MB2380:EE_|LV2PR12MB5966:EE_ X-MS-Office365-Filtering-Correlation-Id: 05c5d3b7-21d0-4cb1-eeea-08def2c51f14 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|23010399003|1800799024|376014|7416014|366016|10067099003|56012099006|11063799006|18002099003|22082099003; X-Microsoft-Antispam-Message-Info: Lf5Oxevuc37L9zjpDwXh+opJJgWd6V/VR3OcRGQm0byPRS3NqkqiBK0+IpD1nnzUaBllFA3srlX//yA/BibfvZRjAw86BC0Kj53j6OiXwPHi615Q+5yNlxrg0s5ShP2vMJsbMa/m8jxcV/BLn0n02YFuWLJXw6UHBud+p0BZc0Yyua4kIzb9TzUFMKbiV/5siQY+AV21eYVomgL3QAZ1JiASKIYTxqFdnbH/QvXOq1n15c0YBzKpenCnq19Bowr++H+yl4TAAh2vzgETEf7VtGV32k3IpVgvjiaMyH1Lcd7i0kVYrE/K0Ri2yKW/13SKomGQlkmx7jEv1n6J3SS+qijoPw27zUELWqaxNS2ugmZFYoqapFvMegx5pJIhheOzMZ4u89bLfszp07ETGVhzlqlOfz9DMAGph2IIlmojyHW6nh/DreqNWf96Ex19c5SYMKT1AJ82xvIK1Wez7XGBHVkvs0BUN2EP6BFqXqSW6aaZe1wiKY5lOHVrUfqzDyyToLNU2dPDObzyTBVsdkMs968m9KxAgyZiNiYvzBss9XCDZgOe5+t8babc2BHjQS/73iFKoa0dZCHPBdgm+1DVw3G1xzolaCKMx73e13krT3BMupA7z6jJg8bkdEL9IBscnfr6k8ERoMFRcRvmonQiakHBstW9XAku0bgaDSHtLqo= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:MW2PR12MB2380.namprd12.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(23010399003)(1800799024)(376014)(7416014)(366016)(10067099003)(56012099006)(11063799006)(18002099003)(22082099003);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?TAlcnEIbpTm5+sPmzDpAJAVIg8zaJvxiU3MZjuov+dmRCbCKI46hBPVg3Xw+?= =?us-ascii?Q?8eGAhNeKy1Osuvi9CBD/rnwjscWKey0YrbXZA1h7Arb4c6jfEEGF1LiJpKL/?= =?us-ascii?Q?jySwix4zi8oBgDTtxcNUnwbs7dlXJYi+dlLrNszLy3hP8e5T0UtNhI4JDI83?= =?us-ascii?Q?YsS0g2qTMmlANw3+3K6ChexgF8FbPrOjDX5oGLAwWZGCpp18PPLft7L2Wif7?= =?us-ascii?Q?/GqXl5OZ/oREWWR9btHK1qFPjsYAhWt84MQqw/KUp4T1vsBFdFy2uGW1PNwz?= =?us-ascii?Q?YVnb8Mtty6s7EbVLdZ7v0Ptt4VIsI44YK5LJqghSuAJ8TsHKWhNPXbenPaBl?= =?us-ascii?Q?kOJwKSChSqdMivMwiAz6WivsKdlLfree9T5IPQSgKGxR3EZYgwEb6cXX7Luc?= =?us-ascii?Q?nPhaYj6TUZDZFlkTgoPL7GySNDlwBP+wzOJ6TJeYQ+uygAYae8E0rH4PCM5X?= =?us-ascii?Q?H9oOUd6DfKcIVG1rm/E/qWNU3Oh2FESaXOoRL2e3q5tT+YDvrD04MFaYyYpz?= =?us-ascii?Q?WiMY2qMNTmZinVFsMSalEvb+0RaTOD4rypvPDmXxPLso8mmjNpFNMw3ZaNgp?= =?us-ascii?Q?bgYP+VTDwKhefZ1dp067HWmPwT6kzEdRmQaz0XWjDyXxLb+TA8geh/7OPVbY?= =?us-ascii?Q?U71f7c9iyPBYSnVM5mE0BV6JHwQQIsY+wnQDj2x15tJJs8rz5Uwro+f0QqfJ?= =?us-ascii?Q?iAEIbL+NJq3eJGv922Zkhh6lpDpED4SNKYlLxTQfuk9ZKE53ZgHvDfSnSO07?= =?us-ascii?Q?kk/jUeY8R9Fz2P3LJfHYxCLDqwMtRF5NZsRJwh700P4czTbGPNnuTM6clvkd?= =?us-ascii?Q?04eglw7c1ig+Qt837Wg/sKY951BJn2gE9GizgOFU82wSuJ9GFsva1cYiMhiI?= =?us-ascii?Q?1fr8rtFZ/RC8uJiN6452+BtdRUb9WVy/R3FpIk+NcapqeirM2UgVA3c2J34S?= =?us-ascii?Q?77sYXfXraBbMjzMPgxomLK5ory391CusRLIFLDTqKAqNEhu98GeRjqG8xbbd?= =?us-ascii?Q?WJ152/DK0H6SmRvzCgYCeQhV9mIu+5rwLXIMHyHzGQUsBm4OFwlBW8qCQHyF?= =?us-ascii?Q?C43+l7Zu+MaT456yORjXkW0+TvXTPGmcBsF55amkjSJFHSo8UPvULEjECaAa?= =?us-ascii?Q?jFmCc/5cS2Ur4Z7ZGWNyA16UHWkur8wWWyfq9f8EzU4peGs9vN3wSBGc8AtD?= =?us-ascii?Q?raWCEHzcoMz0IMnq85789Nr/c/c6wJGyCdmt4UF5u7pR/+Zw2jEjmLXJ0sK8?= =?us-ascii?Q?blsetZzL22MJLF0HwwJ8pkPNxhgtDALcYp+fjuJLtPriMl6wZVJKCR8i3XqS?= =?us-ascii?Q?WmRwSpS535tKRXvcLRPsK415lFnRCkipjgmCB1+GTQg/k89GZDsXqTac8C6f?= =?us-ascii?Q?f2S/nIsh+6y0gRNFrOT4tkBSG/96fsW5ga5h0N5gyJRqmemWlISK6YPIaJdZ?= =?us-ascii?Q?cE55CCdF0cpmoxTE4I6nXu94Kr9NMjKinvTN38ylDF0aVQEbdEXH1yv2aVqU?= =?us-ascii?Q?LBn3GGdE4uea9Z6z/hR+EXA4iX7y5c2jhlwCKdfQnBnDGg8V+iPF/PdBDiJr?= =?us-ascii?Q?ZE94qpN0FLECoXz4cSh6ac5eQH1fsRXdDlaKOYJVpa+2zrK2sdK7eS7B7oxE?= =?us-ascii?Q?LXotq7NMdV0qUgDr2XQC8A/WgE21MCorv4UqqUni71HJz0xvET8Ru3D+sXDK?= =?us-ascii?Q?/+Yx7U4oeEIDbHTONEkgpVYK+Za05VA4pe6PjLLIcfZ4f2EVrdhH5GQm/FJV?= =?us-ascii?Q?djy9dGtgGw=3D=3D?= X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-Network-Message-Id: 05c5d3b7-21d0-4cb1-eeea-08def2c51f14 X-MS-Exchange-CrossTenant-AuthSource: MW2PR12MB2380.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 05 Aug 2026 07:42:38.1537 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: UeoKGtuNcbQ623jvfufPRe/S0jQz6jW3kQ9xpR8DsIMvD+2RocJVh0VyF79jT/o5aVlL4+VzBid4apU3qrGUQQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: LV2PR12MB5966 Content-Type: text/plain; charset="utf-8" devm_cxl_probe_mem() currently fails when FW has not committed a region, even when a Type-2 accelerator has usable CXL.mem capacity. When no mapped decoder exists, select a pristine manual DEVMEM decoder and the first compatible unlocked Type-2 RAM root decoder. Create a non-AUTO, single-target region, allocate HPA and the full volatile DPA partition, attach and commit the decoder path, then return the resulting HPA range. Use provider-managed reset for partial-commit rollback and unwind region, HPA, DPA, and partition state in reverse order on failure. Preserve the existing FW-precommitted path. This support is limited to decoder 0, IW=3D1, and first-compatible root selection. Signed-off-by: Richard Cheng --- drivers/cxl/core/region.c | 312 ++++++++++++++++++++++++++++++++++---- 1 file changed, 284 insertions(+), 28 deletions(-) diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c index 7fcaddc61180..4ceabdfdd3b6 100644 --- a/drivers/cxl/core/region.c +++ b/drivers/cxl/core/region.c @@ -363,7 +363,8 @@ static int commit_decoder(struct cxl_decoder *cxld) return 0; } =20 -static int cxl_region_decode_commit(struct cxl_region *cxlr) +static int cxl_region_decode_commit( + struct cxl_region *cxlr, enum cxl_region_reset_context context) { struct cxl_region_params *p =3D &cxlr->params; int i, rc =3D 0; @@ -405,7 +406,7 @@ static int cxl_region_decode_commit(struct cxl_region *= cxlr) =20 err: /* undo the targets that were successfully committed */ - cxl_region_decode_reset(cxlr, i, CXL_REGION_RESET_DEFAULT); + cxl_region_decode_reset(cxlr, i, context); return rc; } =20 @@ -427,7 +428,8 @@ static int queue_reset(struct cxl_region *cxlr) return 0; } =20 -static int __commit(struct cxl_region *cxlr) +static int __commit_context(struct cxl_region *cxlr, + enum cxl_region_reset_context context) { struct cxl_region_params *p =3D &cxlr->params; int rc; @@ -452,7 +454,7 @@ static int __commit(struct cxl_region *cxlr) if (rc) return rc; =20 - rc =3D cxl_region_decode_commit(cxlr); + rc =3D cxl_region_decode_commit(cxlr, context); if (rc) return rc; =20 @@ -461,6 +463,11 @@ static int __commit(struct cxl_region *cxlr) return 0; } =20 +static int __commit(struct cxl_region *cxlr) +{ + return __commit_context(cxlr, CXL_REGION_RESET_DEFAULT); +} + static ssize_t commit_store(struct device *dev, struct device_attribute *a= ttr, const char *buf, size_t len) { @@ -4177,45 +4184,271 @@ static int first_mapped_decoder(struct device *dev= , const void *data) return 0; } =20 +static int first_attach_decoder(struct device *dev, const void *data) +{ + struct cxl_port *endpoint =3D (struct cxl_port *)data; + struct cxl_endpoint_decoder *cxled; + struct cxl_decoder *cxld; + + if (!is_endpoint_decoder(dev)) + return 0; + + cxled =3D to_cxl_endpoint_decoder(dev); + cxld =3D &cxled->cxld; + if (cxld->id !=3D 0 || cxled->state !=3D CXL_DECODER_STATE_MANUAL || + cxld->target_type !=3D CXL_DECODER_DEVMEM || cxld->region || + cxled->dpa_res || + (cxld->flags & (CXL_DECODER_F_ENABLE | CXL_DECODER_F_LOCK))) + return 0; + + if (endpoint->hdm_end !=3D -1 || cxl_num_decoders_committed(endpoint)) + return 0; + + return 1; +} + +static int first_attach_root_decoder(struct device *dev, const void *data) +{ + struct cxl_port *endpoint =3D (struct cxl_port *)data; + unsigned long required =3D CXL_DECODER_F_TYPE2 | CXL_DECODER_F_RAM | + CXL_DECODER_F_ENABLE; + struct cxl_root_decoder *cxlrd; + struct cxl_switch_decoder *cxlsd; + struct cxl_decoder *cxld; + struct cxl_dport *dport; + + if (!is_root_decoder(dev) || !device_is_registered(dev)) + return 0; + + cxlrd =3D to_cxl_root_decoder(dev); + cxlsd =3D &cxlrd->cxlsd; + cxld =3D &cxlsd->cxld; + if (cxlrd->dead || !cxlrd->res || + (cxld->flags & required) !=3D required || + (cxld->flags & CXL_DECODER_F_LOCK) || + cxld->interleave_ways !=3D 1 || cxlsd->nr_targets < 1) + return 0; + + dport =3D cxl_find_dport_by_dev(cxlrd_to_port(cxlrd), + endpoint->host_bridge); + return dport && cxlsd->target[0] =3D=3D dport; +} + +static struct cxl_root_decoder * +find_attach_root_decoder(struct cxl_endpoint_decoder *cxled) +{ + struct cxl_port *endpoint =3D cxled_to_port(cxled); + struct cxl_root *root __free(put_cxl_root) =3D find_cxl_root(endpoint); + struct device *dev; + + if (!root) + return ERR_PTR(-ENXIO); + + /* First compatible x1 Type-2 window is strict v1 policy. */ + dev =3D device_find_child(&root->port.dev, endpoint, + first_attach_root_decoder); + if (!dev) + return ERR_PTR(-ENXIO); + + return to_cxl_root_decoder(dev); +} + +static void restore_attach_decoder_part(struct cxl_endpoint_decoder *cxled, + int old_part) +{ + guard(rwsem_write)(&cxl_rwsem.dpa); + cxled->part =3D old_part; +} + +static int select_attach_ram(struct cxl_endpoint_decoder *cxled, + int *old_part, resource_size_t *size) +{ + struct cxl_memdev *cxlmd =3D cxled_to_memdev(cxled); + struct cxl_dev_state *cxlds =3D cxlmd->cxlds; + struct resource *res; + int part, rc; + + scoped_guard(rwsem_read, &cxl_rwsem.dpa) + *old_part =3D cxled->part; + + rc =3D cxl_dpa_set_part(cxled, CXL_PARTMODE_RAM); + if (rc) + return rc; + + guard(rwsem_read)(&cxl_rwsem.dpa); + part =3D cxled->part; + if (part < 0 || part >=3D cxlds->nr_partitions) + return -ENXIO; + + res =3D &cxlds->part[part].res; + if (res->child) + return -EBUSY; + + *size =3D resource_size(res); + if (!*size || !IS_ALIGNED(*size, SZ_256M)) + return -EINVAL; + + return 0; +} + +static struct cxl_region * +create_attach_region(struct cxl_endpoint_decoder *cxled, + struct cxl_root_decoder *cxlrd, resource_size_t size) +{ + struct cxl_region *cxlr; + int rc; + + guard(mutex)(&cxlrd->regions_lock); + do { + cxlr =3D __create_region(cxlrd, CXL_PARTMODE_RAM, + atomic_read(&cxlrd->region_id), + CXL_DECODER_DEVMEM); + } while (IS_ERR(cxlr) && PTR_ERR(cxlr) =3D=3D -EBUSY); + if (IS_ERR(cxlr)) + return cxlr; + + scoped_guard(rwsem_write, &cxl_rwsem.region) { + /* Single-target IW=3D1 is strict v1 policy. */ + rc =3D set_interleave_ways(cxlr, 1); + if (!rc) + rc =3D set_interleave_granularity( + cxlr, CXL_DECODER_MIN_GRANULARITY); + if (!rc) + rc =3D alloc_hpa(cxlr, size); + } + if (rc) + goto err_unregister; + + rc =3D cxl_dpa_alloc(cxled, size); + if (rc) + goto err_unregister; + + rc =3D attach_target(cxlr, cxled, 0, TASK_UNINTERRUPTIBLE); + if (rc) + goto err_unregister; + + rc =3D __commit_context(cxlr, CXL_REGION_RESET_MANAGED_DETACH); + if (rc) + goto err_unregister; + + rc =3D device_attach(&cxlr->dev); + if (rc <=3D 0) { + if (!rc) + rc =3D -ENXIO; + goto err_unregister; + } + + get_device(&cxlr->dev); + return cxlr; + +err_unregister: + unregister_region(cxlr, CXL_REGION_RESET_MANAGED_DETACH); + return ERR_PTR(rc); +} + +static void cleanup_attach_dpa(struct cxl_endpoint_decoder *cxled, + int old_part, int setup_rc) +{ + int rc; + + rc =3D cxl_dpa_free(cxled); + if (rc) + dev_err(&cxled->cxld.dev, + "failed to clean up DPA after attach error %d: %d\n", + setup_rc, rc); + restore_attach_decoder_part(cxled, old_part); +} + +static int create_memdev_attach_region(struct cxl_memdev *cxlmd, + struct cxl_attach_region *attach) +{ + struct cxl_port *endpoint =3D cxlmd->endpoint; + struct device *decoder_dev __free(put_device) =3D NULL; + struct cxl_endpoint_decoder *cxled; + struct cxl_root_decoder *cxlrd; + struct cxl_region *cxlr; + struct range hpa_range; + resource_size_t size; + int old_part, rc; + + scoped_guard(rwsem_read, &cxl_rwsem.region) { + guard(rwsem_read)(&cxl_rwsem.dpa); + decoder_dev =3D device_find_child(&endpoint->dev, endpoint, + first_attach_decoder); + } + if (!decoder_dev) { + dev_dbg(cxlmd->cxlds->dev, + "no free manual DEVMEM decoder to auto-create a region for %s\n", + dev_name(&cxlmd->dev)); + return -ENXIO; + } + cxled =3D to_cxl_endpoint_decoder(decoder_dev); + + rc =3D select_attach_ram(cxled, &old_part, &size); + if (rc) { + restore_attach_decoder_part(cxled, old_part); + return rc; + } + + cxlrd =3D find_attach_root_decoder(cxled); + if (IS_ERR(cxlrd)) { + rc =3D PTR_ERR(cxlrd); + dev_dbg(cxlmd->cxlds->dev, + "no compatible Type-2 root decoder to auto-create a region for %s: %d\n= ", + dev_name(&cxlmd->dev), rc); + goto err_cleanup_dpa; + } + + cxlr =3D create_attach_region(cxled, cxlrd, size); + put_device(&cxlrd->cxlsd.cxld.dev); + if (IS_ERR(cxlr)) { + rc =3D PTR_ERR(cxlr); + goto err_cleanup_dpa; + } + + hpa_range =3D (struct range) { + .start =3D cxlr->params.res->start, + .end =3D cxlr->params.res->end, + }; + rc =3D devm_add_action_or_reset(&endpoint->dev, + endpoint_unregister_region, cxlr); + if (rc) + goto err_cleanup_dpa; + + attach->hpa_range =3D hpa_range; + return 0; + +err_cleanup_dpa: + cleanup_attach_dpa(cxled, old_part, rc); + return rc; +} + /* - * Runs in cxl_mem_probe context after successful endpoint probe, assumes = the - * simple case of single mapped decoder per memdev. + * Attach to a firmware-precommitted region already mapped to the endpoint. + * Return 0 on success, -ENODEV when no region is present (the caller then + * auto-creates one), or a negative errno for a present-but-unusable regio= n. */ -int cxl_memdev_attach_region(struct cxl_memdev *cxlmd) +static int find_committed_attach_region(struct cxl_memdev *cxlmd, + struct cxl_attach_region *attach) { - struct cxl_attach_region *attach =3D - container_of(cxlmd->attach, typeof(*attach), attach); struct cxl_port *endpoint =3D cxlmd->endpoint; struct cxl_endpoint_decoder *cxled; struct cxl_region *cxlr; int rc; =20 - /* hold endpoint lock to setup autoremove of the region */ - guard(device)(&endpoint->dev); - if (!endpoint->dev.driver) - return -ENXIO; guard(rwsem_read)(&cxl_rwsem.region); guard(rwsem_read)(&cxl_rwsem.dpa); - - /* - * TODO auto-instantiate a region, for now assume this will find an - * auto-region - */ struct device *dev __free(put_device) =3D device_find_child(&endpoint->dev, NULL, first_mapped_decoder); =20 - if (!dev) { - dev_dbg(cxlmd->cxlds->dev, "no region found for memdev %s\n", - dev_name(&cxlmd->dev)); - return -ENXIO; - } + if (!dev) + return -ENODEV; =20 cxled =3D to_cxl_endpoint_decoder(dev); cxlr =3D cxled->cxld.region; =20 if (cxlr->params.state < CXL_CONFIG_COMMIT) { - dev_dbg(cxlmd->cxlds->dev, - "region %s not committed for memdev %s\n", + dev_dbg(cxlmd->cxlds->dev, "region %s not committed for memdev %s\n", dev_name(&cxlr->dev), dev_name(&cxlmd->dev)); return -ENXIO; } @@ -4226,10 +4459,10 @@ int cxl_memdev_attach_region(struct cxl_memdev *cxl= md) return -ENXIO; } =20 - /* Only teardown regions that pass validation, ignore the rest */ + /* Only teardown regions that pass validation. */ get_device(&cxlr->dev); - rc =3D devm_add_action_or_reset(&endpoint->dev, - endpoint_unregister_region, cxlr); + rc =3D devm_add_action_or_reset(&endpoint->dev, endpoint_unregister_regio= n, + cxlr); if (rc) return rc; =20 @@ -4239,6 +4472,29 @@ int cxl_memdev_attach_region(struct cxl_memdev *cxlm= d) }; return 0; } + +/* + * Runs in cxl_mem_probe context after successful endpoint probe, assumes = the + * simple case of single mapped decoder per memdev. + */ +int cxl_memdev_attach_region(struct cxl_memdev *cxlmd) +{ + struct cxl_attach_region *attach =3D + container_of(cxlmd->attach, typeof(*attach), attach); + struct cxl_port *endpoint =3D cxlmd->endpoint; + int rc; + + /* hold endpoint lock to setup autoremove of the region */ + guard(device)(&endpoint->dev); + if (!endpoint->dev.driver) + return -ENXIO; + + rc =3D find_committed_attach_region(cxlmd, attach); + if (rc !=3D -ENODEV) + return rc; + + return create_memdev_attach_region(cxlmd, attach); +} EXPORT_SYMBOL_FOR_MODULES(cxl_memdev_attach_region, "cxl_mem"); =20 /* --=20 2.43.0 From nobody Fri Oct 2 03:40:52 2026 Received: from SN4PR2101CU001.outbound.protection.outlook.com (mail-southcentralusazon11012035.outbound.protection.outlook.com [40.93.195.35]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6CB2D3515E6; Wed, 5 Aug 2026 07:42:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.93.195.35 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785915775; cv=fail; b=HrXsemECCO+aW4MzjpcJh4QZmL4zv0AKd3oi6rewDrJffh1TFWo/d6zvzaBM93hxDvdQkfbPVJfB8oYWI8U3NdDGJxerWPqYVibXvQaSTcQnNMtVNyiAH94gVYEHgd6KfqEvqyliMB17KjzbVNvZsvXTJRJjGndO8v9v0NnoXhM= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785915775; c=relaxed/simple; bh=EZHms4qXVef8tti30Rkm08wj93+uPFIHzLwbYNMyogc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=Nefb3XdRQ7IGEgkMo97XubCwWstaPTFbN/Q9dv20f24uqTpvjsewnDvusaw9dpcrADXUFmI1jVSVowyRFwbVoq/BgNwLGGPCgMujqOLY9k7zd/xKdGsUPjQp99AtfWhj5fTRqU+WErcw/TDXQ/twWFqZKpGl9LyBfxtC375ATQQ= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=nvidia.com; spf=fail smtp.mailfrom=nvidia.com; dkim=pass (2048-bit key) header.d=Nvidia.com header.i=@Nvidia.com header.b=sLhHqdfE; arc=fail smtp.client-ip=40.93.195.35 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=nvidia.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=nvidia.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=Nvidia.com header.i=@Nvidia.com header.b="sLhHqdfE" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=yjJyElFTP1oxD9xwbV9okPNv2Ke+kDWzu+USxB6G8bYzGTbL0a0UU5pus+DygKC0asDcM2k+/gsbLWkzpNLU5GD3NJgBip9M4NlBrTSadRCaaDTjfPRW+6+CtP30Wv+aYQTc+mKy0EuUdNAUIV1yTa4YXXdBlHk5at1wg+YgqZ7J1021fasPaLPYQUb6rvUaFJAcYp7DiogKm2xf7Bbx4DjjbBrx+8SzQ+uNAbhJjZ5IIcVX217IEb38A04lgWnSJB3malhPdtfhlsWa10+y63xeO+IhJdZidxE54sIEKD/svQwQymbgNKZ+pZ0mNC1iNWe8EOLFrxzYAMftNgjI9Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=ciXtTSUApIRZK32G5tnpo7fNyWW4dwzCK7k1Zh315IM=; b=MyMLZpJ3gyHP0Yd/zm1GjPV11ZUE8UGOXcM+I8VuFo0zqL0oE46GV1JwkkV1eVV2ncp0NL2q9o5OCusPVc4a9tRoGpEqvtxzYNtv13/sI05aFbPnPcw+2jrbWsqCma63NI5q9ZHP9aychjwSo8MrdBHJOerRmvri4J2yNwpbGg5gpmr1GZ+l372nyvhj1NHoS0f34Ytldcw6P3MZtTDf0pMWijTMvFQutZ5839dfdJypm6cQvCsWxCKOx9/TwQongXVUs16JUsIW5JTnMMOiCMODq407UTlF1szk/pKNkoQnPI3MTC4IeKlrYFpFCyht9Ch5JBaGMb7KP2IA3/gHUA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nvidia.com; dmarc=pass action=none header.from=nvidia.com; dkim=pass header.d=nvidia.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=ciXtTSUApIRZK32G5tnpo7fNyWW4dwzCK7k1Zh315IM=; b=sLhHqdfEbQywCzwRG7raxWhdfHfXF/o0J38JT3SBAAmInEs2AvaFtyM4bMVwmy3gV0h5YpVusXBo5jtdhHc7VNoojpG8Iy/bh07fPkXxEwJ/wzTl9FX9qRtKorXo26E5NnOB/blaUTjYTkIGRnziKX+jIVAuO+3fpEJ4a3UybfdlYD9f7+Q3uYHrjmST9RTorIjG3LUJJigpM+AzTk+rmHPN1ldZJVksG2FA4nOnofgjTY9VfX5MvJTBRcNiam3yWk3V2p3PjjaQd/QdpfyNOOO/wXlM9KIU56oBrTb3Ho4ZTpoWIYb2sOf28N6H6La2HaF5iT/EbObEAKBmlgYVJg== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nvidia.com; Received: from MW2PR12MB2380.namprd12.prod.outlook.com (2603:10b6:907:4::32) by LV2PR12MB5966.namprd12.prod.outlook.com (2603:10b6:408:171::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.270.20; Wed, 5 Aug 2026 07:42:49 +0000 Received: from MW2PR12MB2380.namprd12.prod.outlook.com ([fe80::90d:c5c:6a5e:94a5]) by MW2PR12MB2380.namprd12.prod.outlook.com ([fe80::90d:c5c:6a5e:94a5%4]) with mapi id 15.21.0270.017; Wed, 5 Aug 2026 07:42:49 +0000 From: Richard Cheng To: dave@stgolabs.net, jic23@kernel.org, dave.jiang@intel.com, alison.schofield@intel.com, vishal.l.verma@intel.com, djbw@kernel.org Cc: iweiny@kernel.org, ming.li@zohomail.com, gourry@gourry.net, rrichter@amd.com, linux-cxl@vger.kernel.org, linux-kernel@vger.kernel.org, newtonl@nvidia.com, kristinc@nvidia.com, kaihengf@nvidia.com, kobak@nvidia.com, Richard Cheng Subject: [RFC PATCH 3/3] cxl/test: Exercise Type-2 automatic region creation Date: Wed, 5 Aug 2026 15:40:42 +0800 Message-ID: <20260805074042.30173-4-icheng@nvidia.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20260805074042.30173-1-icheng@nvidia.com> References: <20260805074042.30173-1-icheng@nvidia.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: JH0PR01CA0096.apcprd01.prod.exchangelabs.com (2603:1096:990:58::10) To MW2PR12MB2380.namprd12.prod.outlook.com (2603:10b6:907:4::32) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: MW2PR12MB2380:EE_|LV2PR12MB5966:EE_ X-MS-Office365-Filtering-Correlation-Id: 9c31873c-6d7e-4ea1-d5a4-08def2c525a5 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|23010399003|1800799024|376014|7416014|366016|10067099003|56012099006|11063799006|6133799003|3023799007|18002099003|22082099003; X-Microsoft-Antispam-Message-Info: T/hRp59bBvAlXYtz2z1fY6JAV6ZPcWtrkz4HQP+UzxcHnkrCtOPtVAjn7VgEBrNkgsHgoYkqr+tFe3tmncp7eaTyzjy3MyJ7cJzRsFiTbns2JO2U8BeBD3y5alYgGdFtyG56NYjCLcTLmtuKtW73WlE8/qPfOMH6UM6axRtzaXIup+RP0a/B7MvkBuNFzLf3ZtcbjTz2GqdI62Dto75Zu0F1sHhe6gZB+zyy7tpS2EeZGvP4t2SUV+0yHMvfLa/xYfSU2EedaYTfF1byL/sz6UBjXb0Ne2rtv47A5868ctJDH/u7tzGwhDJOUigRMOaA6mgiMOfg/irz8zaax9qIIPdK9ynGSXPfg+GGirbo+mGnNAwb2x8YLNgTVLk7onscl50AYsjnhoXFw5uOabmQyfx6NzKrmVU0v0FewWC3SF8Elv8KSclGeuth92MTOgI84iScmkzuVmiXj2jHFS+UwwlgI71uDQSPPItmpUFqbTPr1JEQAtiuyKqhJ5tCSvM2JkSK90gE+gbAydr9DaF7pWsXvQkdNf0jtFKmnWkIVFGE5Lq0ECB8tJnWls9iXqZqPrMYjNnARUzLROhODM1jJk3WHMYKl6H3ZNo9gv2TVBZPndSyK0lN4mmS5GXrLkpKbnDFjxaUCHVbfSpG7hOyHRGZEE5A72Vtt4ZzNvWpBTI= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:MW2PR12MB2380.namprd12.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(23010399003)(1800799024)(376014)(7416014)(366016)(10067099003)(56012099006)(11063799006)(6133799003)(3023799007)(18002099003)(22082099003);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?82lgNC4gP4ITv5iaFRPOucPtDgJkNiYuxmlEoePZw/j3BB/ErDVUaLS0r2f+?= =?us-ascii?Q?FajoS0hMD21V6W4Ro7fWM5RhVIDoMFi7cyHwH28ExcILueZkG9Q9+ZmLN87M?= =?us-ascii?Q?S8Kyo++v9lFAVDxgPN9SBMmhWFo0wbR7Mom2t+MwXuQryyMGQkpTr8BYO1su?= =?us-ascii?Q?u8ZFR0+gCnIO59Ewt/K1w2YONCm9RdO10ouQLPkiyM3cAZZ5CVkxaA+R27rI?= =?us-ascii?Q?4niiFn05oZlenQWiKWlgSTtSmSnmVD09GkA6nolILBOKxr60seCag7SpFGZt?= =?us-ascii?Q?snhYu9VhylPInO/NCzS9xqpNNUovJ7D6pkeN/NjZzyrFYRQ6z9iENxOeaJC0?= =?us-ascii?Q?qbaGJSQr4wq+vHz5k51GG2zXznROry2/XSqkP/HYWaQ66jvZs+doEnM0r1Yr?= =?us-ascii?Q?R42RaOGFehQULtL7gO7Fho9wrysgFu/MxPqmA3O2EFowP9JIV+0L4DyWP29Q?= =?us-ascii?Q?qDBho3EvN4Xtd0B3FDyKsNc8egEWEKzPyrmN718Q9CjHiBwvaRDtbqyNtbgm?= =?us-ascii?Q?GbQXHvLUIhVl9Vj0CA/h9pAhetCxiKZIwdQ/7wCsr9xTOyeYC672kI3YeYPO?= =?us-ascii?Q?NC6XkiOTddgDRj4CnqFdeAnAL5igzOpsrOcvy53Ug15LUq9tbhDkP+tSwz/T?= =?us-ascii?Q?oT5yLwxxu+VQGMR+UOksM4irm8Uhe16Uf9mHviKNdBeAg1INKZu37mjqI29G?= =?us-ascii?Q?d1t4M/gjDWvZTb0ImR35SXEBr4s4ehRB8kduQSDiT6RH16KTfn6tUpHGl0G5?= =?us-ascii?Q?U4a2jW9o9v1vGfgz72scBUT1C8nyb9jmU3t2a3N5tNIp7OPU7bZHjSdXlojh?= =?us-ascii?Q?rlWP0StYD2Ju3PqM1J5XN6JcNQbb3EvfhuM/huHq+Hk+02tRsxPrAae5WM7t?= =?us-ascii?Q?jzB8eU59yKRmX6VgAjB3+YP8Omza2Obt0CbwoL4eYkIXe7BjO1VVbD7eH3+s?= =?us-ascii?Q?NYhSjFqFAcgu4UzNecgaPSlh4zK53yXq5otWSca/zbkkxLOKtU8SFXdp+kPf?= =?us-ascii?Q?xk7VEBpxnqV1IsCe1V4jrdRpoWKPHWJCRF9leGW+XhRWEbp/UbsdhKjJ1Pz6?= =?us-ascii?Q?q5rA6KyEhJmcz8xA80eqcNNZeMr0OoF6XYN7D/z58+Xh52Hc8G3JgfBVifZy?= =?us-ascii?Q?G7DUdZ7d7nOrQyRMlj4Xzf2aWq5/5v74MGgzSUidj2PRDe3UBNGnkWzJTnTv?= =?us-ascii?Q?SF+qeCy1jtLqa238YQJPmgx1kSYRFABWWfgg+pTwyx8CGud2fcQ5jYEaJgNs?= =?us-ascii?Q?VrpRsuDtZ/a43aPT8L3Wt3Jk2IwEFWSBWrPauAAUbOfjiI4XN8RM1Pe3dsMP?= =?us-ascii?Q?te5WXSDdqv1XQLSQGkAhvU7/SIwVbdmgNBWxWJOdCMiJT4sk0P78YAb+11aC?= =?us-ascii?Q?9zjnX7RsKqeY6HPFXPotabeF5B+vFkKnJaLrBVmcJwwRxKN8MeJalKDdm5G1?= =?us-ascii?Q?37gIvTA/8d2di/Eo9gA9hkspiCieCsPOlA34Yqrm/nSznjIBgY0i3DFmbuZ6?= =?us-ascii?Q?4vT47U8a90xwE6L7wkuxxhaVTlR68iWhzW/FNDT8kOZoEvBpbs20+K5WFUGC?= =?us-ascii?Q?rPlf64srbF2wVBEsUFcn7sc1CDokpkNsjbteRV1WxHGlybcfnbFmrdUD2flh?= =?us-ascii?Q?pHOYsiWweiKU+e+4r1XygPiQJ5uoz2KDt+YYGLZPVoRnCLby5XFZTfokedxO?= =?us-ascii?Q?kMtbLBl4Ww16laXlSP9tZfc95jccKFzyIrAqHpfSAd2Cqh7rLL05BjGUO+pS?= =?us-ascii?Q?uwcIuevRaQ=3D=3D?= X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-Network-Message-Id: 9c31873c-6d7e-4ea1-d5a4-08def2c525a5 X-MS-Exchange-CrossTenant-AuthSource: MW2PR12MB2380.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 05 Aug 2026 07:42:49.1062 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: Ob9i6BG/LtHC2lik01xgUgDjyj2fyR4u2ph7zg9UBaXVqpLlz9jsxEfXiY5cRc4XX+UWKL9ooey1fGidLby6yQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: LV2PR12MB5966 Content-Type: text/plain; charset="utf-8" Add a second mock Type-2 accelerator with an independent single-target CFMWS and an uncommitted manual DEVMEM decoder. Keep the existing FW-precomitted accelerator unchanged. Verify that devm_cxl_probe_mem() creates the missing region and returns a valid 512 MB HPA range. Preserve the manual decoder config after reset so the fallback remains available across unbind and rebind. Signed-off-by: Richard Cheng --- tools/testing/cxl/test/accel.c | 7 ++++ tools/testing/cxl/test/cxl.c | 61 ++++++++++++++++++++++++++++++++-- 2 files changed, 65 insertions(+), 3 deletions(-) diff --git a/tools/testing/cxl/test/accel.c b/tools/testing/cxl/test/accel.c index 8e6f4687ca02..7e5d76a7f8c4 100644 --- a/tools/testing/cxl/test/accel.c +++ b/tools/testing/cxl/test/accel.c @@ -38,6 +38,13 @@ static int cxl_mock_accel_probe(struct platform_device *= pdev) cxlmd =3D devm_cxl_probe_mem(cxlds, &mock_range); if (IS_ERR(cxlmd)) return PTR_ERR(cxlmd); + if (mock_range.start > mock_range.end || + range_len(&mock_range) !=3D SZ_512M) { + dev_err(dev, + "accelerator%d returned invalid HPA range %pra (expected 512 MiB)\n", + pdev->id, &mock_range); + return -ERANGE; + } cxl_accel->cxlmd =3D cxlmd; =20 dev_dbg(dev, "Probed mock accelerator with range %pra\n", &mock_range); diff --git a/tools/testing/cxl/test/cxl.c b/tools/testing/cxl/test/cxl.c index 8ab2ce1262f3..305a0c3705da 100644 --- a/tools/testing/cxl/test/cxl.c +++ b/tools/testing/cxl/test/cxl.c @@ -28,7 +28,7 @@ static bool type2_test; #define NR_CXL_SWITCH_PORTS 2 #define NR_CXL_PORT_DECODERS 8 #define NR_BRIDGES (NR_CXL_HOST_BRIDGES + NR_CXL_SINGLE_HOST + NR_CXL_RCH) -#define NR_CXL_TYPE2_ACCEL 1 +#define NR_CXL_TYPE2_ACCEL 2 =20 #define MOCK_AUTO_REGION_SIZE_DEFAULT SZ_512M static int mock_auto_region_size =3D MOCK_AUTO_REGION_SIZE_DEFAULT; @@ -493,7 +493,16 @@ static void cfmws_elc_update(struct acpi_cedt_cfmws *w= indow, int index) =20 static void update_type2_cfmws(void) { + struct acpi_cedt_cfmws *window =3D &mock_cedt.cfmws1.cfmws; + memcpy(&mock_cedt.cfmws0.cfmws, &type2_cfmws0, sizeof(type2_cfmws0)); + + window->header.length =3D sizeof(*window) + + sizeof(mock_cedt.cfmws1.target[0]); + window->interleave_ways =3D 0; + window->restrictions =3D ACPI_CEDT_CFMWS_RESTRICT_DEVMEM | + ACPI_CEDT_CFMWS_RESTRICT_VOLATILE; + mock_cedt.cfmws1.target[0] =3D 1; } =20 static int populate_cedt(void) @@ -814,6 +823,32 @@ static int mock_decoder_commit(struct cxl_decoder *cxl= d); static void mock_decoder_reset(struct cxl_decoder *cxld); static void init_disabled_mock_decoder(struct cxl_decoder *cxld); =20 +static bool is_type2_manual_decoder(struct cxl_decoder *cxld, + struct platform_device *pdev) +{ + return type2_test && is_endpoint_decoder(&cxld->dev) && pdev && + pdev->id =3D=3D 1 && !strcmp(pdev->name, "cxl_type2_accel") && + cxld->id =3D=3D 0; +} + +static void init_type2_manual_decoder(struct cxl_endpoint_decoder *cxled) +{ + struct cxl_decoder *cxld =3D &cxled->cxld; + + cxld->hpa_range =3D (struct range) { + .start =3D 0, + .end =3D -1, + }; + cxld->interleave_ways =3D 1; + cxld->interleave_granularity =3D CXL_DECODER_MIN_GRANULARITY; + cxld->target_type =3D CXL_DECODER_DEVMEM; + cxld->flags =3D 0; + cxled->state =3D CXL_DECODER_STATE_MANUAL; + cxled->skip =3D 0; + cxld->commit =3D mock_decoder_commit; + cxld->reset =3D mock_decoder_reset; +} + static void cxld_copy(struct cxl_decoder *a, struct cxl_decoder *b) { a->id =3D b->id; @@ -1089,6 +1124,7 @@ enum cxld_init_type { MOCK_DECODER_INIT_SAVED, MOCK_DECODER_INIT_TYPE3_AUTO, MOCK_DECODER_INIT_TYPE2_AUTO, + MOCK_DECODER_INIT_TYPE2_MANUAL, }; =20 static enum cxld_init_type get_decoder_init_type(struct cxl_decoder *cxld, @@ -1104,6 +1140,8 @@ static enum cxld_init_type get_decoder_init_type(stru= ct cxl_decoder *cxld, } =20 *td =3D NULL; + if (is_type2_manual_decoder(cxld, pdev)) + return MOCK_DECODER_INIT_TYPE2_MANUAL; =20 /* * The first decoder on the first 2 devices on the first switch @@ -1121,7 +1159,9 @@ static enum cxld_init_type get_decoder_init_type(stru= ct cxl_decoder *cxld, MOCK_DECODER_INIT_TYPE3_AUTO; } =20 -static bool mock_decoder_handle_saved(struct cxl_decoder *cxld, struct cxl= _test_decoder *td) +static bool mock_decoder_handle_saved(struct cxl_decoder *cxld, + struct cxl_test_decoder *td, + struct platform_device *pdev) { bool enabled; =20 @@ -1133,6 +1173,11 @@ static bool mock_decoder_handle_saved(struct cxl_dec= oder *cxld, struct cxl_test_ if (enabled) return !cxld_registry_restore(cxld, td); =20 + if (is_type2_manual_decoder(cxld, pdev)) { + init_type2_manual_decoder(to_cxl_endpoint_decoder(&cxld->dev)); + return false; + } + init_disabled_mock_decoder(cxld); return false; } @@ -1209,6 +1254,13 @@ static void mock_init_hdm_type2_cxled(struct cxl_end= point_decoder *cxled, put_device(dev); } =20 +static void mock_init_hdm_type2_manual(struct cxl_endpoint_decoder *cxled) +{ + init_type2_manual_decoder(cxled); + + WARN_ON_ONCE(!cxld_registry_new(&cxled->cxld)); +} + static void mock_init_hdm_type3_cxled(struct cxl_endpoint_decoder *cxled, struct cxl_port *port, struct platform_device *pdev, @@ -1361,7 +1413,7 @@ static bool mock_init_hdm_decoder(struct cxl_decoder = *cxld) case MOCK_DECODER_INIT_SAVED: if (WARN_ON(!td)) return false; - return mock_decoder_handle_saved(cxld, td); + return mock_decoder_handle_saved(cxld, td, pdev); case MOCK_DECODER_INIT_DEFAULT: /* * The default path picks up all the decoders that are not @@ -1375,6 +1427,9 @@ static bool mock_init_hdm_decoder(struct cxl_decoder = *cxld) case MOCK_DECODER_INIT_TYPE2_AUTO: mock_init_hdm_type2_cxled(cxled, port); return false; + case MOCK_DECODER_INIT_TYPE2_MANUAL: + mock_init_hdm_type2_manual(cxled); + return false; default: return false; } --=20 2.43.0