From: <mhonap@nvidia.com>
To: <alex@shazbot.org>, <jgg@ziepe.ca>, <ankita@nvidia.com>,
<jic23@kernel.org>, <dave.jiang@intel.com>,
<alejandro.lucero-palau@amd.com>, <smadhavan@nvidia.com>,
<corbet@lwn.net>, <skhan@linuxfoundation.org>,
<dave@stgolabs.net>, <alison.schofield@intel.com>,
<vishal.l.verma@intel.com>, <iweiny@kernel.org>,
<ming.li@zohomail.com>, <yishaih@nvidia.com>,
<skolothumtho@nvidia.com>, <kevin.tian@intel.com>,
<bhelgaas@google.com>, <dmatlack@google.com>, <kees@kernel.org>,
<gustavoars@kernel.org>
Cc: <cjia@nvidia.com>, <kjaju@nvidia.com>, <vsethi@nvidia.com>,
<zhiw@nvidia.com>, <mhonap@nvidia.com>,
<linux-doc@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
<kvm@vger.kernel.org>, <linux-cxl@vger.kernel.org>,
<linux-pci@vger.kernel.org>, <linux-kselftest@vger.kernel.org>,
<linux-hardening@vger.kernel.org>
Subject: [PATCH v5 20/27] vfio/cxl: Expose the HDM decoder registers read-only to the guest
Date: Thu, 17 Sep 2026 00:05:33 +0530 [thread overview]
Message-ID: <20260916183540.3813685-21-mhonap@nvidia.com> (raw)
In-Reply-To: <20260916183540.3813685-1-mhonap@nvidia.com>
From: Manish Honap <mhonap@nvidia.com>
A CXL Type-2 guest reads the HDM decoder registers to learn the HDM
region it was handed. Those registers live in the component BAR that
vfio-pci owns.
Map the decoder block at bind: its location comes from the pdev->hdm
enumeration cache, and vfio-pci owns the BAR, so map it without
claiming the block and expose it as a second, read-only region under
VFIO_REGION_TYPE_PCI_VENDOR_TYPE with the CXL vendor id, registered per
open like the HDM memory region.
Serve reads live from the mapped block and absorb writes without
forwarding them to hardware.
Registering a second region is the first point at which an open-time
failure must unwind an already-registered region, so add
vfio_pci_core_unregister_dev_region() to drop the most recently
registered region, and use it to unwind the HDM memory region if the
decoder region fails to register.
Assisted-by: LLM
Signed-off-by: Manish Honap <mhonap@nvidia.com>
---
drivers/vfio/pci/cxl/vfio_cxl_core.c | 81 +++++++++++++++++++++++++++-
include/uapi/linux/vfio.h | 2 +
2 files changed, 82 insertions(+), 1 deletion(-)
diff --git a/drivers/vfio/pci/cxl/vfio_cxl_core.c b/drivers/vfio/pci/cxl/vfio_cxl_core.c
index e099e9a70a5a..da04776356e4 100644
--- a/drivers/vfio/pci/cxl/vfio_cxl_core.c
+++ b/drivers/vfio/pci/cxl/vfio_cxl_core.c
@@ -24,6 +24,8 @@
* @cxlmd: memory device joined to the CXL topology at bind
* @hpa_range: host physical range of the HDM region
* @hdm_pfn_space: HDM-region pfn range registered with memory_failure()
+ * @hdm_regs: mapped HDM decoder registers, read live by the decoder region
+ * @hdm_len: length of the HDM decoder register block
* @hdm_valid: true when host CPU access to the HDM range is safe; under memory_lock
*/
struct vfio_cxl_state {
@@ -31,6 +33,8 @@ struct vfio_cxl_state {
struct cxl_memdev *cxlmd;
struct range hpa_range;
struct pfn_address_space hdm_pfn_space;
+ void __iomem *hdm_regs;
+ u32 hdm_len;
bool hdm_valid;
};
@@ -212,6 +216,56 @@ static int vfio_cxl_register_pfn_space(struct vfio_pci_core_device *vdev)
return register_pfn_address_space(&cxl->hdm_pfn_space);
}
+static ssize_t vfio_cxl_comp_rw(struct vfio_pci_core_device *vdev,
+ char __user *buf, size_t count, loff_t *ppos,
+ bool iswrite)
+{
+ struct vfio_cxl_state *cxl = vdev->cxl;
+ loff_t pos = *ppos & VFIO_PCI_OFFSET_MASK;
+ void *tmp;
+
+ if (pos >= cxl->hdm_len)
+ return -EINVAL;
+
+ /* The decoder registers take only aligned dword accesses. */
+ if (pos % sizeof(u32) || count % sizeof(u32))
+ return -EINVAL;
+
+ count = min_t(size_t, count, cxl->hdm_len - pos);
+
+ /*
+ * The host committed and locked the physical decoder before the guest
+ * saw the device, so the guest never drives it: absorb writes without
+ * forwarding them to hardware. The guest programs a GPA that the VMM
+ * virtualizes; reads return the live registers, which already report the
+ * decoder committed. BASE_LOW and BASE_HIGH carry the host HPA, visible
+ * only to the trusted VMM that virtualizes it away from the guest.
+ */
+ if (iswrite) {
+ *ppos += count;
+ return count;
+ }
+
+ tmp = kmalloc(count, GFP_KERNEL);
+ if (!tmp)
+ return -ENOMEM;
+
+ memcpy_fromio(tmp, cxl->hdm_regs + pos, count);
+ if (copy_to_user(buf, tmp, count)) {
+ kfree(tmp);
+ return -EFAULT;
+ }
+ kfree(tmp);
+
+ *ppos += count;
+ return count;
+}
+
+static const struct vfio_pci_regops vfio_cxl_comp_regops = {
+ .rw = vfio_cxl_comp_rw,
+ .release = vfio_cxl_region_release,
+};
+
static void vfio_cxl_release_hpa(void *data)
{
struct vfio_cxl_state *cxl = data;
@@ -299,6 +353,21 @@ static int vfio_cxl_init_device(struct vfio_pci_core_device *vdev)
goto err;
}
+ /*
+ * Map the HDM decoder registers so the decoder region can read them
+ * live. The block location comes from the enumeration cache in
+ * pdev->hdm; vfio-pci owns the BAR, so map without claiming the block.
+ */
+ cxl->hdm_regs = devm_ioremap(&pdev->dev,
+ pci_resource_start(pdev, pdev->hdm->hdm_bar) +
+ pdev->hdm->hdm_offset, pdev->hdm->hdm_size);
+ if (!cxl->hdm_regs) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ cxl->hdm_len = pdev->hdm->hdm_size;
+
/*
* A Type-2 accelerator has no mailbox and no media-ready register, so
* set media ready directly.
@@ -381,6 +450,13 @@ static int vfio_cxl_open_device(struct vfio_pci_core_device *vdev)
if (ret)
return ret;
+ ret = vfio_cxl_add_region(vdev, VFIO_REGION_SUBTYPE_CXL_COMP_REGS,
+ &vfio_cxl_comp_regops, cxl->hdm_len,
+ VFIO_REGION_INFO_FLAG_READ |
+ VFIO_REGION_INFO_FLAG_WRITE);
+ if (ret)
+ goto err_unregister_mem;
+
/*
* The HDM region is advertised mmap-able, so a fd holder can fault its
* struct-page-less device memory in from the host CPU. Register it with
@@ -389,7 +465,7 @@ static int vfio_cxl_open_device(struct vfio_pci_core_device *vdev)
*/
ret = vfio_cxl_register_pfn_space(vdev);
if (ret && ret != -EOPNOTSUPP)
- goto err_unregister_mem;
+ goto err_unregister_comp;
/*
* The decoder is firmware-committed, so host access to the HDM range is
@@ -400,6 +476,9 @@ static int vfio_cxl_open_device(struct vfio_pci_core_device *vdev)
return 0;
+err_unregister_comp:
+ vfio_pci_core_unregister_dev_region(vdev);
+
err_unregister_mem:
vfio_pci_core_unregister_dev_region(vdev);
diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
index 1bf86763c0f7..8927a7a4e8e4 100644
--- a/include/uapi/linux/vfio.h
+++ b/include/uapi/linux/vfio.h
@@ -373,6 +373,8 @@ struct vfio_region_info_cap_type {
/* CXL Type-2 device (0x1e98) sub-types for VFIO_REGION_TYPE_PCI_VENDOR_TYPE */
/* CXL.mem HDM region of a Type-2 device, mmap-able */
#define VFIO_REGION_SUBTYPE_CXL_MEM (1)
+/* CXL HDM decoder registers: read live, guest writes are absorbed */
+#define VFIO_REGION_SUBTYPE_CXL_COMP_REGS (2)
/* sub-types for VFIO_REGION_TYPE_GFX */
#define VFIO_REGION_SUBTYPE_GFX_EDID (1)
--
2.25.1
next prev parent reply other threads:[~2026-09-16 18:40 UTC|newest]
Thread overview: 75+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-16 18:35 [PATCH v5 00/27] vfio/pci: Add CXL Type-2 device passthrough support mhonap
2026-09-16 18:35 ` [PATCH v5 01/27] cxl/regs: Split the BAR block request and ioremap helpers mhonap
2026-09-22 1:28 ` Jonathan Cameron
2026-09-16 18:35 ` [PATCH v5 02/27] cxl/regs: Let a BAR-owning driver own the component register block mhonap
2026-09-22 1:36 ` Jonathan Cameron
2026-10-09 6:13 ` Manish Honap
2026-09-16 18:35 ` [PATCH v5 03/27] cxl: Move component register defines to uapi/cxl/cxl_regs.h mhonap
2026-09-22 1:43 ` Jonathan Cameron
2026-10-09 6:14 ` Manish Honap
2026-09-16 18:35 ` [PATCH v5 04/27] cxl: Add cxl_reset_dvsec_sequence() for vfio-pci mhonap
2026-09-25 20:41 ` Jonathan Cameron
2026-10-09 6:14 ` Manish Honap
2026-09-16 18:35 ` [PATCH v5 05/27] vfio/pci: Add the CXL provider ops registration interface mhonap
2026-09-16 18:35 ` [PATCH v5 06/27] vfio/pci: Detect CXL devices and load the CXL provider on demand mhonap
2026-09-17 8:48 ` Richard Cheng
2026-09-21 10:05 ` Manish Honap
2026-09-16 18:35 ` [PATCH v5 07/27] vfio/pci: Honor -EPROBE_DEFER from CXL provider probe mhonap
2026-09-16 18:35 ` [PATCH v5 08/27] vfio/pci: Fall back to plain vfio-pci when CXL init fails mhonap
2026-09-22 2:15 ` Alex Williamson
2026-10-09 6:14 ` Manish Honap
2026-09-16 18:35 ` [PATCH v5 09/27] vfio/pci: Add a generic excluded-range list mhonap
2026-09-22 2:13 ` Alex Williamson
2026-10-09 6:14 ` Manish Honap
2026-09-25 22:05 ` Jonathan Cameron
2026-10-09 6:14 ` Manish Honap
2026-09-16 18:35 ` [PATCH v5 10/27] vfio/pci: Migrate MSI-X exclusion onto the " mhonap
2026-09-16 18:35 ` [PATCH v5 11/27] vfio/pci: Virtualize the CXL DVSEC in vfio_pci_config.c mhonap
2026-09-22 2:14 ` Alex Williamson
2026-10-09 6:14 ` Manish Honap
2026-09-25 22:15 ` Jonathan Cameron
2026-10-09 6:15 ` Manish Honap
2026-09-16 18:35 ` [PATCH v5 12/27] vfio/pci: Call the CXL open and close hooks around device use mhonap
2026-09-25 22:17 ` Jonathan Cameron
2026-10-09 6:14 ` Manish Honap
2026-09-16 18:35 ` [PATCH v5 13/27] vfio/pci: Bracket PCI resets with the CXL reset hooks mhonap
2026-09-22 2:14 ` Alex Williamson
2026-10-09 6:14 ` Manish Honap
2026-09-16 18:35 ` [PATCH v5 14/27] vfio/pci: Provide an opt-out for the CXL Type-2 extensions mhonap
2026-09-16 18:35 ` [PATCH v5 15/27] vfio/cxl: Add the vfio-cxl provider module skeleton mhonap
2026-09-16 18:35 ` [PATCH v5 16/27] vfio/cxl: Create the CXL memdev and set media ready at bind mhonap
2026-09-22 2:14 ` Alex Williamson
2026-10-09 6:14 ` Manish Honap
2026-09-25 22:22 ` Jonathan Cameron
2026-10-09 6:14 ` Manish Honap
2026-09-16 18:35 ` [PATCH v5 17/27] vfio/cxl: Own the whole component register BAR mhonap
2026-09-22 2:14 ` Alex Williamson
2026-10-09 6:14 ` Manish Honap
2026-09-16 18:35 ` [PATCH v5 18/27] vfio/cxl: Expose the HDM memory region to the guest mhonap
2026-09-22 2:14 ` Alex Williamson
2026-10-09 6:14 ` Manish Honap
2026-09-16 18:35 ` [PATCH v5 19/27] vfio/cxl: Contain HDM memory errors with memory_failure() mhonap
2026-09-16 18:35 ` mhonap [this message]
2026-09-22 2:13 ` [PATCH v5 20/27] vfio/cxl: Expose the HDM decoder registers read-only to the guest Alex Williamson
2026-10-09 6:14 ` Manish Honap
2026-09-16 18:35 ` [PATCH v5 21/27] vfio/cxl: Exclude the HDM decoder registers from direct BAR access mhonap
2026-09-17 7:28 ` Richard Cheng
2026-09-21 9:52 ` Manish Honap
2026-09-16 18:35 ` [PATCH v5 22/27] vfio/cxl: Clear the HDM access gate after a hot reset mhonap
2026-09-22 2:13 ` Alex Williamson
2026-10-09 6:14 ` Manish Honap
2026-09-16 18:35 ` [PATCH v5 23/27] vfio/cxl: Describe the CXL device and decoder geometry to userspace mhonap
2026-09-16 18:35 ` [PATCH v5 24/27] vfio/cxl: Export the HDM memory region as a dma-buf mhonap
2026-09-17 7:55 ` Richard Cheng
2026-09-21 9:58 ` Manish Honap
2026-09-16 18:35 ` [PATCH v5 25/27] vfio/cxl: Run the CXL reset at the vfio reset points mhonap
2026-09-17 8:11 ` Richard Cheng
2026-09-21 10:01 ` Manish Honap
2026-09-22 2:13 ` Alex Williamson
2026-10-09 6:14 ` Manish Honap
2026-09-16 18:35 ` [PATCH v5 26/27] Documentation: vfio-pci: Document CXL Type-2 device passthrough mhonap
2026-09-16 19:33 ` Gregory Price
2026-09-21 9:43 ` Manish Honap
2026-09-24 0:54 ` Jonathan Cameron
2026-10-09 6:15 ` Manish Honap
2026-09-16 18:35 ` [PATCH v5 27/27] selftests/vfio: Add CXL Type-2 passthrough tests mhonap
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260916183540.3813685-21-mhonap@nvidia.com \
--to=mhonap@nvidia.com \
--cc=alejandro.lucero-palau@amd.com \
--cc=alex@shazbot.org \
--cc=alison.schofield@intel.com \
--cc=ankita@nvidia.com \
--cc=bhelgaas@google.com \
--cc=cjia@nvidia.com \
--cc=corbet@lwn.net \
--cc=dave.jiang@intel.com \
--cc=dave@stgolabs.net \
--cc=dmatlack@google.com \
--cc=gustavoars@kernel.org \
--cc=iweiny@kernel.org \
--cc=jgg@ziepe.ca \
--cc=jic23@kernel.org \
--cc=kees@kernel.org \
--cc=kevin.tian@intel.com \
--cc=kjaju@nvidia.com \
--cc=kvm@vger.kernel.org \
--cc=linux-cxl@vger.kernel.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-hardening@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=ming.li@zohomail.com \
--cc=skhan@linuxfoundation.org \
--cc=skolothumtho@nvidia.com \
--cc=smadhavan@nvidia.com \
--cc=vishal.l.verma@intel.com \
--cc=vsethi@nvidia.com \
--cc=yishaih@nvidia.com \
--cc=zhiw@nvidia.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.