Messages in this thread Patch in this message | | | Subject | Re: [RFC 18/19] KVM: s390: New ioctl to configure KVM guest's AP matrix | From | Tony Krowiak <> | Date | Thu, 2 Nov 2017 14:55:41 -0400 |
| |
On 10/13/2017 01:39 PM, Tony Krowiak wrote: > Implements an ioctl to configure the adapters, usage domains > and control domains to which a KVM guest will be granted > access. The ioctl is invoked using the VFIO mediated matrix > device's file descriptor. > > Guest access to AP adapters, usage domains and control domains > is controlled by three bit masks referenced from the > guest's SIE state description: The AP Mask (APM) controls > access to the AP adapters; the AP Queue Mask (AQM) controls > access to the AP usage domains; and the AP Domain Mask (ADM) > controls access to the AP control domains. Each bit > in the APM represents an adapter, from left to right, > starting with adapter 0. Each bit in the AQM represents > a usage domain, from left to right, starting with domain 0. > Each bit in the ADM represents a control domain, from left > to right, starting with domain 0. > > The APM, AQM and ADM bit masks will be populated from the > bit masks stored in the corresponding mediated matrix device's > sysfs files. The bit masks will also be returned by the ioctl > call to the caller. > > Signed-off-by: Tony Krowiak <akrowiak@linux.vnet.ibm.com> > --- > drivers/s390/crypto/vfio_ap_matrix_ops.c | 68 +++++++++++++++++++++++++++++- > include/uapi/linux/vfio.h | 20 +++++++++ > 2 files changed, 86 insertions(+), 2 deletions(-) > > diff --git a/drivers/s390/crypto/vfio_ap_matrix_ops.c b/drivers/s390/crypto/vfio_ap_matrix_ops.c > index 74ea8db..d81e3ab 100644 > --- a/drivers/s390/crypto/vfio_ap_matrix_ops.c > +++ b/drivers/s390/crypto/vfio_ap_matrix_ops.c > @@ -160,8 +160,69 @@ static int ap_matrix_mdev_get_device_info(unsigned long arg) > return copy_to_user((void __user *)arg, &info, minsz); > } > > -static ssize_t ap_matrix_mdev_ioctl(struct mdev_device *mdev, > - unsigned int cmd, unsigned long arg) > +static int ap_matrix_configure(struct mdev_device *mdev) > +{ > + int ret; > + struct ap_matrix_mdev *matrix_mdev = mdev_get_drvdata(mdev); > + > + ret = ap_config_matrix(matrix_mdev->kvm, &matrix_mdev->masks); > + if (ret) > + return ret; > + > + return 0; > +} > + > +static int ap_matrix_copy_to_user(struct mdev_device *mdev, > + struct vfio_ap_matrix_config *mcfg, > + unsigned long arg) > +{ > + size_t i; > + struct ap_matrix_mdev *matrix_mdev = mdev_get_drvdata(mdev); > + > + > + for (i = 0; i < AP_MATRIX_MASK_INDICES; i++) { > + if (i < VFIO_AP_MATRIX_MASK_INDICES) { > + mcfg->apm[i] = matrix_mdev->masks.apm[i]; > + mcfg->aqm[i] = matrix_mdev->masks.aqm[i]; > + mcfg->adm[i] = matrix_mdev->masks.adm[i]; > + } > + } > + > + if (copy_to_user((void __user *)arg, &mcfg, sizeof(mcfg))) > + return -EFAULT; This is in error and needs to be:
if (copy_to_user((void __user *)arg, &mcfg, sizeof(*mcfg))) return -EFAULT;
> + > + return 0; > +} > + > +static ssize_t ap_matrix_mdev_configure(struct mdev_device *mdev, > + unsigned long arg) > +{ > + int ret; > + unsigned long minsz; > + struct vfio_ap_matrix_config mcfg; > + > + minsz = offsetofend(struct vfio_ap_matrix_config, adm); > + > + if (copy_from_user(&mcfg, (void __user *)arg, minsz)) > + return -EFAULT; > + > + if (mcfg.argsz < minsz) { > + pr_err("%s: Argument size %u less than min size %li", > + VFIO_AP_MATRIX_MODULE_NAME, mcfg.argsz, minsz); > + return -EINVAL; > + } > + > + ret = ap_matrix_configure(mdev); > + if (ret) > + return ret; > + > + ret = ap_matrix_copy_to_user(mdev, &mcfg, arg); > + > + return 0; > +} > + > +static long ap_matrix_mdev_ioctl(struct mdev_device *mdev, > + unsigned int cmd, unsigned long arg) > { > int ret; > > @@ -169,6 +230,9 @@ static ssize_t ap_matrix_mdev_ioctl(struct mdev_device *mdev, > case VFIO_DEVICE_GET_INFO: > ret = ap_matrix_mdev_get_device_info(arg); > break; > + case VFIO_AP_MATRIX_CONFIGURE: > + ret = ap_matrix_mdev_configure(mdev, arg); > + break; > default: > pr_err("%s: ioctl command %d is not a supported command", > VFIO_AP_MATRIX_MODULE_NAME, cmd); > diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h > index 08f1ab4..2d96c57 100644 > --- a/include/uapi/linux/vfio.h > +++ b/include/uapi/linux/vfio.h > @@ -716,6 +716,26 @@ struct vfio_iommu_spapr_tce_remove { > }; > #define VFIO_IOMMU_SPAPR_TCE_REMOVE _IO(VFIO_TYPE, VFIO_BASE + 20) > > +/** > + * VFIO_AP_MATRIX_CONFIGURE _IO(VFIO_TYPE, VFIO_BASE + 21 > + * > + * Configure the AP matrix for a KVM guest. > + */ > +#define VFIO_AP_MATRIX_CONFIGURE _IO(VFIO_TYPE, VFIO_BASE + 21) > + > +#define VFIO_AP_MATRIX_MASK_INDICES 4 > +#define VFIO_AP_MATTRIX_MASK_BYTES (VFIO_AP_MATRIX_MASK_INDICES * \ > + sizeof(__u64)) > +#define VFIO_AP_MATRIX_MASK_BITS (VFIO_AP_MATTRIX_MASK_BYTES * 8) > + > +struct vfio_ap_matrix_config { > + __u32 argsz; > + __u32 flags; > + /* out */ > + __u64 apm[VFIO_AP_MATRIX_MASK_INDICES]; > + __u64 aqm[VFIO_AP_MATRIX_MASK_INDICES]; > + __u64 adm[VFIO_AP_MATRIX_MASK_INDICES]; > +}; > /* ***************************************************************** */ > > #endif /* _UAPIVFIO_H */
| |