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

