Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/1.1/patches/2229152/?format=api
{ "id": 2229152, "url": "http://patchwork.ozlabs.org/api/1.1/patches/2229152/?format=api", "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20260427181235.3003865-6-mhonap@nvidia.com/", "project": { "id": 14, "url": "http://patchwork.ozlabs.org/api/1.1/projects/14/?format=api", "name": "QEMU Development", "link_name": "qemu-devel", "list_id": "qemu-devel.nongnu.org", "list_email": "qemu-devel@nongnu.org", "web_url": "", "scm_url": "", "webscm_url": "" }, "msgid": "<20260427181235.3003865-6-mhonap@nvidia.com>", "date": "2026-04-27T18:12:31", "name": "[RFC,5/9] hw/vfio/pci: Add CXL Type-2 device detection and region setup", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "681373f1849af1288f897b8738005ce4dccda589", "submitter": { "id": 92895, "url": "http://patchwork.ozlabs.org/api/1.1/people/92895/?format=api", "name": "Manish Honap", "email": "mhonap@nvidia.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20260427181235.3003865-6-mhonap@nvidia.com/mbox/", "series": [ { "id": 501717, "url": "http://patchwork.ozlabs.org/api/1.1/series/501717/?format=api", "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/list/?series=501717", "date": "2026-04-27T18:12:35", "name": "QEMU: CXL Type-2 device passthrough via vfio-pci", "version": 1, "mbox": "http://patchwork.ozlabs.org/series/501717/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2229152/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2229152/checks/", "tags": {}, "headers": { "Return-Path": "<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>", "X-Original-To": "incoming@patchwork.ozlabs.org", "Delivered-To": "patchwork-incoming@legolas.ozlabs.org", "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=Nvidia.com header.i=@Nvidia.com header.a=rsa-sha256\n header.s=selector2 header.b=luF8HMr2;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org\n (client-ip=209.51.188.17; helo=lists1p.gnu.org;\n envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n receiver=patchwork.ozlabs.org)" ], "Received": [ "from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17])\n\t(using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g4Dv86y7Pz1yHv\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 28 Apr 2026 06:00:20 +1000 (AEST)", "from localhost ([::1] helo=lists1p.gnu.org)\n\tby lists1p.gnu.org with esmtp (Exim 4.90_1)\n\t(envelope-from <qemu-devel-bounces@nongnu.org>)\n\tid 1wHS5P-00035t-HW; Mon, 27 Apr 2026 15:57:43 -0400", "from eggs.gnu.org ([2001:470:142:3::10])\n by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <mhonap@nvidia.com>)\n id 1wHQTa-00034S-O1; Mon, 27 Apr 2026 14:14:36 -0400", "from mail-eastus2azlp170110003.outbound.protection.outlook.com\n ([2a01:111:f403:c110::3] helo=BN8PR05CU002.outbound.protection.outlook.com)\n by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <mhonap@nvidia.com>)\n id 1wHQTY-0000Bp-LC; Mon, 27 Apr 2026 14:14:34 -0400", "from MN2PR11CA0030.namprd11.prod.outlook.com (2603:10b6:208:23b::35)\n by SN7PR12MB8817.namprd12.prod.outlook.com (2603:10b6:806:347::8)\n with Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9870.15; Mon, 27 Apr\n 2026 18:14:20 +0000", "from BL02EPF0001A0FB.namprd03.prod.outlook.com\n (2603:10b6:208:23b::4) by MN2PR11CA0030.outlook.office365.com\n (2603:10b6:208:23b::35) with Microsoft SMTP Server (version=TLS1_3,\n cipher=TLS_AES_256_GCM_SHA384) id 15.20.9846.26 via Frontend Transport; Mon,\n 27 Apr 2026 18:14:20 +0000", "from mail.nvidia.com (216.228.117.161) by\n BL02EPF0001A0FB.mail.protection.outlook.com (10.167.242.102) with Microsoft\n SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id\n 15.20.9846.18 via Frontend Transport; Mon, 27 Apr 2026 18:14:20 +0000", "from rnnvmail201.nvidia.com (10.129.68.8) by mail.nvidia.com\n (10.129.200.67) with Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.20; Mon, 27 Apr\n 2026 11:14:00 -0700", "from nvidia-4028GR-scsim.nvidia.com (10.126.230.37) by\n rnnvmail201.nvidia.com (10.129.68.8) with Microsoft SMTP Server\n (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id\n 15.2.2562.20; Mon, 27 Apr 2026 11:13:52 -0700" ], "ARC-Seal": "i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none;\n b=vMgfi/JX0CKRWhz/P5n+JKfWxZQRE/PdGcEO2zd5yxSk/MoY7u+jB4jzgJAPrbfoQT8xz0oFzrNT/CVb0pRGvATrR4wMiM20LnLvugIWRLJpqv0id+B9yUdnZChUQpUbX7ysAtcfBl50Hv+NsjLhXEYag2LGaoDNa7M71je1ZfB3cgInxiyMHo8CwbJ/KWdrShbL1GbSO+c9+48y6Rroxtr2n7LwBFCg380UtUhL+l1SR7JkIGmrqH4lEAUWnaFw14K48HMy0ec9j6wOpZLqaejRmFftZX+Q+uWkfh9qH8f4JzgL9YbVzGpC3T80V3rC0OuVmAmLm2Tyja7UqLpkTA==", "ARC-Message-Signature": "i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com;\n s=arcselector10001;\n 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;\n bh=JuG8Ge0ykEIBDtFWCFC9wN1HAPiMU07Z5XLejSBkzZc=;\n b=mDh3caji+USfc6Mm6COUr5auMO/kS1Qf3gh+piXcTAlK5Phhk4u4unZUbapBDvmpCDTkPaOtWesqMKS3A1Bt7wBSvnNZfH4QSJEQ7bWSLLwNn2hRSEm7lgrcPH+KGEgMUb3/HSUqsGUNJPPKO0OtvBBR/WtNCs3r+5Nwd191D1YEWzLqavxDGWbOY/RdpWfzlY9cuFrOpbe74MhD5rZy1F2XSwBv4r4a1JAQR1VEH8b+B7b3+U5Zmav7zS9p8qACzCdI1cXojgz4vzO8a3ZEaXTNUDtDYGE6uXqzojhdQT4SHVW6H994r74aiBV1X+Nv1k0eRmtm/boDv37kSUqBnA==", "ARC-Authentication-Results": "i=1; mx.microsoft.com 1; spf=pass (sender ip is\n 216.228.117.161) smtp.rcpttodomain=nongnu.org smtp.mailfrom=nvidia.com;\n dmarc=pass (p=reject sp=reject pct=100) action=none header.from=nvidia.com;\n dkim=none (message not signed); arc=none (0)", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com;\n s=selector2;\n h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;\n bh=JuG8Ge0ykEIBDtFWCFC9wN1HAPiMU07Z5XLejSBkzZc=;\n b=luF8HMr2GgZtmjCmO3VAcU69gr8Bw5NfFjvQsyCimKcYl8RQ54ukegQ3rmkfms1gMWdsy9bcq3Tbl+3lrQCZC0wYLGl0k9+BeEf/t8vc/+K/NEY+YR8xb8ktduB7bJwVHS6RaQ1EOhc0tZZZGQWcQrJhSBDgkIVq9qTOwBEYd/NRnyXbNlGRUxfuFAK1eG5h/J6ZelNHshS2h1vyyANe2FwVP3YIeOjurSds0oUgR6iGLUyrLXIqPWNl+WzkcZUSVbeyJ7Ol9mSsFx/fChBM5TIoGXJmaLQYtRMylyv8E/3NOIMCXHIBlGZTAiK2C1k2yRlrX9IXfs2W+hUXgGjfMw==", "X-MS-Exchange-Authentication-Results": "spf=pass (sender IP is 216.228.117.161)\n smtp.mailfrom=nvidia.com;\n dkim=none (message not signed)\n header.d=none;dmarc=pass action=none header.from=nvidia.com;", "Received-SPF": [ "Pass (protection.outlook.com: domain of nvidia.com designates\n 216.228.117.161 as permitted sender) receiver=protection.outlook.com;\n client-ip=216.228.117.161; helo=mail.nvidia.com; pr=C", "permerror client-ip=2a01:111:f403:c110::3;\n envelope-from=mhonap@nvidia.com;\n helo=BN8PR05CU002.outbound.protection.outlook.com" ], "From": "<mhonap@nvidia.com>", "To": "<alwilliamson@nvidia.com>, <skolothumtho@nvidia.com>, <ankita@nvidia.com>,\n <mst@redhat.com>, <imammedo@redhat.com>, <anisinha@redhat.com>,\n <eric.auger@redhat.com>, <peter.maydell@linaro.org>,\n <shannon.zhaosl@gmail.com>, <jonathan.cameron@huawei.com>,\n <fan.ni@samsung.com>, <pbonzini@redhat.com>, <richard.henderson@linaro.org>,\n <marcel.apfelbaum@gmail.com>, <clg@redhat.com>, <cohuck@redhat.com>,\n <dan.j.williams@intel.com>, <dave.jiang@intel.com>,\n <alejandro.lucero-palau@amd.com>", "CC": "<vsethi@nvidia.com>, <cjia@nvidia.com>, <targupta@nvidia.com>,\n <zhiw@nvidia.com>, <kjaju@nvidia.com>, <linux-cxl@vger.kernel.org>,\n <kvm@vger.kernel.org>, <qemu-devel@nongnu.org>, <qemu-arm@nongnu.org>,\n \"Manish Honap\" <mhonap@nvidia.com>", "Subject": "[RFC 5/9] hw/vfio/pci: Add CXL Type-2 device detection and region\n setup", "Date": "Mon, 27 Apr 2026 23:42:31 +0530", "Message-ID": "<20260427181235.3003865-6-mhonap@nvidia.com>", "X-Mailer": "git-send-email 2.25.1", "In-Reply-To": "<20260427181235.3003865-1-mhonap@nvidia.com>", "References": "<20260427181235.3003865-1-mhonap@nvidia.com>", "MIME-Version": "1.0", "Content-Type": "text/plain; charset=\"UTF-8\"", "Content-Transfer-Encoding": "8bit", "X-Originating-IP": "[10.126.230.37]", "X-ClientProxiedBy": "rnnvmail202.nvidia.com (10.129.68.7) To\n rnnvmail201.nvidia.com (10.129.68.8)", "X-EOPAttributedMessage": "0", "X-MS-PublicTrafficType": "Email", "X-MS-TrafficTypeDiagnostic": "BL02EPF0001A0FB:EE_|SN7PR12MB8817:EE_", "X-MS-Office365-Filtering-Correlation-Id": "3022b281-ce9c-4e75-44be-08dea488cd84", "X-MS-Exchange-SenderADCheck": "1", "X-MS-Exchange-AntiSpam-Relay": "0", "X-Microsoft-Antispam": "BCL:0;\n ARA:13230040|36860700016|82310400026|376014|7416014|1800799024|56012099003|18002099003|22082099003|921020;", "X-Microsoft-Antispam-Message-Info": "\n A7u+6mZXZapd1DPWCyM5S0OUkSizfa8I1Lg9Y2BTVEELiBFQRNdLYw+VM/xpD7UXk0+XjL8cP0nRSYJCDC8aAJ/v4o0LSjoee9pJdyZ5J1bW6b8EDZ0HVSZ8LHgPXh+IN2ziLkHZTTb0KHQ4aghXRobCkIRHyNKr3SF8OFv0A4XddZaIt5yotyEMHI2bXV5thh5bcPBvFD5v4VDy8enXX034vqpfH5AULFYf/IgsKsxo4WKuczQGu6NwfEHz09U3B7FoGok2TFh+WNB6nd/5INDUHZVBj3uYD8MigVnJNit63yqAEDEmD+V5pIRH6Ng/Lq6TtQLNvUF8gBBu6PJXh8cp2QoIe8pUiR4eWl1qFZuKVFrPsiP0r42QjoZvfpyP61CTyrII/ZF6wZ+EgM+3L/W5XacwF2ehtbPtTyd3tkYWorYo6dHSqXJELWUFnevoxu/ZiLGLpFYcSKHn8q2WqFpYTPCRW6G/iJr2/qt0hYADJaZF7ZLBBDj9bYBHEyz6IvaqFx5Sc5p11Eour46hFquVe9eg0vbLGScFHwrvU+jl30jyYhK6v2StTk8We9Es7rF9iMHvxOO3KDEIE1RvkToxpkCsmiMOJHdb/YxSsboKu6yxQbRscRklZZO9JH6l4lJQExUfFFIYnfMXk8Pj1YbmUdzqf6KZR09FrejE8Z3WRhpYNxqhRlqI7KSCtzYACCfq7xLVMqpAK1nT/RYByMR6NeNBJOiMFJ204E3wtuLmKngFto9M1Bsa/vEYPa6HsZvKmS39FYigABJ4V3yvhMS0ZDuyaxT4Q6jpyHYwd+bYPktTPVyD8dMvB3wh5c5E", "X-Forefront-Antispam-Report": "CIP:216.228.117.161; CTRY:US; LANG:en; SCL:1;\n SRV:;\n IPV:NLI; SFV:NSPM; H:mail.nvidia.com; PTR:dc6edge2.nvidia.com; CAT:NONE;\n SFS:(13230040)(36860700016)(82310400026)(376014)(7416014)(1800799024)(56012099003)(18002099003)(22082099003)(921020);\n DIR:OUT; SFP:1101;", "X-MS-Exchange-AntiSpam-MessageData-ChunkCount": "1", "X-MS-Exchange-AntiSpam-MessageData-0": "\n 6WuA0owz+mcNaLZQdFn3wUWrQ0d9eNcUr7dMmY4z1TMR7XVSsqgM3s/Bq7kL5ggx24FM5DYItLIvUkCDe6FvdlEe5qr7CgJN/cF1Su5vy0gM0aUaOdUBZPzfmL0/BY4MXXPIeCq+GvQbzm8I9oCaS/Rn4kZRFwtUb1c0xup6oHBOdxvkNcxOX6+sl7000n1jsjLtA4RXFi59jZ404LxNOxFgW1ov2bhE4tQz96HPi6AoUCMQq3S1VZO0bSojxOUBHazV3PRUt5Vk9+ymM7GJLM2UpnKTmTL2yXn3plSljRIiQu+NZEv4gZWA8RXRD6FUiRmExZaqMbaGBJI/dAHbX4TRsOHxWmmSQuOYQC+PsdiyT0HC2+TJbvHe/y55BU7l3Bds3WT6ik4mEHBNok3yv8WcydyQJwKN51fLOQb7B4ghsUatYIiJ5nfqxTv6KI/W", "X-OriginatorOrg": "Nvidia.com", "X-MS-Exchange-CrossTenant-OriginalArrivalTime": "27 Apr 2026 18:14:20.1749 (UTC)", "X-MS-Exchange-CrossTenant-Network-Message-Id": "\n 3022b281-ce9c-4e75-44be-08dea488cd84", "X-MS-Exchange-CrossTenant-Id": "43083d15-7273-40c1-b7db-39efd9ccc17a", "X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp": "\n TenantId=43083d15-7273-40c1-b7db-39efd9ccc17a; Ip=[216.228.117.161];\n Helo=[mail.nvidia.com]", "X-MS-Exchange-CrossTenant-AuthSource": "\n BL02EPF0001A0FB.namprd03.prod.outlook.com", "X-MS-Exchange-CrossTenant-AuthAs": "Anonymous", "X-MS-Exchange-CrossTenant-FromEntityHeader": "HybridOnPrem", "X-MS-Exchange-Transport-CrossTenantHeadersStamped": "SN7PR12MB8817", "X-Spam_score_int": "-10", "X-Spam_score": "-1.1", "X-Spam_bar": "-", "X-Spam_report": "(-1.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001,\n DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1,\n FORGED_SPF_HELO=1, SPF_HELO_PASS=-0.001,\n SPF_NONE=0.001 autolearn=no autolearn_force=no", "X-Spam_action": "no action", "X-Mailman-Approved-At": "Mon, 27 Apr 2026 15:57:41 -0400", "X-BeenThere": "qemu-devel@nongnu.org", "X-Mailman-Version": "2.1.29", "Precedence": "list", "List-Id": "qemu development <qemu-devel.nongnu.org>", "List-Unsubscribe": "<https://lists.nongnu.org/mailman/options/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=unsubscribe>", "List-Archive": "<https://lists.nongnu.org/archive/html/qemu-devel>", "List-Post": "<mailto:qemu-devel@nongnu.org>", "List-Help": "<mailto:qemu-devel-request@nongnu.org?subject=help>", "List-Subscribe": "<https://lists.nongnu.org/mailman/listinfo/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=subscribe>", "Errors-To": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org", "Sender": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org" }, "content": "From: Manish Honap <mhonap@nvidia.com>\n\nWhen VFIO_DEVICE_FLAGS_CXL is set, the kernel has identified a CXL\nType-2 device and populated the capability chain with a\nvfio_device_info_cap_cxl entry. Read that entry to locate the DPA\nand CXL Component Register shadow regions, then call vfio_region_setup()\nfor each.\n\nDPA covers the device's host-managed memory and is faulted in lazily\nby the VMM. The CXL Component Register shadow gives the VMM access to\nthe HDM Decoder Capability block so it can intercept decoder commits\nwithout touching the hardware register page directly.\n\nvfio_cxl_derive_hdm_info() walks the CXL Capability Array inside the\nComponent Register shadow to find the HDM Decoder capability (ID 0x5)\nand extracts hdm_decoder_offset and hdm_count. All reads use\nle32_to_cpu() since the capability array is little-endian per the CXL\nspec. Dword 0 is the array header; capability entries start at dword 1,\nwhich is why the loop begins at i = 1.\n\nCXL register constants are defined here using names that mirror\n<linux/cxl.h> to make cross-referencing straightforward.\n\nAdd the VFIOCXL struct embedded in VFIOPCIDevice.\n\nSigned-off-by: Zhi Wang <zhiw@nvidia.com>\nSigned-off-by: Manish Honap <mhonap@nvidia.com>\n---\n hw/vfio/pci.c | 214 +++++++++++++++++++++++++++++++++++++++++++\n hw/vfio/pci.h | 14 +++\n hw/vfio/trace-events | 4 +\n 3 files changed, 232 insertions(+)", "diff": "diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c\nindex b2a07f6bb4..49ac661eb3 100644\n--- a/hw/vfio/pci.c\n+++ b/hw/vfio/pci.c\n@@ -24,6 +24,7 @@\n \n #include \"hw/core/hw-error.h\"\n #include \"hw/core/iommu.h\"\n+#include \"hw/cxl/cxl_component.h\"\n #include \"hw/pci/msi.h\"\n #include \"hw/pci/msix.h\"\n #include \"hw/pci/pci_bridge.h\"\n@@ -2957,6 +2958,38 @@ static VFIODeviceOps vfio_pci_ops = {\n .vfio_load_config = vfio_pci_load_config,\n };\n \n+/*\n+ * CXL Component Register Space constants (CXL 4.0 8.2.3).\n+ */\n+\n+/* CXL Capability Array Header (dword 0 of COMP_REGS) */\n+#define CXL_CM_CAP_HDR_ARRAY_ID 0x0001U /* expected ID value */\n+#define CXL_CM_CAP_HDR_NUM_CAPS_SHIFT 24 /* bits [31:24] = num entries */\n+#define CXL_CM_CAP_HDR_NUM_CAPS_MASK 0xffU\n+#define CXL_CM_CAP_ENTRY_ID_MASK 0xffffU /* bits [15:0] = cap ID */\n+#define CXL_CM_CAP_ENTRY_PTR_SHIFT 20 /* bits [31:20] = byte offset */\n+#define CXL_CM_CAP_ENTRY_PTR_MASK 0xfffU\n+#define CXL_CM_CAP_ID_HDM 0x0005U /* HDM Decoder cap ID */\n+\n+/* HDM Decoder Capability (HDMC) register at hdm_decoder_offset+0x00 */\n+#define CXL_HDMC_DECODER_COUNT_MASK 0xfU /* bits [3:0]; 0→1, N→N*2 */\n+\n+/*\n+ * Per-decoder register offsets from hdm_decoder_offset (CXL 4.0 Table 8-119).\n+ * Decoder records begin at +0x10 and are 0x20 bytes each.\n+ */\n+#define CXL_HDM_DECODER0_BASE_LOW_OFFSET(i) (0x20 * (i) + 0x10)\n+#define CXL_HDM_DECODER0_BASE_HIGH_OFFSET(i) (0x20 * (i) + 0x14)\n+#define CXL_HDM_DECODER0_CTRL_OFFSET(i) (0x20 * (i) + 0x20)\n+\n+/* HDM Decoder n Control register bits (CXL 4.0 Table 8-123) */\n+#define CXL_HDM_CTRL_COMMIT_LOCK (1U << 8) /* decoder locked */\n+#define CXL_HDM_CTRL_COMMIT (1U << 9) /* software trigger */\n+#define CXL_HDM_CTRL_COMMITTED (1U << 10) /* hardware status */\n+\n+/* HDM Decoder BASE_LO: bits [31:28] hold address bits [31:28] */\n+#define CXL_HDM_BASE_LO_ADDR_MASK 0xF0000000U\n+\n bool vfio_populate_vga(VFIOPCIDevice *vdev, Error **errp)\n {\n VFIODevice *vbasedev = &vdev->vbasedev;\n@@ -3102,6 +3135,25 @@ void vfio_pci_put_device(VFIOPCIDevice *vdev)\n {\n vfio_display_finalize(vdev);\n vfio_bars_finalize(vdev);\n+\n+ /*\n+ * The DPA region is not in bars[] and must be cleaned up here.\n+ * Remove it from the system address space before releasing.\n+ */\n+ if (vdev->cxl.dpa_in_system_mem) {\n+ memory_region_del_subregion(get_system_memory(), vdev->cxl.region.mem);\n+ vdev->cxl.dpa_in_system_mem = false;\n+ trace_vfio_cxl_put_device(vdev->vbasedev.name);\n+ }\n+ if (vdev->cxl.region.mem) {\n+ vfio_region_exit(&vdev->cxl.region);\n+ vfio_region_finalize(&vdev->cxl.region);\n+ }\n+ if (vdev->cxl.comp_regs_region.mem) {\n+ vfio_region_exit(&vdev->cxl.comp_regs_region);\n+ vfio_region_finalize(&vdev->cxl.comp_regs_region);\n+ }\n+\n vfio_cpr_pci_unregister_device(vdev);\n g_free(vdev->emulated_config_bits);\n g_free(vdev->rom);\n@@ -3254,6 +3306,164 @@ void vfio_pci_register_req_notifier(VFIOPCIDevice *vdev)\n }\n }\n \n+/*\n+ * vfio_cxl_derive_hdm_info - read hdm_decoder_offset and hdm_count from the\n+ * COMP_REGS region by traversing the CXL Capability Array.\n+ *\n+ * Dword 0: CXL Capability Array Header\n+ * bits[31:24] = num_caps,\n+ * bits[15:0] = 1.\n+ * Dwords 1..N:\n+ * bits[15:0] = cap ID;\n+ * bits[31:20] = byte offset from region start.\n+ * HDM Decoder cap ID = 0x5; its offset is hdm_decoder_offset.\n+ * HDMC register at hdm_decoder_offset+0:\n+ * bits[3:0] encode count (0→1, N→N*2).\n+ */\n+static bool vfio_cxl_derive_hdm_info(VFIODevice *vbasedev, VFIOCXL *cxl,\n+ Error **errp)\n+{\n+ off_t base = cxl->comp_regs_region.fd_offset;\n+ uint32_t hdr, num_caps, i;\n+\n+ if (pread(vbasedev->fd, &hdr, sizeof(hdr), base) != sizeof(hdr)) {\n+ error_setg(errp, \"vfio-cxl: failed to read CXL Capability Header\");\n+ return false;\n+ }\n+ hdr = le32_to_cpu(hdr);\n+\n+ if ((hdr & CXL_CM_CAP_ENTRY_ID_MASK) != CXL_CM_CAP_HDR_ARRAY_ID) {\n+ error_setg(errp, \"vfio-cxl: unexpected CXL Capability Array ID 0x%x\",\n+ hdr & CXL_CM_CAP_ENTRY_ID_MASK);\n+ return false;\n+ }\n+\n+ num_caps = (hdr >> CXL_CM_CAP_HDR_NUM_CAPS_SHIFT) &\n+ CXL_CM_CAP_HDR_NUM_CAPS_MASK;\n+\n+ /*\n+ * Dword 0 is the CXL Capability Array Header;\n+ * capability entries start at dword 1.\n+ */\n+ for (i = 1; i <= num_caps; i++) {\n+ uint32_t entry, cap_id;\n+\n+ if (pread(vbasedev->fd, &entry, sizeof(entry),\n+ base + i * sizeof(entry)) != sizeof(entry)) {\n+ error_setg(errp, \"vfio-cxl: failed to read cap entry %u\", i);\n+ return false;\n+ }\n+ entry = le32_to_cpu(entry);\n+\n+ cap_id = entry & CXL_CM_CAP_ENTRY_ID_MASK;\n+ if (cap_id == CXL_CM_CAP_ID_HDM) {\n+ uint32_t hdmc, field;\n+\n+ cxl->hdm_decoder_offset = (entry >> CXL_CM_CAP_ENTRY_PTR_SHIFT) &\n+ CXL_CM_CAP_ENTRY_PTR_MASK;\n+\n+ if (pread(vbasedev->fd, &hdmc, sizeof(hdmc),\n+ base + cxl->hdm_decoder_offset) != sizeof(hdmc)) {\n+ error_setg(errp, \"vfio-cxl: failed to read HDMC register\");\n+ return false;\n+ }\n+ hdmc = le32_to_cpu(hdmc);\n+ field = hdmc & CXL_HDMC_DECODER_COUNT_MASK;\n+ cxl->hdm_count = field ? (uint8_t)(field * 2) : 1;\n+ return true;\n+ }\n+ }\n+\n+ error_setg(errp, \"vfio-cxl: HDM Decoder capability not found in COMP_REGS\");\n+ return false;\n+}\n+\n+static bool vfio_cxl_setup(VFIOPCIDevice *vdev, Error **errp)\n+{\n+ VFIODevice *vbasedev = &vdev->vbasedev;\n+ VFIOCXL *cxl = &vdev->cxl;\n+ g_autofree struct vfio_device_info *info = NULL;\n+ struct vfio_info_cap_header *hdr;\n+ struct vfio_device_info_cap_cxl *cap;\n+ g_autofree struct vfio_region_info *region_info = NULL;\n+ g_autofree struct vfio_region_info *comp_info = NULL;\n+ int ret;\n+\n+ if (!(vbasedev->flags & VFIO_DEVICE_FLAGS_CXL)) {\n+ return true;\n+ }\n+\n+ info = vfio_get_device_info(vbasedev->fd);\n+ if (!info) {\n+ error_setg(errp, \"vfio-cxl: failed to get device info\");\n+ return false;\n+ }\n+\n+ hdr = vfio_get_device_info_cap(info, VFIO_DEVICE_INFO_CAP_CXL);\n+ if (!hdr) {\n+ error_setg(errp, \"vfio-cxl: CXL capability not found in device info\");\n+ return false;\n+ }\n+ cap = (void *)hdr;\n+\n+ if (cap->dpa_region_index == (uint32_t)-1 ||\n+ cap->comp_regs_region_index == (uint32_t)-1) {\n+ error_setg(errp, \"vfio-cxl: kernel did not provide region indices \"\n+ \"(dpa=%u comp=%u)\",\n+ cap->dpa_region_index, cap->comp_regs_region_index);\n+ return false;\n+ }\n+\n+ cxl->hdm_regs_bar_index = cap->hdm_regs_bar_index;\n+ cxl->hdm_regs_offset = cap->hdm_regs_offset;\n+\n+ /* DPA region */\n+ ret = vfio_device_get_region_info(vbasedev, cap->dpa_region_index,\n+ ®ion_info);\n+ if (ret || !region_info) {\n+ error_setg(errp, \"vfio-cxl: failed to get DPA region info\");\n+ return false;\n+ }\n+ ret = vfio_region_setup(OBJECT(vdev), vbasedev, &cxl->region,\n+ region_info->index, \"cxl-dpa\", errp);\n+ if (ret) {\n+ error_setg(errp, \"vfio-cxl: failed to set up DPA region\");\n+ return false;\n+ }\n+ cxl->dpa_size = region_info->size;\n+\n+ if (vfio_region_mmap(&cxl->region)) {\n+ error_setg(errp, \"vfio-cxl: failed to mmap DPA region for %s\",\n+ vbasedev->name);\n+ return false;\n+ }\n+\n+ /* COMP_REGS region (HDM decoder shadow) */\n+ ret = vfio_device_get_region_info(vbasedev, cap->comp_regs_region_index,\n+ &comp_info);\n+ if (ret || !comp_info) {\n+ error_setg(errp, \"vfio-cxl: failed to get COMP_REGS region info\");\n+ return false;\n+ }\n+ ret = vfio_region_setup(OBJECT(vdev), vbasedev, &cxl->comp_regs_region,\n+ comp_info->index, \"cxl-comp-regs\", errp);\n+ if (ret) {\n+ error_setg(errp, \"vfio-cxl: failed to set up COMP_REGS region\");\n+ return false;\n+ }\n+ cxl->hdm_regs_size = comp_info->size;\n+\n+ if (!vfio_cxl_derive_hdm_info(vbasedev, cxl, errp)) {\n+ return false;\n+ }\n+\n+ trace_vfio_cxl_setup_params(vbasedev->name, cxl->hdm_regs_bar_index,\n+ cxl->hdm_regs_offset, cxl->hdm_regs_size,\n+ cxl->dpa_size);\n+ return true;\n+}\n+\n+\n static void vfio_unregister_req_notifier(VFIOPCIDevice *vdev)\n {\n Error *err = NULL;\n@@ -3508,6 +3718,10 @@ static void vfio_pci_realize(PCIDevice *pdev, Error **errp)\n goto error;\n }\n \n+ if (!vfio_cxl_setup(vdev, errp)) {\n+ goto error;\n+ }\n+\n if (!vfio_pci_config_setup(vdev, errp)) {\n goto error;\n }\ndiff --git a/hw/vfio/pci.h b/hw/vfio/pci.h\nindex c3a1f53d35..f3906f0c53 100644\n--- a/hw/vfio/pci.h\n+++ b/hw/vfio/pci.h\n@@ -122,6 +122,19 @@ typedef struct VFIOMSIXInfo {\n \n OBJECT_DECLARE_SIMPLE_TYPE(VFIOPCIDevice, VFIO_PCI_DEVICE)\n \n+typedef struct VFIOCXL {\n+ uint8_t hdm_regs_bar_index;\n+ uint64_t hdm_regs_offset;\n+ uint64_t hdm_regs_size;\n+ uint64_t hdm_decoder_offset;\n+ uint8_t hdm_count;\n+ uint64_t dpa_size;\n+ hwaddr fmws_base; /* GPA base programmed into HDM decoder 0 */\n+ bool dpa_in_system_mem;\n+ VFIORegion region;\n+ VFIORegion comp_regs_region;\n+} VFIOCXL;\n+\n struct VFIOPCIDevice {\n PCIDevice parent_obj;\n \n@@ -191,6 +204,7 @@ struct VFIOPCIDevice {\n VFIODisplay *dpy;\n Notifier irqchip_change_notifier;\n VFIOPCICPR cpr;\n+ VFIOCXL cxl;\n };\n \n /* Use uin32_t for vendor & device so PCI_ANY_ID expands and cannot match hw */\ndiff --git a/hw/vfio/trace-events b/hw/vfio/trace-events\nindex 846e3625c5..3678481a8e 100644\n--- a/hw/vfio/trace-events\n+++ b/hw/vfio/trace-events\n@@ -197,3 +197,7 @@ vfio_device_get_region_info_type(const char *name, int index, uint32_t type, uin\n vfio_device_reset_handler(void) \"\"\n vfio_device_attach(const char *name, int group_id) \" (%s) group %d\"\n vfio_device_detach(const char *name, int group_id) \" (%s) group %d\"\n+\n+# pci.c CXL Type-2 passthrough\n+vfio_cxl_setup_params(const char *name, uint8_t bar, uint64_t hdm_off, uint64_t hdm_sz, uint64_t dpa_sz) \" (%s) hdm_bar=%u hdm_regs_offset=0x%\"PRIx64\" hdm_regs_size=0x%\"PRIx64\" dpa_size=0x%\"PRIx64\n+vfio_cxl_put_device(const char *name) \" (%s) removing DPA region from system memory\"\n", "prefixes": [ "RFC", "5/9" ] }