From: Manish Honap <[email protected]>

Advertise the assignment with a device-info flag so a VMM can tell a
CXL Type-2 device apart from a plain vfio-pci one. On the trapped
component region, add a capability carrying the BAR and offset of the
HDM decoder registers so the VMM can place the window where the guest
expects to find it.

Signed-off-by: Manish Honap <[email protected]>
---
 drivers/vfio/pci/cxl/vfio_cxl_core.c | 16 ++++++++++++++++
 drivers/vfio/pci/vfio_pci_core.c     |  3 +++
 include/uapi/linux/vfio.h            | 18 ++++++++++++++++++
 3 files changed, 37 insertions(+)

diff --git a/drivers/vfio/pci/cxl/vfio_cxl_core.c 
b/drivers/vfio/pci/cxl/vfio_cxl_core.c
index ec938813bd91..0fb5ed5d86b7 100644
--- a/drivers/vfio/pci/cxl/vfio_cxl_core.c
+++ b/drivers/vfio/pci/cxl/vfio_cxl_core.c
@@ -381,9 +381,25 @@ static ssize_t vfio_cxl_comp_rw(struct 
vfio_pci_core_device *vdev,
        return count;
 }
 
+static int vfio_cxl_comp_add_capability(struct vfio_pci_core_device *vdev,
+                                       struct vfio_pci_region *region,
+                                       struct vfio_info_cap *caps)
+{
+       struct cxl_hdm_info *hdm = vdev->pdev->hdm;
+       struct vfio_region_info_cap_cxl_comp_regs cap = {
+               .header.id = VFIO_REGION_INFO_CAP_CXL_COMP_REGS,
+               .header.version = 1,
+               .bar = hdm->hdm_bar,
+               .offset = hdm->hdm_offset,
+       };
+
+       return vfio_info_add_capability(caps, &cap.header, sizeof(cap));
+}
+
 static const struct vfio_pci_regops vfio_cxl_comp_regops = {
        .rw = vfio_cxl_comp_rw,
        .release = vfio_cxl_region_release,
+       .add_capability = vfio_cxl_comp_add_capability,
 };
 
 static void vfio_cxl_release_hpa(void *data)
diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c
index 6f6ebcce86a1..77f8f39dd670 100644
--- a/drivers/vfio/pci/vfio_pci_core.c
+++ b/drivers/vfio/pci/vfio_pci_core.c
@@ -1192,6 +1192,9 @@ static int vfio_pci_ioctl_get_info(struct 
vfio_pci_core_device *vdev,
        if (vdev->reset_works)
                info.flags |= VFIO_DEVICE_FLAGS_RESET;
 
+       if (vdev->cxl_ops)
+               info.flags |= VFIO_DEVICE_FLAGS_CXL;
+
        info.num_regions = VFIO_PCI_NUM_REGIONS + vdev->num_regions;
        info.num_irqs = VFIO_PCI_NUM_IRQS;
 
diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
index d5b8106625bf..df88535ede5f 100644
--- a/include/uapi/linux/vfio.h
+++ b/include/uapi/linux/vfio.h
@@ -215,6 +215,7 @@ struct vfio_device_info {
 #define VFIO_DEVICE_FLAGS_FSL_MC (1 << 6)      /* vfio-fsl-mc device */
 #define VFIO_DEVICE_FLAGS_CAPS (1 << 7)        /* Info supports caps */
 #define VFIO_DEVICE_FLAGS_CDX  (1 << 8)        /* vfio-cdx device */
+#define VFIO_DEVICE_FLAGS_CXL  (1 << 9)        /* vfio-cxl device */
        __u32   num_regions;    /* Max region index + 1 */
        __u32   num_irqs;       /* Max IRQ index + 1 */
        __u32   cap_offset;     /* Offset within info struct of first cap */
@@ -505,6 +506,23 @@ struct vfio_region_info_cap_nvlink2_lnkspd {
        __u32 __pad;
 };
 
+/*
+ * Geometry of a CXL Type-2 device's HDM decoder registers, so a VMM can place
+ * the trapped component register window where the guest expects it. The 
trapped
+ * region spans the whole HDM decoder block (every decoder), not just decoder 
0:
+ * a VMM reads the decoder count and each decoder's committed base from the 
block
+ * itself. Additional trapped component capabilities, such as CXL RAS, are
+ * exposed as their own region subtypes rather than by extending this cap.
+ */
+#define VFIO_REGION_INFO_CAP_CXL_COMP_REGS     6
+
+struct vfio_region_info_cap_cxl_comp_regs {
+       struct vfio_info_cap_header header;
+       __u32 bar;
+       __u32 __resv;   /* reserved, must be zero; versioning anchor for flags 
*/
+       __aligned_u64 offset;
+};
+
 /**
  * VFIO_DEVICE_GET_IRQ_INFO - _IOWR(VFIO_TYPE, VFIO_BASE + 9,
  *                                 struct vfio_irq_info)
-- 
2.25.1


Reply via email to