Re: [PATCH 29/32] vfio-pci/zdev: wire up zPCI IOAT assist support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 





On 12/7/21 21:57, Matthew Rosato wrote:
Introduce support for VFIO_DEVICE_FEATURE_ZPCI_IOAT, which is a new
VFIO_DEVICE_FEATURE ioctl.  This interface is used to indicate that an
s390x vfio-pci device wishes to enable/disable zPCI I/O Address
Translation assistance, allowing the host to perform address translation
and shadowing.

Signed-off-by: Matthew Rosato <mjrosato@xxxxxxxxxxxxx>
---
  arch/s390/include/asm/kvm_pci.h  |  1 +
  drivers/vfio/pci/vfio_pci_core.c |  2 ++
  drivers/vfio/pci/vfio_pci_zdev.c | 61 ++++++++++++++++++++++++++++++++
  include/linux/vfio_pci_core.h    | 10 ++++++
  include/uapi/linux/vfio.h        |  8 +++++
  include/uapi/linux/vfio_zdev.h   | 13 +++++++
  6 files changed, 95 insertions(+)

diff --git a/arch/s390/include/asm/kvm_pci.h b/arch/s390/include/asm/kvm_pci.h
index 0a0e42e1db1c..0b362d55c7b2 100644
--- a/arch/s390/include/asm/kvm_pci.h
+++ b/arch/s390/include/asm/kvm_pci.h
@@ -32,6 +32,7 @@ struct kvm_zdev {
  	struct zpci_dev *zdev;
  	struct kvm *kvm;
  	u64 rpcit_count;
+	u64 iota;
  	struct kvm_zdev_ioat ioat;
  	struct zpci_fib fib;
  	struct notifier_block nb;
diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c
index 01658de660bd..709d9ba22a60 100644
--- a/drivers/vfio/pci/vfio_pci_core.c
+++ b/drivers/vfio/pci/vfio_pci_core.c
@@ -1176,6 +1176,8 @@ long vfio_pci_core_ioctl(struct vfio_device *core_vdev, unsigned int cmd,
  			return vfio_pci_zdev_feat_interp(vdev, feature, arg);
  		case VFIO_DEVICE_FEATURE_ZPCI_AIF:
  			return vfio_pci_zdev_feat_aif(vdev, feature, arg);
+		case VFIO_DEVICE_FEATURE_ZPCI_IOAT:
+			return vfio_pci_zdev_feat_ioat(vdev, feature, arg);
  		default:
  			return -ENOTTY;
  		}
diff --git a/drivers/vfio/pci/vfio_pci_zdev.c b/drivers/vfio/pci/vfio_pci_zdev.c
index dd98808b9139..85be77492a6d 100644
--- a/drivers/vfio/pci/vfio_pci_zdev.c
+++ b/drivers/vfio/pci/vfio_pci_zdev.c
@@ -298,6 +298,66 @@ int vfio_pci_zdev_feat_aif(struct vfio_pci_core_device *vdev,
  	return rc;
  }
+int vfio_pci_zdev_feat_ioat(struct vfio_pci_core_device *vdev,
+			    struct vfio_device_feature feature,
+			    unsigned long arg)
+{
+	struct zpci_dev *zdev = to_zpci(vdev->pdev);
+	struct vfio_device_zpci_ioat *data;
+	struct vfio_device_feature *feat;
+	unsigned long minsz;
+	int size, rc = 0;
+
+	if (!zdev || !zdev->kzdev)
+		return -EINVAL;
+
+	/*
+	 * If PROBE requested and feature not found, leave immediately.
+	 * Otherwise, keep going as GET or SET may also be specified.
+	 */
+	if (feature.flags & VFIO_DEVICE_FEATURE_PROBE) {
+		rc = kvm_s390_pci_ioat_probe(zdev);
+		if (rc)
+			return rc;
+	}
+	if (!(feature.flags & (VFIO_DEVICE_FEATURE_GET +
+			       VFIO_DEVICE_FEATURE_SET)))
+		return 0;
+

I think you should verify the argsz.

+	size = sizeof(*feat) + sizeof(*data);
+	feat = kzalloc(size, GFP_KERNEL);
+	if (!feat)
+		return -ENOMEM;
+
+	data = (struct vfio_device_zpci_ioat *)&feat->data;
+	minsz = offsetofend(struct vfio_device_feature, flags);
+
+	/* Get the rest of the payload for GET/SET */
+	rc = copy_from_user(data, (void __user *)(arg + minsz),
+			sizeof(*data));

Alignment

+	if (rc)
+		rc = -EINVAL;
+
+	if (feature.flags & VFIO_DEVICE_FEATURE_GET) {
+		data->iota = (u64)zdev->kzdev->iota;
+		if (copy_to_user((void __user *)arg, feat, size))
+			rc = -EFAULT;
+	} else if (feature.flags & VFIO_DEVICE_FEATURE_SET) {
+		if (data->iota != 0) {
+			rc = kvm_s390_pci_ioat_enable(zdev, data->iota);
+			if (!rc)
+				zdev->kzdev->iota = data->iota;
+		} else if (zdev->kzdev->iota != 0) {
+			rc = kvm_s390_pci_ioat_disable(zdev);
+			if (!rc)
+				zdev->kzdev->iota = 0;
+		}
+	}
+
+	kfree(feat);
+	return rc;
+}
+
  static int vfio_pci_zdev_group_notifier(struct notifier_block *nb,
  					unsigned long action, void *data)
  {
@@ -353,6 +413,7 @@ int vfio_pci_zdev_release(struct vfio_pci_core_device *vdev)
  	 */
  	if (zdev->gd != 0) {
  		kvm_s390_pci_aif_disable(zdev);
+		kvm_s390_pci_ioat_disable(zdev);
  		kvm_s390_pci_interp_disable(zdev);
  	}
diff --git a/include/linux/vfio_pci_core.h b/include/linux/vfio_pci_core.h
index 5442d3fa1662..7c45a425e7f8 100644
--- a/include/linux/vfio_pci_core.h
+++ b/include/linux/vfio_pci_core.h
@@ -204,6 +204,9 @@ int vfio_pci_zdev_feat_interp(struct vfio_pci_core_device *vdev,
  int vfio_pci_zdev_feat_aif(struct vfio_pci_core_device *vdev,
  			   struct vfio_device_feature feature,
  			   unsigned long arg);
+int vfio_pci_zdev_feat_ioat(struct vfio_pci_core_device *vdev,
+			    struct vfio_device_feature feature,
+			    unsigned long arg);
  int vfio_pci_zdev_open(struct vfio_pci_core_device *vdev);
  int vfio_pci_zdev_release(struct vfio_pci_core_device *vdev);
  #else
@@ -227,6 +230,13 @@ static inline int vfio_pci_zdev_feat_aif(struct vfio_pci_core_device *vdev,
  	return -ENOTTY;
  }
+static inline int vfio_pci_zdev_feat_ioat(struct vfio_pci_core_device *vdev,
+					  struct vfio_device_feature feature,
+					  unsigned long arg)
+{
+	return -ENOTTY;
+}
+
  static inline int vfio_pci_zdev_open(struct vfio_pci_core_device *vdev)
  {
  	return -ENODEV;
diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
index fe3bfd99bf50..32c687388f48 100644
--- a/include/uapi/linux/vfio.h
+++ b/include/uapi/linux/vfio.h
@@ -1016,6 +1016,14 @@ struct vfio_device_feature {
   */
  #define VFIO_DEVICE_FEATURE_ZPCI_AIF		(2)
+/*
+ * Provide support for enabling guest I/O address translation assistance for
+ * zPCI devices.  This feature is only valid for s390x PCI devices.  Data
+ * provided when setting and getting this feature is further described in
+ * vfio_zdev.h
+ */
+#define VFIO_DEVICE_FEATURE_ZPCI_IOAT		(3)
+
  /* -------- API for Type1 VFIO IOMMU -------- */
/**
diff --git a/include/uapi/linux/vfio_zdev.h b/include/uapi/linux/vfio_zdev.h
index c574e23f9385..1a5229b7bb18 100644
--- a/include/uapi/linux/vfio_zdev.h
+++ b/include/uapi/linux/vfio_zdev.h
@@ -110,4 +110,17 @@ struct vfio_device_zpci_aif {
  	__u8 sbo;		/* Offset of guest summary bit vector */
  };
+/**
+ * VFIO_DEVICE_FEATURE_ZPCI_IOAT
+ *
+ * This feature is used for enabling guest I/O translation assistance for
+ * passthrough zPCI devices using instruction interpretation.  When setting
+ * this feature, the iota specifies a KVM guest I/O translation anchor.  When
+ * getting this feature, the most recently set anchor (or 0) is returned in
+ * iota.
+ */
+struct vfio_device_zpci_ioat {
+	__u64 iota;
+};
+
  #endif


--
Pierre Morel
IBM Lab Boeblingen



[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux