Skip to content

Commit a5bfe22

Browse files
committed
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: Cédric Le Goater <clg@redhat.com> Reviewed-by: Robin Voetter <robin@streamhpc.com> Tested-by: Robin Voetter <robin@streamhpc.com> Link: https://lore.kernel.org/r/20230519214748.402003-1-alex.williamson@redhat.com Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
1 parent d9824f7 commit a5bfe22

File tree

2 files changed

+52
-0
lines changed

2 files changed

+52
-0
lines changed

drivers/vfio/pci/vfio_pci_core.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -885,6 +885,37 @@ int vfio_pci_core_register_dev_region(struct vfio_pci_core_device *vdev,
885885
}
886886
EXPORT_SYMBOL_GPL(vfio_pci_core_register_dev_region);
887887

888+
static int vfio_pci_info_atomic_cap(struct vfio_pci_core_device *vdev,
889+
struct vfio_info_cap *caps)
890+
{
891+
struct vfio_device_info_cap_pci_atomic_comp cap = {
892+
.header.id = VFIO_DEVICE_INFO_CAP_PCI_ATOMIC_COMP,
893+
.header.version = 1
894+
};
895+
struct pci_dev *pdev = pci_physfn(vdev->pdev);
896+
u32 devcap2;
897+
898+
pcie_capability_read_dword(pdev, PCI_EXP_DEVCAP2, &devcap2);
899+
900+
if ((devcap2 & PCI_EXP_DEVCAP2_ATOMIC_COMP32) &&
901+
!pci_enable_atomic_ops_to_root(pdev, PCI_EXP_DEVCAP2_ATOMIC_COMP32))
902+
cap.flags |= VFIO_PCI_ATOMIC_COMP32;
903+
904+
if ((devcap2 & PCI_EXP_DEVCAP2_ATOMIC_COMP64) &&
905+
!pci_enable_atomic_ops_to_root(pdev, PCI_EXP_DEVCAP2_ATOMIC_COMP64))
906+
cap.flags |= VFIO_PCI_ATOMIC_COMP64;
907+
908+
if ((devcap2 & PCI_EXP_DEVCAP2_ATOMIC_COMP128) &&
909+
!pci_enable_atomic_ops_to_root(pdev,
910+
PCI_EXP_DEVCAP2_ATOMIC_COMP128))
911+
cap.flags |= VFIO_PCI_ATOMIC_COMP128;
912+
913+
if (!cap.flags)
914+
return -ENODEV;
915+
916+
return vfio_info_add_capability(caps, &cap.header, sizeof(cap));
917+
}
918+
888919
static int vfio_pci_ioctl_get_info(struct vfio_pci_core_device *vdev,
889920
struct vfio_device_info __user *arg)
890921
{
@@ -923,6 +954,13 @@ static int vfio_pci_ioctl_get_info(struct vfio_pci_core_device *vdev,
923954
return ret;
924955
}
925956

957+
ret = vfio_pci_info_atomic_cap(vdev, &caps);
958+
if (ret && ret != -ENODEV) {
959+
pci_warn(vdev->pdev,
960+
"Failed to setup AtomicOps info capability\n");
961+
return ret;
962+
}
963+
926964
if (caps.size) {
927965
info.flags |= VFIO_DEVICE_FLAGS_CAPS;
928966
if (info.argsz < sizeof(info) + caps.size) {

include/uapi/linux/vfio.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,20 @@ struct vfio_device_info {
240240
#define VFIO_DEVICE_INFO_CAP_ZPCI_UTIL 3
241241
#define VFIO_DEVICE_INFO_CAP_ZPCI_PFIP 4
242242

243+
/*
244+
* The following VFIO_DEVICE_INFO capability reports support for PCIe AtomicOp
245+
* completion to the root bus with supported widths provided via flags.
246+
*/
247+
#define VFIO_DEVICE_INFO_CAP_PCI_ATOMIC_COMP 5
248+
struct vfio_device_info_cap_pci_atomic_comp {
249+
struct vfio_info_cap_header header;
250+
__u32 flags;
251+
#define VFIO_PCI_ATOMIC_COMP32 (1 << 0)
252+
#define VFIO_PCI_ATOMIC_COMP64 (1 << 1)
253+
#define VFIO_PCI_ATOMIC_COMP128 (1 << 2)
254+
__u32 reserved;
255+
};
256+
243257
/**
244258
* VFIO_DEVICE_GET_REGION_INFO - _IOWR(VFIO_TYPE, VFIO_BASE + 8,
245259
* struct vfio_region_info)

0 commit comments

Comments
 (0)