diff mbox series

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

Message ID 20230519214748.402003-1-alex.williamson@redhat.com (mailing list archive)
State New, archived
Headers show
Series vfio/pci-core: Add capability for AtomicOp copleter support | expand

Commit Message

Alex Williamson May 19, 2023, 9:47 p.m. UTC
Test and enable PCIe AtomicOp completer support of various widths and
report via device-info capability to userspace.

Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
---
 drivers/vfio/pci/vfio_pci_core.c | 38 ++++++++++++++++++++++++++++++++
 include/uapi/linux/vfio.h        | 14 ++++++++++++
 2 files changed, 52 insertions(+)

Comments

Robin Voetter May 31, 2023, 10:02 p.m. UTC | #1
On 5/19/23 23:47, Alex Williamson wrote:
> Test and enable PCIe AtomicOp completer support of various widths and
> report via device-info capability to userspace.
> 
> Signed-off-by: Alex Williamson <alex.williamson@redhat.com>

Reviewed-by: Robin Voetter <robin@streamhpc.com>
Tested-by: Robin Voetter <robin@streamhpc.com>

Kind regards,

Robin Voetter
Cédric Le Goater June 8, 2023, 7:57 p.m. UTC | #2
On 5/19/23 23:47, Alex Williamson wrote:
> Test and enable PCIe AtomicOp completer support of various widths and
> report via device-info capability to userspace.
> 
> Signed-off-by: Alex Williamson <alex.williamson@redhat.com>

Reviewed-by: Cédric Le Goater <clg@redhat.com>

Thanks,

C.


> ---
>   drivers/vfio/pci/vfio_pci_core.c | 38 ++++++++++++++++++++++++++++++++
>   include/uapi/linux/vfio.h        | 14 ++++++++++++
>   2 files changed, 52 insertions(+)
> 
> diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c
> index a5ab416cf476..a21ab726c9d4 100644
> --- a/drivers/vfio/pci/vfio_pci_core.c
> +++ b/drivers/vfio/pci/vfio_pci_core.c
> @@ -882,6 +882,37 @@ int vfio_pci_core_register_dev_region(struct vfio_pci_core_device *vdev,
>   }
>   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,
>   				   struct vfio_device_info __user *arg)
>   {
> @@ -920,6 +951,13 @@ static int vfio_pci_ioctl_get_info(struct vfio_pci_core_device *vdev,
>   		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) {
>   		info.flags |= VFIO_DEVICE_FLAGS_CAPS;
>   		if (info.argsz < sizeof(info) + caps.size) {
> diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
> index 0552e8dcf0cb..07988d62b33c 100644
> --- a/include/uapi/linux/vfio.h
> +++ b/include/uapi/linux/vfio.h
> @@ -240,6 +240,20 @@ struct vfio_device_info {
>   #define VFIO_DEVICE_INFO_CAP_ZPCI_UTIL		3
>   #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,
>    *				       struct vfio_region_info)
diff mbox series

Patch

diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c
index a5ab416cf476..a21ab726c9d4 100644
--- a/drivers/vfio/pci/vfio_pci_core.c
+++ b/drivers/vfio/pci/vfio_pci_core.c
@@ -882,6 +882,37 @@  int vfio_pci_core_register_dev_region(struct vfio_pci_core_device *vdev,
 }
 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,
 				   struct vfio_device_info __user *arg)
 {
@@ -920,6 +951,13 @@  static int vfio_pci_ioctl_get_info(struct vfio_pci_core_device *vdev,
 		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) {
 		info.flags |= VFIO_DEVICE_FLAGS_CAPS;
 		if (info.argsz < sizeof(info) + caps.size) {
diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
index 0552e8dcf0cb..07988d62b33c 100644
--- a/include/uapi/linux/vfio.h
+++ b/include/uapi/linux/vfio.h
@@ -240,6 +240,20 @@  struct vfio_device_info {
 #define VFIO_DEVICE_INFO_CAP_ZPCI_UTIL		3
 #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,
  *				       struct vfio_region_info)