@@ -885,6 +885,37 @@ int vfio_pci_core_register_dev_region(struct vfio_pci_core_device *vdev,
885
885
}
886
886
EXPORT_SYMBOL_GPL (vfio_pci_core_register_dev_region );
887
887
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
+
888
919
static int vfio_pci_ioctl_get_info (struct vfio_pci_core_device * vdev ,
889
920
struct vfio_device_info __user * arg )
890
921
{
@@ -923,6 +954,13 @@ static int vfio_pci_ioctl_get_info(struct vfio_pci_core_device *vdev,
923
954
return ret ;
924
955
}
925
956
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
+
926
964
if (caps .size ) {
927
965
info .flags |= VFIO_DEVICE_FLAGS_CAPS ;
928
966
if (info .argsz < sizeof (info ) + caps .size ) {
0 commit comments