public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
From: Tony Krowiak <akrowiak@linux.vnet.ibm.com>
To: linux-s390@vger.kernel.org, linux-kernel@vger.kernel.org,
	kvm@vger.kernel.org
Cc: freude@de.ibm.com, schwidefsky@de.ibm.com,
	heiko.carstens@de.ibm.com, borntraeger@de.ibm.com,
	cohuck@redhat.com, kwankhede@nvidia.com,
	bjsdjshi@linux.vnet.ibm.com, pbonzini@redhat.com,
	alex.williamson@redhat.com, pmorel@linux.vnet.ibm.com,
	alifm@linux.vnet.ibm.com, mjrosato@linux.vnet.ibm.com,
	jjherne@linux.vnet.ibm.com, thuth@redhat.com,
	pasic@linux.vnet.ibm.com, berrange@redhat.com,
	fiuczy@linux.vnet.ibm.com, buendgen@de.ibm.com,
	akrowiak@linux.vnet.ibm.com,
	Tony Krowiak <akrowiak@linux.ibm.com>
Subject: [PATCH v6 11/21] s390: vfio-ap: sysfs interfaces to configure domains
Date: Fri, 29 Jun 2018 17:11:13 -0400	[thread overview]
Message-ID: <1530306683-7270-12-git-send-email-akrowiak@linux.vnet.ibm.com> (raw)
In-Reply-To: <1530306683-7270-1-git-send-email-akrowiak@linux.vnet.ibm.com>

Provides the sysfs interfaces for assigning AP domains to
and unassigning AP domains from a mediated matrix device.

An AP domain ID corresponds to an AP queue index (APQI). For
each domain assigned to the mediated matrix device, its
corresponging APQI is stored in an AP queue mask (AQM).
The bits in the AQM, from most significant to least
significant bit, correspond to AP domain numbers 0 to 255.
When a domain is assigned, the bit corresponding to its
APQI will be set in the AQM. Likewise, when a domain is
unassigned, the bit corresponding to its APQI will be
cleared from the AQM.

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

The assignment will be rejected:

* If the domain ID exceeds the maximum value for an AP domain:

  * If the AP Extended Addressing (APXA) facility is installed,
    the max value is 255

  * Else the max value is 15

* If no AP adapters have yet been assigned and there are
  no AP queues reserved by the VFIO AP driver that have an APQN
  with an APQI matching that of the AP domain number being
  assigned.

* If any of the APQNs that can be derived from the intersection
  of the APQI being assigned and the AP adapter ID (APID) of
  each of the AP adapters previously assigned can not be matched
  with an APQN of an AP queue device reserved by the VFIO AP
  driver.

Signed-off-by: Tony Krowiak <akrowiak@linux.ibm.com>
---
 drivers/s390/crypto/vfio_ap_ops.c |  173 ++++++++++++++++++++++++++++++++++++-
 1 files changed, 172 insertions(+), 1 deletions(-)

diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c
index a4351bd..a5b06e7 100644
--- a/drivers/s390/crypto/vfio_ap_ops.c
+++ b/drivers/s390/crypto/vfio_ap_ops.c
@@ -170,6 +170,27 @@ static int vfio_ap_queue_has_apid(struct device *dev, void *data)
 }
 
 /**
+ * vfio_ap_queue_has_apqi
+ *
+ * @dev: an AP queue device
+ * @data: an AP queue index
+ *
+ * Flags whether any AP queue device has a particular AP queue index
+ *
+ * Returns 0 to indicate the function succeeded
+ */
+static int vfio_ap_queue_has_apqi(struct device *dev, void *data)
+{
+	struct vfio_id_reserved *id_res = data;
+	struct ap_queue *ap_queue = to_ap_queue(dev);
+
+	if (id_res->id == AP_QID_QUEUE(ap_queue->qid))
+		id_res->reserved = true;
+
+	return 0;
+}
+
+/**
  * vfio_ap_verify_qid_reserved
  *
  * @matrix_dev: a mediated matrix device
@@ -236,6 +257,42 @@ static int vfio_ap_verify_apid_reserved(struct ap_matrix_dev *matrix_dev,
 	return -EPERM;
 }
 
+/**
+ * vfio_ap_verify_apqi_reserved
+ *
+ * @matrix_dev: a mediated matrix device
+ * @apqi: an AP queue index
+ *
+ * Verifies that an AP queue with @apqi is reserved by the VFIO AP device
+ * driver.
+ *
+ * Returns 0 if an AP queue with @apqi is reserved; otherwise, returns -ENODEV.
+ */
+static int vfio_ap_verify_apqi_reserved(struct ap_matrix_dev *matrix_dev,
+					const char *mdev_name,
+					unsigned long apqi)
+{
+	int ret;
+	struct vfio_id_reserved id_res;
+
+	id_res.id = apqi;
+	id_res.reserved = false;
+
+	ret = driver_for_each_device(matrix_dev->device.driver, NULL, &id_res,
+				     vfio_ap_queue_has_apqi);
+	if (ret)
+		return ret;
+
+	if (id_res.reserved)
+		return 0;
+
+	pr_err("%s: mdev %s using queue %04lx not reserved by %s driver",
+					VFIO_AP_MODULE_NAME, mdev_name, apqi,
+					VFIO_AP_DRV_NAME);
+
+	return -EPERM;
+}
+
 static int vfio_ap_verify_queues_reserved(struct ap_matrix_dev *matrix_dev,
 					  const char *mdev_name,
 					  struct ap_matrix *matrix)
@@ -417,10 +474,124 @@ static ssize_t unassign_adapter_store(struct device *dev,
 }
 DEVICE_ATTR_WO(unassign_adapter);
 
+/**
+ * vfio_ap_validate_apqi
+ *
+ * @matrix_mdev: the mediated matrix device
+ * @apqi: the APQI (domain ID) to validate
+ *
+ * Validates the value of @apqi:
+ *	* If there are no AP adapters assigned, then there must be at least
+ *	  one AP queue device reserved by the VFIO AP device driver with an
+ *	  APQN containing @apqi.
+ *
+ *	* Else each APQN that can be derived from the cross product of @apqi and
+ *	  the IDs of the AP adapters already assigned must identify an AP queue
+ *	  that has been reserved by the VFIO AP device driver.
+ *
+ * Returns 0 if the value of @apqi is valid; otherwise, returns an error.
+ */
+static int vfio_ap_validate_apqi(struct mdev_device *mdev,
+				 struct ap_matrix_mdev *matrix_mdev,
+				 unsigned long apqi)
+{
+	int ret;
+	unsigned long apmsz = matrix_mdev->matrix.apm_max + 1;
+	struct device *dev = mdev_parent_dev(mdev);
+	struct ap_matrix_dev *matrix_dev = to_ap_matrix_dev(dev);
+	struct ap_matrix matrix = matrix_mdev->matrix;
+
+	/* If there are any adapters assigned to the mediated device */
+	if (find_first_bit_inv(matrix.apm, apmsz) < apmsz) {
+		matrix.apm_max = matrix_mdev->matrix.apm_max;
+		memcpy(matrix.apm, matrix_mdev->matrix.apm,
+		       ARRAY_SIZE(matrix.apm) * sizeof(matrix.apm[0]));
+		matrix.aqm_max = matrix_mdev->matrix.aqm_max;
+		memset(matrix.aqm, 0,
+		       ARRAY_SIZE(matrix.aqm) * sizeof(matrix.aqm[0]));
+		set_bit_inv(apqi, matrix.aqm);
+		ret = vfio_ap_verify_queues_reserved(matrix_dev,
+						     matrix_mdev->name,
+						     &matrix);
+	} else {
+		ret = vfio_ap_verify_apqi_reserved(matrix_dev,
+						   matrix_mdev->name, 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 || (apqi > max_apqi)) {
+		pr_err("%s: %s: domain id '%s' not a value from 0 to %02lu(%#04lx)",
+		       VFIO_AP_MODULE_NAME, __func__, buf, max_apqi, max_apqi);
+
+		return ret ? ret : -EINVAL;
+	}
+
+	ret = vfio_ap_validate_apqi(mdev, matrix_mdev, apqi);
+	if (ret)
+		return ret;
+
+	/* Set the bit in the AQM (bitmask) corresponding to the AP domain
+	 * number (APQI). The bits in the mask, from most significant to least
+	 * significant, correspond to numbers 0-255.
+	 */
+	set_bit_inv(apqi, matrix_mdev->matrix.aqm);
+
+	return count;
+}
+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);
+	unsigned long max_apqi = matrix_mdev->matrix.aqm_max;
+
+	ret = kstrtoul(buf, 0, &apqi);
+	if (ret || (apqi > max_apqi)) {
+		pr_err("%s: %s: domain id '%s' not a value from 0 to %02lu(%#04lx)",
+		       VFIO_AP_MODULE_NAME, __func__, buf, max_apqi, max_apqi);
+
+		return ret ? ret : -EINVAL;
+	}
+
+	if (!test_bit_inv(apqi, matrix_mdev->matrix.aqm)) {
+		pr_err("%s: %s: domain %02lu(%#04lx) not assigned",
+		       VFIO_AP_MODULE_NAME, __func__, apqi, apqi);
+		return -ENODEV;
+	}
+
+	clear_bit_inv((unsigned long)apqi, matrix_mdev->matrix.aqm);
+
+	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 = {
-- 
1.7.1

  parent reply	other threads:[~2018-06-29 21:11 UTC|newest]

Thread overview: 79+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-06-29 21:11 [PATCH v6 00/21] s390: vfio-ap: guest dedicated crypto adapters Tony Krowiak
2018-06-29 21:11 ` [PATCH v6 01/21] s390/zcrypt: Add ZAPQ inline function Tony Krowiak
2018-06-29 21:11 ` [PATCH v6 02/21] s390/zcrypt: Review inline assembler constraints Tony Krowiak
2018-06-29 21:11 ` [PATCH v6 03/21] s390/zcrypt: Show load of cards and queues in sysfs Tony Krowiak
2018-06-29 21:11 ` [PATCH v6 04/21] s390/zcrypt: Integrate ap_asm.h into include/asm/ap.h Tony Krowiak
2018-06-29 21:11 ` [PATCH v6 05/21] KVM: s390: CPU model support for AP virtualization Tony Krowiak
2018-07-02 14:38   ` Christian Borntraeger
2018-07-02 15:37     ` Tony Krowiak
2018-07-02 15:41       ` Cornelia Huck
2018-07-02 15:54         ` Tony Krowiak
2018-07-02 16:11           ` Cornelia Huck
2018-07-02 16:20             ` Halil Pasic
2018-07-02 16:28               ` Cornelia Huck
2018-07-03 14:44                 ` Tony Krowiak
2018-07-02 16:04       ` Halil Pasic
2018-07-02 15:56   ` Tony Krowiak
2018-06-29 21:11 ` [PATCH v6 06/21] KVM: s390: refactor crypto initialization Tony Krowiak
2018-06-29 21:11 ` [PATCH v6 07/21] s390: vfio-ap: base implementation of VFIO AP device driver Tony Krowiak
2018-07-02 13:53   ` Halil Pasic
2018-07-02 15:39     ` Tony Krowiak
2018-06-29 21:11 ` [PATCH v6 08/21] s390: vfio-ap: register matrix device with VFIO mdev framework Tony Krowiak
2018-07-09 14:17   ` Pierre Morel
2018-07-10  7:03     ` Harald Freudenberger
2018-07-12  7:32       ` Tony Krowiak
2018-07-09 15:44   ` Pierre Morel
2018-06-29 21:11 ` [PATCH v6 09/21] s390: vfio-ap: structure for storing mdev matrix Tony Krowiak
2018-07-06 14:26   ` Halil Pasic
2018-07-12 14:34     ` Tony Krowiak
2018-06-29 21:11 ` [PATCH v6 10/21] s390: vfio-ap: sysfs interfaces to configure adapters Tony Krowiak
2018-07-09 12:11   ` Pierre Morel
2018-07-13 12:20     ` Tony Krowiak
2018-06-29 21:11 ` Tony Krowiak [this message]
2018-07-09 12:13   ` [PATCH v6 11/21] s390: vfio-ap: sysfs interfaces to configure domains Pierre Morel
2018-06-29 21:11 ` [PATCH v6 12/21] s390: vfio-ap: sysfs interfaces to configure control domains Tony Krowiak
2018-06-29 21:11 ` [PATCH v6 13/21] s390: vfio-ap: sysfs interface to view matrix mdev matrix Tony Krowiak
2018-07-09 12:20   ` Pierre Morel
2018-07-09 14:38     ` Pierre Morel
2018-07-13 12:24       ` Tony Krowiak
2018-07-13 16:38         ` Halil Pasic
2018-06-29 21:11 ` [PATCH v6 14/21] s390: vfio-ap: implement mediated device open callback Tony Krowiak
2018-07-12 12:47   ` Halil Pasic
2018-07-12 16:03     ` Tony Krowiak
2018-07-13 10:48       ` Halil Pasic
2018-06-29 21:11 ` [PATCH v6 15/21] s390: vfio-ap: configure the guest's AP matrix Tony Krowiak
2018-07-11 23:22   ` Halil Pasic
2018-07-12 14:36     ` Tony Krowiak
2018-07-12 13:28   ` Halil Pasic
2018-07-12 14:37     ` Tony Krowiak
2018-06-29 21:11 ` [PATCH v6 16/21] s390: vfio-ap: sysfs interface to view guest matrix Tony Krowiak
2018-06-29 21:11 ` [PATCH v6 17/21] s390: vfio-ap: implement VFIO_DEVICE_GET_INFO ioctl Tony Krowiak
2018-06-29 21:11 ` [PATCH v6 18/21] s390: vfio-ap: zeroize the AP queues Tony Krowiak
2018-06-29 21:11 ` [PATCH v6 19/21] s390: vfio-ap: implement VFIO_DEVICE_RESET ioctl Tony Krowiak
2018-06-29 21:11 ` [PATCH v6 20/21] KVM: s390: Handling of Cypto control block in VSIE Tony Krowiak
2018-06-29 21:11 ` [PATCH v6 21/21] s390: doc: detailed specifications for AP virtualization Tony Krowiak
2018-07-02 16:28   ` Halil Pasic
2018-07-03  7:46     ` Harald Freudenberger
2018-07-03  9:22       ` Halil Pasic
2018-07-03 11:52         ` Cornelia Huck
2018-07-03 12:20           ` Halil Pasic
2018-07-03 13:25             ` Cornelia Huck
2018-07-03 13:58               ` Halil Pasic
2018-07-03 14:30                 ` Cornelia Huck
2018-07-03 15:25                   ` Tony Krowiak
2018-07-03 16:14                   ` Halil Pasic
2018-07-03 15:20               ` Tony Krowiak
2018-07-03 15:17             ` Tony Krowiak
2018-07-03 15:00           ` Tony Krowiak
2018-07-03 14:56       ` Tony Krowiak
2018-07-04  8:31         ` Harald Freudenberger
2018-07-02 23:10   ` Halil Pasic
2018-07-03 16:36     ` Tony Krowiak
2018-07-04 16:31       ` Boris Fiuczynski
2018-07-05 13:29         ` Tony Krowiak
2018-07-09  9:21     ` Pierre Morel
2018-07-09 15:50       ` Halil Pasic
2018-07-10  8:49         ` Pierre Morel
2018-07-12  7:26       ` Tony Krowiak
2018-07-03  8:10   ` Harald Freudenberger
2018-07-09  9:02     ` Pierre Morel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1530306683-7270-12-git-send-email-akrowiak@linux.vnet.ibm.com \
    --to=akrowiak@linux.vnet.ibm.com \
    --cc=akrowiak@linux.ibm.com \
    --cc=alex.williamson@redhat.com \
    --cc=alifm@linux.vnet.ibm.com \
    --cc=berrange@redhat.com \
    --cc=bjsdjshi@linux.vnet.ibm.com \
    --cc=borntraeger@de.ibm.com \
    --cc=buendgen@de.ibm.com \
    --cc=cohuck@redhat.com \
    --cc=fiuczy@linux.vnet.ibm.com \
    --cc=freude@de.ibm.com \
    --cc=heiko.carstens@de.ibm.com \
    --cc=jjherne@linux.vnet.ibm.com \
    --cc=kvm@vger.kernel.org \
    --cc=kwankhede@nvidia.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-s390@vger.kernel.org \
    --cc=mjrosato@linux.vnet.ibm.com \
    --cc=pasic@linux.vnet.ibm.com \
    --cc=pbonzini@redhat.com \
    --cc=pmorel@linux.vnet.ibm.com \
    --cc=schwidefsky@de.ibm.com \
    --cc=thuth@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox