From: <mhonap@nvidia.com>
To: <alwilliamson@nvidia.com>, <dan.j.williams@intel.com>,
<jonathan.cameron@huawei.com>, <dave.jiang@intel.com>,
<alejandro.lucero-palau@amd.com>, <dave@stgolabs.net>,
<alison.schofield@intel.com>, <vishal.l.verma@intel.com>,
<ira.weiny@intel.com>, <dmatlack@google.com>, <shuah@kernel.org>,
<jgg@ziepe.ca>, <yishaih@nvidia.com>, <skolothumtho@nvidia.com>,
<kevin.tian@intel.com>, <ankita@nvidia.com>
Cc: <vsethi@nvidia.com>, <cjia@nvidia.com>, <targupta@nvidia.com>,
<zhiw@nvidia.com>, <kjaju@nvidia.com>,
<linux-kselftest@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
<linux-cxl@vger.kernel.org>, <kvm@vger.kernel.org>,
<mhonap@nvidia.com>
Subject: [PATCH v2 16/20] vfio/cxl: Register regions with VFIO layer
Date: Wed, 1 Apr 2026 20:09:13 +0530 [thread overview]
Message-ID: <20260401143917.108413-17-mhonap@nvidia.com> (raw)
In-Reply-To: <20260401143917.108413-1-mhonap@nvidia.com>
From: Manish Honap <mhonap@nvidia.com>
Register the DPA and component register region with VFIO layer.
Region indices for both these regions are cached for quick lookup.
vfio_cxl_register_cxl_region()
- memremap(WB) the region HPA (treat CXL.mem as RAM, not MMIO)
- Register VFIO_REGION_SUBTYPE_CXL
- Records dpa_region_idx.
vfio_cxl_register_comp_regs_region()
- Registers VFIO_REGION_SUBTYPE_CXL_COMP_REGS with size
hdm_reg_offset + hdm_reg_size
- Records comp_reg_region_idx.
Signed-off-by: Manish Honap <mhonap@nvidia.com>
---
drivers/vfio/pci/cxl/vfio_cxl_core.c | 98 +++++++++++++++++++++++++++-
drivers/vfio/pci/cxl/vfio_cxl_emu.c | 34 ++++++++++
drivers/vfio/pci/cxl/vfio_cxl_priv.h | 2 +
drivers/vfio/pci/vfio_pci.c | 23 +++++++
drivers/vfio/pci/vfio_pci_priv.h | 11 ++++
5 files changed, 167 insertions(+), 1 deletion(-)
diff --git a/drivers/vfio/pci/cxl/vfio_cxl_core.c b/drivers/vfio/pci/cxl/vfio_cxl_core.c
index a3ff90b7a22c..b38a04301660 100644
--- a/drivers/vfio/pci/cxl/vfio_cxl_core.c
+++ b/drivers/vfio/pci/cxl/vfio_cxl_core.c
@@ -75,6 +75,8 @@ vfio_cxl_create_device_state(struct pci_dev *pdev, u16 dvsec)
}
cxl->cache_capable = FIELD_GET(CXL_DVSEC_CAP_CACHE_CAPABLE, cap_word);
+ cxl->dpa_region_idx = -1;
+ cxl->comp_reg_region_idx = -1;
return cxl;
}
@@ -509,14 +511,19 @@ static int vfio_cxl_region_mmap(struct vfio_pci_core_device *vdev,
*/
void vfio_cxl_zap_region_locked(struct vfio_pci_core_device *vdev)
{
+ struct vfio_device *core_vdev = &vdev->vdev;
struct vfio_pci_cxl_state *cxl = vdev->cxl;
lockdep_assert_held_write(&vdev->memory_lock);
- if (!cxl)
+ if (!cxl || cxl->dpa_region_idx < 0)
return;
WRITE_ONCE(cxl->region_active, false);
+ unmap_mapping_range(core_vdev->inode->i_mapping,
+ VFIO_PCI_INDEX_TO_OFFSET(VFIO_PCI_NUM_REGIONS +
+ cxl->dpa_region_idx),
+ cxl->region_size, true);
}
/*
@@ -601,6 +608,7 @@ static ssize_t vfio_cxl_region_rw(struct vfio_pci_core_device *core_dev,
static void vfio_cxl_region_release(struct vfio_pci_core_device *vdev,
struct vfio_pci_region *region)
{
+ struct vfio_device *core_vdev = &vdev->vdev;
struct vfio_pci_cxl_state *cxl = region->data;
/*
@@ -610,6 +618,16 @@ static void vfio_cxl_region_release(struct vfio_pci_core_device *vdev,
*/
WRITE_ONCE(cxl->region_active, false);
+ /*
+ * Remove all user mappings of the DPA region while the device is
+ * still alive.
+ */
+ if (cxl->dpa_region_idx >= 0)
+ unmap_mapping_range(core_vdev->inode->i_mapping,
+ VFIO_PCI_INDEX_TO_OFFSET(VFIO_PCI_NUM_REGIONS +
+ cxl->dpa_region_idx),
+ cxl->region_size, true);
+
if (cxl->region_vaddr) {
memunmap(cxl->region_vaddr);
cxl->region_vaddr = NULL;
@@ -622,4 +640,82 @@ static const struct vfio_pci_regops vfio_cxl_regops = {
.release = vfio_cxl_region_release,
};
+int vfio_cxl_register_cxl_region(struct vfio_pci_core_device *vdev)
+{
+ struct vfio_pci_cxl_state *cxl = vdev->cxl;
+ u32 flags;
+ int ret;
+
+ if (!cxl)
+ return -ENODEV;
+
+ if (!cxl->region || cxl->region_vaddr)
+ return -ENODEV;
+
+ /*
+ * CXL device memory is RAM, not MMIO. Use memremap() rather than
+ * ioremap_cache() so the correct memory-mapping API is used.
+ * The WB attribute matches the cache-coherent nature of CXL.mem.
+ */
+ cxl->region_vaddr = memremap(cxl->region_hpa, cxl->region_size,
+ MEMREMAP_WB);
+ if (!cxl->region_vaddr)
+ return -ENOMEM;
+
+ flags = VFIO_REGION_INFO_FLAG_READ |
+ VFIO_REGION_INFO_FLAG_WRITE |
+ VFIO_REGION_INFO_FLAG_MMAP;
+
+ ret = vfio_pci_core_register_dev_region(vdev,
+ PCI_VENDOR_ID_CXL |
+ VFIO_REGION_TYPE_PCI_VENDOR_TYPE,
+ VFIO_REGION_SUBTYPE_CXL,
+ &vfio_cxl_regops,
+ cxl->region_size, flags,
+ cxl);
+ if (ret) {
+ memunmap(cxl->region_vaddr);
+ cxl->region_vaddr = NULL;
+ return ret;
+ }
+
+ /*
+ * Cache the vdev->region[] index before activating the region.
+ * vfio_pci_core_register_dev_region() placed the new entry at
+ * vdev->region[num_regions - 1] and incremented num_regions.
+ * vfio_cxl_zap_region_locked() uses this to avoid scanning
+ * vdev->region[] on every FLR.
+ */
+ cxl->dpa_region_idx = vdev->num_regions - 1;
+
+ vfio_cxl_reinit_comp_regs(cxl);
+
+ WRITE_ONCE(cxl->region_active, true);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(vfio_cxl_register_cxl_region);
+
+/**
+ * vfio_cxl_unregister_cxl_region - Undo vfio_cxl_register_cxl_region()
+ * @vdev: VFIO PCI device
+ *
+ * Marks the DPA region inactive and resets dpa_region_idx.
+ * Does NOT touch CXL subsystem state (cxl->region, cxl->cxled, cxl->cxlrd).
+ * The caller must call vfio_cxl_destroy_cxl_region() separately to release
+ * those objects.
+ */
+void vfio_cxl_unregister_cxl_region(struct vfio_pci_core_device *vdev)
+{
+ struct vfio_pci_cxl_state *cxl = vdev->cxl;
+
+ if (!cxl || cxl->dpa_region_idx < 0)
+ return;
+
+ WRITE_ONCE(cxl->region_active, false);
+
+ cxl->dpa_region_idx = -1;
+}
+EXPORT_SYMBOL_GPL(vfio_cxl_unregister_cxl_region);
+
MODULE_IMPORT_NS("CXL");
diff --git a/drivers/vfio/pci/cxl/vfio_cxl_emu.c b/drivers/vfio/pci/cxl/vfio_cxl_emu.c
index 781328a79b43..50d3718b101d 100644
--- a/drivers/vfio/pci/cxl/vfio_cxl_emu.c
+++ b/drivers/vfio/pci/cxl/vfio_cxl_emu.c
@@ -473,3 +473,37 @@ void vfio_cxl_clean_virt_regs(struct vfio_pci_cxl_state *cxl)
kfree(cxl->comp_reg_virt);
cxl->comp_reg_virt = NULL;
}
+
+/*
+ * vfio_cxl_register_comp_regs_region - Register the COMP_REGS device region.
+ *
+ * Exposes the emulated HDM decoder register state as a VFIO device region
+ * with type VFIO_REGION_SUBTYPE_CXL_COMP_REGS. QEMU attaches a
+ * notify_change callback to this region to intercept HDM COMMIT writes
+ * and map the DPA MemoryRegion at the appropriate GPA.
+ *
+ * The region is read+write only (no mmap) to ensure all accesses pass
+ * through comp_regs_dispatch_write() for proper bit-field enforcement.
+ */
+int vfio_cxl_register_comp_regs_region(struct vfio_pci_core_device *vdev)
+{
+ struct vfio_pci_cxl_state *cxl = vdev->cxl;
+ u32 flags = VFIO_REGION_INFO_FLAG_READ | VFIO_REGION_INFO_FLAG_WRITE;
+ int ret;
+
+ if (!cxl || !cxl->comp_reg_virt)
+ return -ENODEV;
+
+ ret = vfio_pci_core_register_dev_region(vdev,
+ PCI_VENDOR_ID_CXL |
+ VFIO_REGION_TYPE_PCI_VENDOR_TYPE,
+ VFIO_REGION_SUBTYPE_CXL_COMP_REGS,
+ &vfio_cxl_comp_regs_ops,
+ cxl->hdm_reg_offset +
+ cxl->hdm_reg_size, flags, cxl);
+ if (!ret)
+ cxl->comp_reg_region_idx = vdev->num_regions - 1;
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(vfio_cxl_register_comp_regs_region);
diff --git a/drivers/vfio/pci/cxl/vfio_cxl_priv.h b/drivers/vfio/pci/cxl/vfio_cxl_priv.h
index b86ee691d050..b884689a1226 100644
--- a/drivers/vfio/pci/cxl/vfio_cxl_priv.h
+++ b/drivers/vfio/pci/cxl/vfio_cxl_priv.h
@@ -28,6 +28,8 @@ struct vfio_pci_cxl_state {
__le32 *comp_reg_virt;
size_t dpa_size;
void __iomem *hdm_iobase;
+ int dpa_region_idx;
+ int comp_reg_region_idx;
u16 dvsec_len;
u8 hdm_count;
u8 comp_reg_bar;
diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c
index 0c771064c0b8..22cf9ea831f9 100644
--- a/drivers/vfio/pci/vfio_pci.c
+++ b/drivers/vfio/pci/vfio_pci.c
@@ -120,6 +120,29 @@ static int vfio_pci_open_device(struct vfio_device *core_vdev)
}
}
+ if (vdev->cxl) {
+ /*
+ * pci_config_map and vconfig are valid now (allocated by
+ * vfio_config_init() inside vfio_pci_core_enable() above).
+ */
+ vfio_cxl_setup_dvsec_perms(vdev);
+
+ ret = vfio_cxl_register_cxl_region(vdev);
+ if (ret) {
+ pci_warn(pdev, "Failed to setup CXL region\n");
+ vfio_pci_core_disable(vdev);
+ return ret;
+ }
+
+ ret = vfio_cxl_register_comp_regs_region(vdev);
+ if (ret) {
+ pci_warn(pdev, "Failed to register COMP_REGS region\n");
+ vfio_cxl_unregister_cxl_region(vdev);
+ vfio_pci_core_disable(vdev);
+ return ret;
+ }
+ }
+
vfio_pci_core_finish_enable(vdev);
return 0;
diff --git a/drivers/vfio/pci/vfio_pci_priv.h b/drivers/vfio/pci/vfio_pci_priv.h
index 96f8361ce6f3..ae0091d5096c 100644
--- a/drivers/vfio/pci/vfio_pci_priv.h
+++ b/drivers/vfio/pci/vfio_pci_priv.h
@@ -148,6 +148,9 @@ void vfio_pci_cxl_cleanup(struct vfio_pci_core_device *vdev);
void vfio_cxl_zap_region_locked(struct vfio_pci_core_device *vdev);
void vfio_cxl_reactivate_region(struct vfio_pci_core_device *vdev);
void vfio_cxl_setup_dvsec_perms(struct vfio_pci_core_device *vdev);
+int vfio_cxl_register_cxl_region(struct vfio_pci_core_device *vdev);
+void vfio_cxl_unregister_cxl_region(struct vfio_pci_core_device *vdev);
+int vfio_cxl_register_comp_regs_region(struct vfio_pci_core_device *vdev);
#else
@@ -161,6 +164,14 @@ static inline void
vfio_cxl_reactivate_region(struct vfio_pci_core_device *vdev) { }
static inline void
vfio_cxl_setup_dvsec_perms(struct vfio_pci_core_device *vdev) { }
+static inline int
+vfio_cxl_register_cxl_region(struct vfio_pci_core_device *vdev)
+{ return 0; }
+static inline void
+vfio_cxl_unregister_cxl_region(struct vfio_pci_core_device *vdev) { }
+static inline int
+vfio_cxl_register_comp_regs_region(struct vfio_pci_core_device *vdev)
+{ return 0; }
#endif /* CONFIG_VFIO_CXL_CORE */
--
2.25.1
next prev parent reply other threads:[~2026-04-01 14:42 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-01 14:38 [PATCH v2 00/20] vfio/pci: Add CXL Type-2 device passthrough support mhonap
2026-04-01 14:38 ` [PATCH v2 01/20] cxl: Add cxl_get_hdm_info() for HDM decoder metadata mhonap
2026-04-01 14:38 ` [PATCH v2 02/20] cxl: Declare cxl_find_regblock and cxl_probe_component_regs in public header mhonap
2026-04-01 14:39 ` [PATCH v2 03/20] cxl: Move component/HDM register defines to uapi/cxl/cxl_regs.h mhonap
2026-04-01 14:39 ` [PATCH v2 04/20] cxl: Split cxl_await_range_active() from media-ready wait mhonap
2026-04-01 14:39 ` [PATCH v2 05/20] cxl: Record BIR and BAR offset in cxl_register_map mhonap
2026-04-01 14:39 ` [PATCH v2 06/20] vfio: UAPI for CXL-capable PCI device assignment mhonap
2026-04-01 14:39 ` [PATCH v2 07/20] vfio/pci: Add CXL state to vfio_pci_core_device mhonap
2026-04-01 14:39 ` [PATCH v2 08/20] vfio/pci: Add CONFIG_VFIO_CXL_CORE and stub CXL hooks mhonap
2026-04-01 14:39 ` [PATCH v2 09/20] vfio/cxl: Detect CXL DVSEC and probe HDM block mhonap
2026-04-01 14:39 ` [PATCH v2 10/20] vfio/pci: Export config access helpers mhonap
2026-04-01 14:39 ` [PATCH v2 11/20] vfio/cxl: Introduce HDM decoder register emulation framework mhonap
2026-04-01 14:39 ` [PATCH v2 12/20] vfio/cxl: Wait for HDM ranges and create memdev mhonap
2026-04-01 14:39 ` [PATCH v2 13/20] vfio/cxl: CXL region management support mhonap
2026-04-01 14:39 ` [PATCH v2 14/20] vfio/cxl: DPA VFIO region with demand fault mmap and reset zap mhonap
2026-04-01 14:39 ` [PATCH v2 15/20] vfio/cxl: Virtualize CXL DVSEC config writes mhonap
2026-04-01 14:39 ` mhonap [this message]
2026-04-03 19:35 ` [PATCH v2 16/20] vfio/cxl: Register regions with VFIO layer Dan Williams
2026-04-04 18:53 ` Jason Gunthorpe
2026-04-04 19:36 ` Dan Williams
2026-04-06 21:22 ` Gregory Price
2026-04-06 22:05 ` Jason Gunthorpe
2026-04-07 14:15 ` Gregory Price
2026-04-06 22:10 ` Jason Gunthorpe
2026-04-01 14:39 ` [PATCH v2 17/20] vfio/pci: Advertise CXL cap and sparse component BAR to userspace mhonap
2026-04-01 14:39 ` [PATCH v2 18/20] vfio/cxl: Provide opt-out for CXL feature mhonap
2026-04-01 14:39 ` [PATCH v2 19/20] docs: vfio-pci: Document CXL Type-2 device passthrough mhonap
2026-04-01 14:39 ` [PATCH v2 20/20] selftests/vfio: Add CXL Type-2 VFIO assignment test 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=20260401143917.108413-17-mhonap@nvidia.com \
--to=mhonap@nvidia.com \
--cc=alejandro.lucero-palau@amd.com \
--cc=alison.schofield@intel.com \
--cc=alwilliamson@nvidia.com \
--cc=ankita@nvidia.com \
--cc=cjia@nvidia.com \
--cc=dan.j.williams@intel.com \
--cc=dave.jiang@intel.com \
--cc=dave@stgolabs.net \
--cc=dmatlack@google.com \
--cc=ira.weiny@intel.com \
--cc=jgg@ziepe.ca \
--cc=jonathan.cameron@huawei.com \
--cc=kevin.tian@intel.com \
--cc=kjaju@nvidia.com \
--cc=kvm@vger.kernel.org \
--cc=linux-cxl@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=shuah@kernel.org \
--cc=skolothumtho@nvidia.com \
--cc=targupta@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox