Commit a5bfe22d authored by Alex Williamson's avatar Alex Williamson

vfio/pci-core: Add capability for AtomicOp completer support

Test and enable PCIe AtomicOp completer support of various widths and
report via device-info capability to userspace.
Reviewed-by: default avatarCédric Le Goater <clg@redhat.com>
Reviewed-by: default avatarRobin Voetter <robin@streamhpc.com>
Tested-by: default avatarRobin Voetter <robin@streamhpc.com>
Link: https://lore.kernel.org/r/20230519214748.402003-1-alex.williamson@redhat.comSigned-off-by: default avatarAlex Williamson <alex.williamson@redhat.com>
parent d9824f70
...@@ -885,6 +885,37 @@ int vfio_pci_core_register_dev_region(struct vfio_pci_core_device *vdev, ...@@ -885,6 +885,37 @@ int vfio_pci_core_register_dev_region(struct vfio_pci_core_device *vdev,
} }
EXPORT_SYMBOL_GPL(vfio_pci_core_register_dev_region); EXPORT_SYMBOL_GPL(vfio_pci_core_register_dev_region);
static int vfio_pci_info_atomic_cap(struct vfio_pci_core_device *vdev,
struct vfio_info_cap *caps)
{
struct vfio_device_info_cap_pci_atomic_comp cap = {
.header.id = VFIO_DEVICE_INFO_CAP_PCI_ATOMIC_COMP,
.header.version = 1
};
struct pci_dev *pdev = pci_physfn(vdev->pdev);
u32 devcap2;
pcie_capability_read_dword(pdev, PCI_EXP_DEVCAP2, &devcap2);
if ((devcap2 & PCI_EXP_DEVCAP2_ATOMIC_COMP32) &&
!pci_enable_atomic_ops_to_root(pdev, PCI_EXP_DEVCAP2_ATOMIC_COMP32))
cap.flags |= VFIO_PCI_ATOMIC_COMP32;
if ((devcap2 & PCI_EXP_DEVCAP2_ATOMIC_COMP64) &&
!pci_enable_atomic_ops_to_root(pdev, PCI_EXP_DEVCAP2_ATOMIC_COMP64))
cap.flags |= VFIO_PCI_ATOMIC_COMP64;
if ((devcap2 & PCI_EXP_DEVCAP2_ATOMIC_COMP128) &&
!pci_enable_atomic_ops_to_root(pdev,
PCI_EXP_DEVCAP2_ATOMIC_COMP128))
cap.flags |= VFIO_PCI_ATOMIC_COMP128;
if (!cap.flags)
return -ENODEV;
return vfio_info_add_capability(caps, &cap.header, sizeof(cap));
}
static int vfio_pci_ioctl_get_info(struct vfio_pci_core_device *vdev, static int vfio_pci_ioctl_get_info(struct vfio_pci_core_device *vdev,
struct vfio_device_info __user *arg) struct vfio_device_info __user *arg)
{ {
...@@ -923,6 +954,13 @@ static int vfio_pci_ioctl_get_info(struct vfio_pci_core_device *vdev, ...@@ -923,6 +954,13 @@ static int vfio_pci_ioctl_get_info(struct vfio_pci_core_device *vdev,
return ret; return ret;
} }
ret = vfio_pci_info_atomic_cap(vdev, &caps);
if (ret && ret != -ENODEV) {
pci_warn(vdev->pdev,
"Failed to setup AtomicOps info capability\n");
return ret;
}
if (caps.size) { if (caps.size) {
info.flags |= VFIO_DEVICE_FLAGS_CAPS; info.flags |= VFIO_DEVICE_FLAGS_CAPS;
if (info.argsz < sizeof(info) + caps.size) { if (info.argsz < sizeof(info) + caps.size) {
......
...@@ -240,6 +240,20 @@ struct vfio_device_info { ...@@ -240,6 +240,20 @@ struct vfio_device_info {
#define VFIO_DEVICE_INFO_CAP_ZPCI_UTIL 3 #define VFIO_DEVICE_INFO_CAP_ZPCI_UTIL 3
#define VFIO_DEVICE_INFO_CAP_ZPCI_PFIP 4 #define VFIO_DEVICE_INFO_CAP_ZPCI_PFIP 4
/*
* The following VFIO_DEVICE_INFO capability reports support for PCIe AtomicOp
* completion to the root bus with supported widths provided via flags.
*/
#define VFIO_DEVICE_INFO_CAP_PCI_ATOMIC_COMP 5
struct vfio_device_info_cap_pci_atomic_comp {
struct vfio_info_cap_header header;
__u32 flags;
#define VFIO_PCI_ATOMIC_COMP32 (1 << 0)
#define VFIO_PCI_ATOMIC_COMP64 (1 << 1)
#define VFIO_PCI_ATOMIC_COMP128 (1 << 2)
__u32 reserved;
};
/** /**
* VFIO_DEVICE_GET_REGION_INFO - _IOWR(VFIO_TYPE, VFIO_BASE + 8, * VFIO_DEVICE_GET_REGION_INFO - _IOWR(VFIO_TYPE, VFIO_BASE + 8,
* struct vfio_region_info) * struct vfio_region_info)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment