kvm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Tony Krowiak <akrowiak@linux.ibm.com>
To: linux-s390@vger.kernel.org, linux-kernel@vger.kernel.org,
	kvm@vger.kernel.org
Cc: freude@linux.ibm.com, borntraeger@de.ibm.com, cohuck@redhat.com,
	mjrosato@linux.ibm.com, pasic@linux.ibm.com,
	alex.williamson@redhat.com, kwankhede@nvidia.com,
	fiuczy@linux.ibm.com, frankja@linux.ibm.com, david@redhat.com,
	imbrenda@linux.ibm.com, hca@linux.ibm.com, gor@linux.ibm.com,
	Tony Krowiak <akrowiak@linux.ibm.com>
Subject: [PATCH v10 09/16] s390/vfio-ap: allow assignment of unavailable AP queues to mdev device
Date: Fri, 21 Aug 2020 15:56:09 -0400	[thread overview]
Message-ID: <20200821195616.13554-10-akrowiak@linux.ibm.com> (raw)
In-Reply-To: <20200821195616.13554-1-akrowiak@linux.ibm.com>

The current implementation does not allow assignment of an AP adapter or
domain to an mdev device if the APQNs resulting from the assignment
do not reference AP queue devices that are bound to the vfio_ap device
driver. This patch allows assignment of AP resources to the matrix mdev as
long as the APQNs resulting from the assignment:
   1. Are not reserved by the AP BUS for use by the zcrypt device drivers.
   2. Are not assigned to another matrix mdev.

The rationale behind this is twofold:
   1. The AP architecture does not preclude assignment of APQNs to an AP
      configuration that are not available to the system.
   2. APQNs that do not reference a queue device bound to the vfio_ap
      device driver will not be assigned to the guest's CRYCB, so the
      guest will not get access to queues not bound to the vfio_ap driver.

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

diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c
index eaf4e9eab6cb..24fd47e43b80 100644
--- a/drivers/s390/crypto/vfio_ap_ops.c
+++ b/drivers/s390/crypto/vfio_ap_ops.c
@@ -1,4 +1,3 @@
-// SPDX-License-Identifier: GPL-2.0+
 /*
  * Adjunct processor matrix VFIO device driver callbacks.
  *
@@ -420,122 +419,6 @@ static struct attribute_group *vfio_ap_mdev_type_groups[] = {
 	NULL,
 };
 
-struct vfio_ap_queue_reserved {
-	unsigned long *apid;
-	unsigned long *apqi;
-	bool reserved;
-};
-
-/**
- * vfio_ap_has_queue
- *
- * @dev: an AP queue device
- * @data: a struct vfio_ap_queue_reserved reference
- *
- * Flags whether the AP queue device (@dev) has a queue ID containing the APQN,
- * apid or apqi specified in @data:
- *
- * - If @data contains both an apid and apqi value, then @data will be flagged
- *   as reserved if the APID and APQI fields for the AP queue device matches
- *
- * - If @data contains only an apid value, @data will be flagged as
- *   reserved if the APID field in the AP queue device matches
- *
- * - If @data contains only an apqi value, @data will be flagged as
- *   reserved if the APQI field in the AP queue device matches
- *
- * Returns 0 to indicate the input to function succeeded. Returns -EINVAL if
- * @data does not contain either an apid or apqi.
- */
-static int vfio_ap_has_queue(struct device *dev, void *data)
-{
-	struct vfio_ap_queue_reserved *qres = data;
-	struct ap_queue *ap_queue = to_ap_queue(dev);
-	ap_qid_t qid;
-	unsigned long id;
-
-	if (qres->apid && qres->apqi) {
-		qid = AP_MKQID(*qres->apid, *qres->apqi);
-		if (qid == ap_queue->qid)
-			qres->reserved = true;
-	} else if (qres->apid && !qres->apqi) {
-		id = AP_QID_CARD(ap_queue->qid);
-		if (id == *qres->apid)
-			qres->reserved = true;
-	} else if (!qres->apid && qres->apqi) {
-		id = AP_QID_QUEUE(ap_queue->qid);
-		if (id == *qres->apqi)
-			qres->reserved = true;
-	} else {
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-/**
- * vfio_ap_verify_queue_reserved
- *
- * @matrix_dev: a mediated matrix device
- * @apid: an AP adapter ID
- * @apqi: an AP queue index
- *
- * Verifies that the AP queue with @apid/@apqi is reserved by the VFIO AP device
- * driver according to the following rules:
- *
- * - If both @apid and @apqi are not NULL, then there must be an AP queue
- *   device bound to the vfio_ap driver with the APQN identified by @apid and
- *   @apqi
- *
- * - If only @apid is not NULL, then there must be an AP queue device bound
- *   to the vfio_ap driver with an APQN containing @apid
- *
- * - If only @apqi is not NULL, then there must be an AP queue device bound
- *   to the vfio_ap driver with an APQN containing @apqi
- *
- * Returns 0 if the AP queue is reserved; otherwise, returns -EADDRNOTAVAIL.
- */
-static int vfio_ap_verify_queue_reserved(unsigned long *apid,
-					 unsigned long *apqi)
-{
-	int ret;
-	struct vfio_ap_queue_reserved qres;
-
-	qres.apid = apid;
-	qres.apqi = apqi;
-	qres.reserved = false;
-
-	ret = driver_for_each_device(&matrix_dev->vfio_ap_drv->driver, NULL,
-				     &qres, vfio_ap_has_queue);
-	if (ret)
-		return ret;
-
-	if (qres.reserved)
-		return 0;
-
-	return -EADDRNOTAVAIL;
-}
-
-static int
-vfio_ap_mdev_verify_queues_reserved_for_apid(struct ap_matrix_mdev *matrix_mdev,
-					     unsigned long apid)
-{
-	int ret;
-	unsigned long apqi;
-	unsigned long nbits = matrix_mdev->matrix.aqm_max + 1;
-
-	if (find_first_bit_inv(matrix_mdev->matrix.aqm, nbits) >= nbits)
-		return vfio_ap_verify_queue_reserved(&apid, NULL);
-
-	for_each_set_bit_inv(apqi, matrix_mdev->matrix.aqm, nbits) {
-		ret = vfio_ap_verify_queue_reserved(&apid, &apqi);
-		if (ret)
-			return ret;
-	}
-
-	return 0;
-}
-
 #define MDEV_SHARING_ERR "Userspace may not re-assign queue %02lx.%04lx " \
 			 "already assigned to %s"
 
@@ -572,6 +455,11 @@ static int vfio_ap_mdev_verify_no_sharing(struct ap_matrix_mdev *matrix_mdev,
 	DECLARE_BITMAP(aqm, AP_DOMAINS);
 
 	list_for_each_entry(lstdev, &matrix_dev->mdev_list, node) {
+		/*
+		 * If either of the input masks belongs to the mdev to which an
+		 * AP resource is being assigned, then we don't need to verify
+		 * that mdev's masks.
+		 */
 		if (matrix_mdev == lstdev)
 			continue;
 
@@ -597,6 +485,20 @@ static int vfio_ap_mdev_verify_no_sharing(struct ap_matrix_mdev *matrix_mdev,
 	return 0;
 }
 
+static int vfio_ap_mdev_validate_masks(struct ap_matrix_mdev *matrix_mdev,
+				       unsigned long *mdev_apm,
+				       unsigned long *mdev_aqm)
+{
+	DECLARE_BITMAP(apm, AP_DEVICES);
+	DECLARE_BITMAP(aqm, AP_DOMAINS);
+
+	if (bitmap_and(apm, mdev_apm, ap_perms.apm, AP_DEVICES) &&
+	    bitmap_and(aqm, mdev_aqm, ap_perms.aqm, AP_DOMAINS))
+		return -EADDRNOTAVAIL;
+
+	return vfio_ap_mdev_verify_no_sharing(matrix_mdev, mdev_apm, mdev_aqm);
+}
+
 /**
  * vfio_ap_mdev_filter_matrix
  *
@@ -882,33 +784,21 @@ static ssize_t assign_adapter_store(struct device *dev,
 	if (apid > matrix_mdev->matrix.apm_max)
 		return -ENODEV;
 
-	/*
-	 * Set the bit in the AP mask (APM) corresponding to the AP adapter
-	 * number (APID). The bits in the mask, from most significant to least
-	 * significant bit, correspond to APIDs 0-255.
-	 */
-	mutex_lock(&matrix_dev->lock);
-
-	ret = vfio_ap_mdev_verify_queues_reserved_for_apid(matrix_mdev, apid);
-	if (ret)
-		goto done;
-
 	memset(apm, 0, sizeof(apm));
 	set_bit_inv(apid, apm);
 
-	ret = vfio_ap_mdev_verify_no_sharing(matrix_mdev, apm,
-					     matrix_mdev->matrix.aqm);
-	if (ret)
-		goto done;
-
+	mutex_lock(&matrix_dev->lock);
+	ret = vfio_ap_mdev_validate_masks(matrix_mdev, apm,
+					  matrix_mdev->matrix.aqm);
+	if (ret) {
+		mutex_unlock(&matrix_dev->lock);
+		return ret;
+	}
 	set_bit_inv(apid, matrix_mdev->matrix.apm);
 	vfio_ap_mdev_link_queues(matrix_mdev, LINK_APID, apid);
-	ret = count;
-
-done:
 	mutex_unlock(&matrix_dev->lock);
 
-	return ret;
+	return count;
 }
 static DEVICE_ATTR_WO(assign_adapter);
 
@@ -958,26 +848,6 @@ static ssize_t unassign_adapter_store(struct device *dev,
 }
 static 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;
-}
-
 /**
  * assign_domain_store
  *
@@ -1031,28 +901,21 @@ static ssize_t assign_domain_store(struct device *dev,
 	if (apqi > max_apqi)
 		return -ENODEV;
 
-	mutex_lock(&matrix_dev->lock);
-
-	ret = vfio_ap_mdev_verify_queues_reserved_for_apqi(matrix_mdev, apqi);
-	if (ret)
-		goto done;
-
 	memset(aqm, 0, sizeof(aqm));
 	set_bit_inv(apqi, aqm);
 
-	ret = vfio_ap_mdev_verify_no_sharing(matrix_mdev,
-					     matrix_mdev->matrix.apm, aqm);
-	if (ret)
-		goto done;
-
+	mutex_lock(&matrix_dev->lock);
+	ret = vfio_ap_mdev_validate_masks(matrix_mdev, matrix_mdev->matrix.apm,
+					  aqm);
+	if (ret) {
+		mutex_unlock(&matrix_dev->lock);
+		return ret;
+	}
 	set_bit_inv(apqi, matrix_mdev->matrix.aqm);
 	vfio_ap_mdev_link_queues(matrix_mdev, LINK_APQI, apqi);
-	ret = count;
-
-done:
 	mutex_unlock(&matrix_dev->lock);
 
-	return ret;
+	return count;
 }
 static DEVICE_ATTR_WO(assign_domain);
 
@@ -1139,11 +1002,6 @@ static ssize_t assign_control_domain_store(struct device *dev,
 	if (id > matrix_mdev->matrix.adm_max)
 		return -ENODEV;
 
-	/* Set the bit in the ADM (bitmask) corresponding to the AP control
-	 * domain number (id). The bits in the mask, from most significant to
-	 * least significant, correspond to IDs 0 up to the one less than the
-	 * number of control domains that can be assigned.
-	 */
 	mutex_lock(&matrix_dev->lock);
 	set_bit_inv(id, matrix_mdev->matrix.adm);
 	mutex_unlock(&matrix_dev->lock);
-- 
2.21.1


  parent reply	other threads:[~2020-08-21 19:58 UTC|newest]

Thread overview: 79+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-08-21 19:56 [PATCH v10 00/16] s390/vfio-ap: dynamic configuration support Tony Krowiak
2020-08-21 19:56 ` [PATCH v10 01/16] s390/vfio-ap: add version vfio_ap module Tony Krowiak
2020-08-25 10:04   ` Cornelia Huck
2020-08-26 14:49     ` Tony Krowiak
2020-08-27 10:32       ` Cornelia Huck
2020-08-27 14:39         ` Tony Krowiak
2020-08-28  8:10           ` Cornelia Huck
2020-08-21 19:56 ` [PATCH v10 02/16] s390/vfio-ap: use new AP bus interface to search for queue devices Tony Krowiak
2020-08-25 10:13   ` Cornelia Huck
2020-08-27 14:24     ` Tony Krowiak
2020-08-28  8:13       ` Cornelia Huck
2020-08-28 15:10         ` Tony Krowiak
2020-09-25  2:11       ` Halil Pasic
2020-10-16 20:59         ` Tony Krowiak
2020-09-04  8:11   ` Christian Borntraeger
2020-09-08 18:54     ` Tony Krowiak
2020-09-25  2:27   ` Halil Pasic
2020-09-29 13:07     ` Tony Krowiak
2020-09-29 13:37       ` Halil Pasic
2020-09-29 20:57         ` Tony Krowiak
2020-08-21 19:56 ` [PATCH v10 03/16] s390/vfio-ap: manage link between queue struct and matrix mdev Tony Krowiak
2020-08-25 10:25   ` Cornelia Huck
2020-08-28 23:05     ` Tony Krowiak
2020-09-04  8:15   ` Christian Borntraeger
2020-09-08 19:03     ` Tony Krowiak
2020-09-25  7:58   ` Halil Pasic
2020-08-21 19:56 ` [PATCH v10 04/16] s390/zcrypt: driver callback to indicate resource in use Tony Krowiak
2020-09-14 15:29   ` Cornelia Huck
2020-09-15 19:32     ` Tony Krowiak
2020-09-17 12:14       ` Cornelia Huck
2020-09-17 13:54         ` Tony Krowiak
2020-09-25  9:24   ` Halil Pasic
2020-09-29 13:59     ` Tony Krowiak
2020-08-21 19:56 ` [PATCH v10 05/16] s390/vfio-ap: implement in-use callback for vfio_ap driver Tony Krowiak
2020-09-14 15:31   ` Cornelia Huck
2020-09-25  9:29   ` Halil Pasic
2020-09-29 14:00     ` Tony Krowiak
2020-08-21 19:56 ` [PATCH v10 06/16] s390/vfio-ap: introduce shadow APCB Tony Krowiak
2020-09-17 14:22   ` Cornelia Huck
2020-09-18 17:03     ` Tony Krowiak
2020-09-26  1:38   ` Halil Pasic
2020-09-29 16:04     ` Tony Krowiak
2020-09-29 16:19       ` Halil Pasic
2020-08-21 19:56 ` [PATCH v10 07/16] s390/vfio-ap: sysfs attribute to display the guest's matrix Tony Krowiak
2020-09-17 14:34   ` Cornelia Huck
2020-09-18 17:09     ` Tony Krowiak
2020-09-26  7:16       ` Halil Pasic
2020-09-29 21:00         ` Tony Krowiak
2020-08-21 19:56 ` [PATCH v10 08/16] s390/vfio-ap: filter matrix for unavailable queue devices Tony Krowiak
2020-09-26  8:24   ` Halil Pasic
2020-09-29 21:59     ` Tony Krowiak
2020-08-21 19:56 ` Tony Krowiak [this message]
2020-09-26 23:49   ` [PATCH v10 09/16] s390/vfio-ap: allow assignment of unavailable AP queues to mdev device Halil Pasic
2020-09-30 12:59     ` Tony Krowiak
2020-09-30 22:29       ` Halil Pasic
2020-08-21 19:56 ` [PATCH v10 10/16] s390/vfio-ap: allow configuration of matrix mdev in use by a KVM guest Tony Krowiak
2020-09-27  0:03   ` Halil Pasic
2020-09-30 13:19     ` Tony Krowiak
2020-08-21 19:56 ` [PATCH v10 11/16] s390/vfio-ap: allow hot plug/unplug of AP resources using mdev device Tony Krowiak
2020-09-28  1:01   ` Halil Pasic
2020-10-05 16:24     ` Tony Krowiak
2020-10-05 18:30       ` Halil Pasic
2020-10-05 21:48         ` Tony Krowiak
2020-10-05 23:05         ` Tony Krowiak
2020-08-21 19:56 ` [PATCH v10 12/16] s390/zcrypt: Notify driver on config changed and scan complete callbacks Tony Krowiak
2020-09-27  1:39   ` Halil Pasic
2020-08-21 19:56 ` [PATCH v10 13/16] s390/vfio-ap: handle host AP config change notification Tony Krowiak
2020-09-28  1:38   ` Halil Pasic
2020-10-12 20:53     ` Tony Krowiak
2020-10-12 21:27     ` Tony Krowiak
2020-08-21 19:56 ` [PATCH v10 14/16] s390/vfio-ap: handle AP bus scan completed notification Tony Krowiak
2020-09-28  2:11   ` Halil Pasic
2020-08-21 19:56 ` [PATCH v10 15/16] s390/vfio-ap: handle probe/remove not due to host AP config changes Tony Krowiak
2020-09-28  2:45   ` Halil Pasic
2020-08-21 19:56 ` [PATCH v10 16/16] s390/vfio-ap: update docs to include dynamic config support Tony Krowiak
2020-08-25 10:45   ` Cornelia Huck
2020-08-31 18:34     ` Tony Krowiak
2020-09-28  2:48   ` Halil Pasic
2020-10-16 16:36     ` Tony Krowiak

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=20200821195616.13554-10-akrowiak@linux.ibm.com \
    --to=akrowiak@linux.ibm.com \
    --cc=alex.williamson@redhat.com \
    --cc=borntraeger@de.ibm.com \
    --cc=cohuck@redhat.com \
    --cc=david@redhat.com \
    --cc=fiuczy@linux.ibm.com \
    --cc=frankja@linux.ibm.com \
    --cc=freude@linux.ibm.com \
    --cc=gor@linux.ibm.com \
    --cc=hca@linux.ibm.com \
    --cc=imbrenda@linux.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.ibm.com \
    --cc=pasic@linux.ibm.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;
as well as URLs for NNTP newsgroup(s).