diff mbox series

[RFC,10/13] vfio/pci: emulate CXL DVSEC registers in the configuration space

Message ID 20240920223446.1908673-11-zhiw@nvidia.com (mailing list archive)
State New, archived
Headers show
Series vfio: introduce vfio-cxl to support CXL type-2 accelerator passthrough | expand

Commit Message

Zhi Wang Sept. 20, 2024, 10:34 p.m. UTC
A CXL device has many DVSEC registers in the configuration space for
device control and enumeration. E.g. enable CXL.mem/CXL.cahce.

However, the kernel CXL core owns those registers to control the device.
Thus, the VM is forbidden to touch the physical device control registers.

Read/write the CXL DVSEC from/to the virt configuration space.

Signed-off-by: Zhi Wang <zhiw@nvidia.com>
---
 drivers/vfio/pci/vfio_pci_config.c | 9 +++++++++
 1 file changed, 9 insertions(+)

Comments

Alex Williamson Oct. 11, 2024, 9:02 p.m. UTC | #1
On Fri, 20 Sep 2024 15:34:43 -0700
Zhi Wang <zhiw@nvidia.com> wrote:

> A CXL device has many DVSEC registers in the configuration space for
> device control and enumeration. E.g. enable CXL.mem/CXL.cahce.
> 
> However, the kernel CXL core owns those registers to control the device.
> Thus, the VM is forbidden to touch the physical device control registers.
> 
> Read/write the CXL DVSEC from/to the virt configuration space.
> 
> Signed-off-by: Zhi Wang <zhiw@nvidia.com>
> ---
>  drivers/vfio/pci/vfio_pci_config.c | 9 +++++++++
>  1 file changed, 9 insertions(+)
> 
> diff --git a/drivers/vfio/pci/vfio_pci_config.c b/drivers/vfio/pci/vfio_pci_config.c
> index 98f3ac2d305c..af8c0997c796 100644
> --- a/drivers/vfio/pci/vfio_pci_config.c
> +++ b/drivers/vfio/pci/vfio_pci_config.c
> @@ -1902,6 +1902,15 @@ static ssize_t vfio_config_do_rw(struct vfio_pci_core_device *vdev, char __user
>  
>  			perm = &ecap_perms[cap_id];
>  			cap_start = vfio_find_cap_start(vdev, *ppos);
> +
> +			if (cap_id == PCI_EXT_CAP_ID_DVSEC) {
> +				u32 dword;

This should be an __le32 and we should use an le32_to_cpu before
comparison to PCI_VENDOR_ID_CXL.

> +
> +				memcpy(&dword, vdev->vconfig + cap_start + PCI_DVSEC_HEADER1, 4);
> +
> +				if (PCI_DVSEC_HEADER1_VID(dword) == PCI_VENDOR_ID_CXL)
> +					perm = &virt_perms;

We're making an assumption here that all CXL defined DVSEC capabilities
will have the same behavior.  Also, should we bother to expose an
emulated, dummy capability, or should we expect the VMM to handle
emulating it?  Doesn't the virt_perms allow the entire capability,
including headers to be writable?  Thanks,

Alex

> +			}
>  		} else {
>  			WARN_ON(cap_id > PCI_CAP_ID_MAX);
>
diff mbox series

Patch

diff --git a/drivers/vfio/pci/vfio_pci_config.c b/drivers/vfio/pci/vfio_pci_config.c
index 98f3ac2d305c..af8c0997c796 100644
--- a/drivers/vfio/pci/vfio_pci_config.c
+++ b/drivers/vfio/pci/vfio_pci_config.c
@@ -1902,6 +1902,15 @@  static ssize_t vfio_config_do_rw(struct vfio_pci_core_device *vdev, char __user
 
 			perm = &ecap_perms[cap_id];
 			cap_start = vfio_find_cap_start(vdev, *ppos);
+
+			if (cap_id == PCI_EXT_CAP_ID_DVSEC) {
+				u32 dword;
+
+				memcpy(&dword, vdev->vconfig + cap_start + PCI_DVSEC_HEADER1, 4);
+
+				if (PCI_DVSEC_HEADER1_VID(dword) == PCI_VENDOR_ID_CXL)
+					perm = &virt_perms;
+			}
 		} else {
 			WARN_ON(cap_id > PCI_CAP_ID_MAX);