Message ID | 1534196899-16987-12-git-send-email-akrowiak@linux.vnet.ibm.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | guest dedicated crypto adapters | expand |
On Mon, 13 Aug 2018 17:48:08 -0400 Tony Krowiak <akrowiak@linux.vnet.ibm.com> wrote: > From: Tony Krowiak <akrowiak@linux.ibm.com> > > Introduces two new sysfs attributes for the VFIO mediated > matrix device for assigning AP domains to and unassigning > AP domains from a mediated matrix device. The IDs of the > AP domains assigned to the mediated matrix device will be > stored in an AP queue mask (AQM). > > The bits in the AQM, from most significant to least > significant bit, correspond to AP queue index (APQI) 0 to > 255 (note that an APQI is synonymous with with a domain ID). > On some systems, the maximum allowable domain number may be > less than 255 - depending upon the host's AP configuration - > and assignment may be rejected if the input domain ID exceeds > the limit. > > When a domain is assigned, the bit corresponding to the APQI > will be set in the AQM. Likewise, when a domain is unassigned, > the bit corresponding to the APQI will be cleared from the AQM. > > In order to successfully assign a domain, the APQNs derived from > the domain ID being assigned and the adapter numbers of all > adapters previously assigned: > > 1. Must be bound to the vfio_ap device driver. > > 2. Must not be assigned to any other mediated matrix device. > > If there are no adapters assigned to the mdev, then there must > be an AP queue bound to the vfio_ap device driver with an > APQN containing the domain ID (i.e., APQI), otherwise all > adapters subsequently assigned will fail because there will be no > AP queues bound with an APQN containing the APQI. > > Assigning or un-assigning an AP domain will also be rejected if > a guest using the mediated matrix device is running. > > The relevant sysfs structures are: > > /sys/devices/vfio_ap/matrix/ > ...... [mdev_supported_types] > ......... [vfio_ap-passthrough] > ............ [devices] > ...............[$uuid] > .................. assign_domain > .................. unassign_domain > > To assign a domain to the $uuid mediated matrix device, > write the domain's ID to the assign_domain file. To > unassign a domain, write the domain's ID to the > unassign_domain file. The ID is specified using > conventional semantics: If it begins with 0x, the number > will be parsed as a hexadecimal (case insensitive) number; > if it begins with 0, it will be parsed as an octal number; > otherwise, it will be parsed as a decimal number. > > For example, to assign domain 173 (0xad) to the mediated matrix > device $uuid: > > echo 173 > assign_domain > > or > > echo 0255 > assign_domain > > or > > echo 0xad > assign_domain > > To unassign domain 173 (0xad): > > echo 173 > unassign_domain > > or > > echo 0255 > unassign_domain > > or > > echo 0xad > unassign_domain > > Signed-off-by: Tony Krowiak <akrowiak@linux.ibm.com> > Reviewed-by: Halil Pasic <pasic@linux.ibm.com> > Tested-by: Michael Mueller <mimu@linux.ibm.com> > Tested-by: Farhan Ali <alifm@linux.ibm.com> > Tested-by: Pierre Morel <pmorel@linux.ibm.com> > Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com> > --- > drivers/s390/crypto/vfio_ap_ops.c | 88 ++++++++++++++++++++++++++++++++++++- > 1 files changed, 87 insertions(+), 1 deletions(-) Looks sane to me.
On 08/15/2018 08:05 AM, Cornelia Huck wrote: > On Mon, 13 Aug 2018 17:48:08 -0400 > Tony Krowiak <akrowiak@linux.vnet.ibm.com> wrote: > >> From: Tony Krowiak <akrowiak@linux.ibm.com> >> >> Introduces two new sysfs attributes for the VFIO mediated >> matrix device for assigning AP domains to and unassigning >> AP domains from a mediated matrix device. The IDs of the >> AP domains assigned to the mediated matrix device will be >> stored in an AP queue mask (AQM). >> >> The bits in the AQM, from most significant to least >> significant bit, correspond to AP queue index (APQI) 0 to >> 255 (note that an APQI is synonymous with with a domain ID). >> On some systems, the maximum allowable domain number may be >> less than 255 - depending upon the host's AP configuration - >> and assignment may be rejected if the input domain ID exceeds >> the limit. >> >> When a domain is assigned, the bit corresponding to the APQI >> will be set in the AQM. Likewise, when a domain is unassigned, >> the bit corresponding to the APQI will be cleared from the AQM. >> >> In order to successfully assign a domain, the APQNs derived from >> the domain ID being assigned and the adapter numbers of all >> adapters previously assigned: >> >> 1. Must be bound to the vfio_ap device driver. >> >> 2. Must not be assigned to any other mediated matrix device. >> >> If there are no adapters assigned to the mdev, then there must >> be an AP queue bound to the vfio_ap device driver with an >> APQN containing the domain ID (i.e., APQI), otherwise all >> adapters subsequently assigned will fail because there will be no >> AP queues bound with an APQN containing the APQI. >> >> Assigning or un-assigning an AP domain will also be rejected if >> a guest using the mediated matrix device is running. >> >> The relevant sysfs structures are: >> >> /sys/devices/vfio_ap/matrix/ >> ...... [mdev_supported_types] >> ......... [vfio_ap-passthrough] >> ............ [devices] >> ...............[$uuid] >> .................. assign_domain >> .................. unassign_domain >> >> To assign a domain to the $uuid mediated matrix device, >> write the domain's ID to the assign_domain file. To >> unassign a domain, write the domain's ID to the >> unassign_domain file. The ID is specified using >> conventional semantics: If it begins with 0x, the number >> will be parsed as a hexadecimal (case insensitive) number; >> if it begins with 0, it will be parsed as an octal number; >> otherwise, it will be parsed as a decimal number. >> >> For example, to assign domain 173 (0xad) to the mediated matrix >> device $uuid: >> >> echo 173 > assign_domain >> >> or >> >> echo 0255 > assign_domain >> >> or >> >> echo 0xad > assign_domain >> >> To unassign domain 173 (0xad): >> >> echo 173 > unassign_domain >> >> or >> >> echo 0255 > unassign_domain >> >> or >> >> echo 0xad > unassign_domain >> >> Signed-off-by: Tony Krowiak <akrowiak@linux.ibm.com> >> Reviewed-by: Halil Pasic <pasic@linux.ibm.com> >> Tested-by: Michael Mueller <mimu@linux.ibm.com> >> Tested-by: Farhan Ali <alifm@linux.ibm.com> >> Tested-by: Pierre Morel <pmorel@linux.ibm.com> >> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com> >> --- >> drivers/s390/crypto/vfio_ap_ops.c | 88 ++++++++++++++++++++++++++++++++++++- >> 1 files changed, 87 insertions(+), 1 deletions(-) > Looks sane to me. Sanity rules! >
diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c index dfb434c..c4d7504 100644 --- a/drivers/s390/crypto/vfio_ap_ops.c +++ b/drivers/s390/crypto/vfio_ap_ops.c @@ -363,10 +363,96 @@ static ssize_t unassign_adapter_store(struct device *dev, } DEVICE_ATTR_WO(unassign_adapter); +static int +vfio_ap_mdev_verify_queues_reserved_for_apqi(struct ap_matrix_mdev *matrix_mdev, + unsigned long apqi) +{ + int ret; + unsigned long apid; + unsigned long nbits = matrix_mdev->matrix.apm_max + 1; + + if (find_first_bit_inv(matrix_mdev->matrix.apm, nbits) >= nbits) + return vfio_ap_verify_queue_reserved(NULL, &apqi); + + for_each_set_bit_inv(apid, matrix_mdev->matrix.apm, nbits) { + ret = vfio_ap_verify_queue_reserved(&apid, &apqi); + if (ret) + return ret; + } + + return 0; +} + +static ssize_t assign_domain_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int ret; + unsigned long apqi; + struct mdev_device *mdev = mdev_from_dev(dev); + struct ap_matrix_mdev *matrix_mdev = mdev_get_drvdata(mdev); + unsigned long max_apqi = matrix_mdev->matrix.aqm_max; + + ret = kstrtoul(buf, 0, &apqi); + if (ret) + return ret; + if (apqi > max_apqi) + return -EINVAL; + + mutex_lock(&matrix_dev.lock); + + ret = vfio_ap_mdev_verify_queues_reserved_for_apqi(matrix_mdev, apqi); + if (ret) + goto done; + + set_bit_inv(apqi, matrix_mdev->matrix.aqm); + + ret = vfio_ap_mdev_verify_no_sharing(matrix_mdev); + if (ret) + goto share_err; + + ret = count; + goto done; + +share_err: + clear_bit_inv(apqi, matrix_mdev->matrix.aqm); +done: + mutex_unlock(&matrix_dev.lock); + + return ret; +} +DEVICE_ATTR_WO(assign_domain); + +static ssize_t unassign_domain_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int ret; + unsigned long apqi; + struct mdev_device *mdev = mdev_from_dev(dev); + struct ap_matrix_mdev *matrix_mdev = mdev_get_drvdata(mdev); + + ret = kstrtoul(buf, 0, &apqi); + if (ret) + return ret; + + if (apqi > matrix_mdev->matrix.aqm_max) + return -EINVAL; + + mutex_lock(&matrix_dev.lock); + clear_bit_inv((unsigned long)apqi, matrix_mdev->matrix.aqm); + mutex_unlock(&matrix_dev.lock); + + return count; +} +DEVICE_ATTR_WO(unassign_domain); + static struct attribute *vfio_ap_mdev_attrs[] = { &dev_attr_assign_adapter.attr, &dev_attr_unassign_adapter.attr, - NULL + &dev_attr_assign_domain.attr, + &dev_attr_unassign_domain.attr, + NULL, }; static struct attribute_group vfio_ap_mdev_attr_group = {