linux-kernel.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, pmorel@linux.ibm.com,
	pasic@linux.ibm.com, alex.williamson@redhat.com,
	kwankhede@nvidia.com, jjherne@linux.ibm.com,
	Tony Krowiak <akrowiak@linux.ibm.com>
Subject: [PATCH v6 06/10] s390: vfio-ap: update guest CRYCB in vfio_ap probe and remove callbacks
Date: Fri, 13 Sep 2019 17:26:54 -0400	[thread overview]
Message-ID: <1568410018-10833-7-git-send-email-akrowiak@linux.ibm.com> (raw)
In-Reply-To: <1568410018-10833-1-git-send-email-akrowiak@linux.ibm.com>

When the vfio_ap device driver's probe callback is invoked to bind a
an AP queue device, if its APQN has been assigned to a matrix mdev that is
in use by a guest, the queue will be hot plugged into the guest's AP
configuration if:

1. Each APQN derived from the APID and the APQIs already set in the
   guest's CRYCB references an AP queue device bound to the vfio_ap
   device driver.

2. Each APQN derived from the APQI and the APIDs already set in the
   guest's CRYCB references an AP queue device bound to the vfio_ap
   device driver.

When an AP adapter is removed from the AP configuration via the SE or an
'SCLP Deconfigure AP Adapter' instruction, each queue device associated
with the adapter will be unbound from device driver to which it is bound.
When the vfio_ap device driver's remove callback is invoked to unbind an
AP queue device, if the queue's APQN is assigned to a matrix mdev in use
by a guest, the adapter to which the queue is connected will be hot
unplugged from the guest's configuration. The reason for this is because
an adapter of a different type can be added back to the AP configuration
with the APID corresponding to the adapter being removed. If the new
adapter is not of the appropriate type, it will not get bound to the
vfio_ap driver. If we did not unplug it from the guest, both the guest
and the host would have access to all of the queues associated with the
adapter which is a no-no.

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

diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c
index 14f221b7426b..f3332424670f 100644
--- a/drivers/s390/crypto/vfio_ap_ops.c
+++ b/drivers/s390/crypto/vfio_ap_ops.c
@@ -507,6 +507,63 @@ static void vfio_ap_mdev_get_crycb_matrix(struct ap_matrix_mdev *matrix_mdev)
 	}
 }
 
+static bool vfio_ap_mdev_update_crycb_matrix(struct ap_matrix_mdev *matrix_mdev,
+					     struct vfio_ap_queue *q)
+{
+	unsigned long crycb_apid, crycb_apqi;
+	unsigned long apid = AP_QID_CARD(q->apqn);
+	unsigned long apqi = AP_QID_QUEUE(q->apqn);
+
+	/*
+	 * If the APID of the input queue is not already set in the guest's
+	 * CRYCB, then verify that all APQNs derived from Cartesian product of
+	 * the APID and each APQI set in the guest's CRYCB references a queue
+	 * that is bound to the vfio_ap driver.
+	 */
+	if (!test_bit_inv(apid, matrix_mdev->crycb.apm)) {
+		for_each_set_bit_inv(crycb_apqi, matrix_mdev->crycb.aqm,
+				     matrix_mdev->crycb.aqm_max + 1) {
+			/*
+			 * The APQN formulated from the APID and APQI of the
+			 * input queue is in the process of being bound to the
+			 * vfio_ap driver so there is no need to verify it.
+			 */
+			if (apqi == crycb_apqi)
+				continue;
+
+			if (!vfio_ap_find_queue(AP_MKQID(apid, crycb_apqi)))
+				return false;
+		}
+	}
+
+	/*
+	 * If the APQI of the input queue is not already set in the guest's
+	 * CRYCB, then verify that all APQNs derived from Cartesian product of
+	 * the APQI and each APID set in the guest's CRYCB references a queue
+	 * that is bound to the vfio_ap driver.
+	 */
+	if (!test_bit_inv(apqi, matrix_mdev->crycb.aqm)) {
+		for_each_set_bit_inv(crycb_apid, matrix_mdev->crycb.apm,
+				     matrix_mdev->crycb.apm_max + 1) {
+			/*
+			 * The APQN formulated from the APID and APQI of the
+			 * input queue is in the process of being bound to the
+			 * vfio_ap driver so there is no need to verify it.
+			 */
+			if (apid == crycb_apid)
+				continue;
+
+			if (!vfio_ap_find_queue(AP_MKQID(crycb_apid, apqi)))
+				return false;
+		}
+	}
+
+	set_bit_inv(apid, matrix_mdev->crycb.apm);
+	set_bit_inv(apqi, matrix_mdev->crycb.aqm);
+
+	return true;
+}
+
 static bool vfio_ap_mdev_has_crycb(struct ap_matrix_mdev *matrix_mdev)
 {
 	return matrix_mdev->kvm && matrix_mdev->kvm->arch.crypto.crycbd;
@@ -1311,9 +1368,23 @@ void vfio_ap_mdev_unregister(void)
 	mdev_unregister_device(&matrix_dev->device);
 }
 
+static struct ap_matrix_mdev *vfio_ap_mdev_for_queue(int apqn)
+{
+	struct ap_matrix_mdev *matrix_mdev;
+
+	list_for_each_entry(matrix_mdev, &matrix_dev->mdev_list, node) {
+		if (test_bit_inv(AP_QID_CARD(apqn), matrix_mdev->matrix.apm) &&
+		    test_bit_inv(AP_QID_QUEUE(apqn), matrix_mdev->matrix.aqm))
+			return matrix_mdev;
+	}
+
+	return NULL;
+}
+
 int vfio_ap_mdev_probe_queue(struct ap_queue *queue)
 {
 	struct vfio_ap_queue *q;
+	struct ap_matrix_mdev *matrix_mdev;
 
 	q = kzalloc(sizeof(*q), GFP_KERNEL);
 	if (!q)
@@ -1322,18 +1393,40 @@ int vfio_ap_mdev_probe_queue(struct ap_queue *queue)
 	q->apqn = queue->qid;
 	q->saved_isc = VFIO_AP_ISC_INVALID;
 
+	/*
+	 * If the APQN for the queue is assigned to a matrix mdev that is in
+	 * use by a guest, then plug the queue into the guest.
+	 */
+	matrix_mdev = vfio_ap_mdev_for_queue(queue->qid);
+	if (matrix_mdev && vfio_ap_mdev_has_crycb(matrix_mdev)) {
+		vfio_ap_mdev_update_crycb_matrix(matrix_mdev, q);
+		vfio_ap_mdev_update_crycb(matrix_mdev);
+	}
+
 	return 0;
 }
 
 void vfio_ap_mdev_remove_queue(struct ap_queue *queue)
 {
 	struct vfio_ap_queue *q;
+	struct ap_matrix_mdev *matrix_mdev;
 	int apid, apqi;
 
 	q = dev_get_drvdata(&queue->ap_dev.device);
 	dev_set_drvdata(&queue->ap_dev.device, NULL);
 	apid = AP_QID_CARD(q->apqn);
 	apqi = AP_QID_QUEUE(q->apqn);
+
+	/*
+	 * If the APQN for the queue is assigned to a matrix mdev that is in
+	 * use by a guest, then unplug the adapter from the guest.
+	 */
+	matrix_mdev = vfio_ap_mdev_for_queue(queue->qid);
+	if (matrix_mdev && vfio_ap_mdev_has_crycb(matrix_mdev)) {
+		clear_bit_inv(apid, matrix_mdev->crycb.apm);
+		vfio_ap_mdev_update_crycb(matrix_mdev);
+	}
+
 	vfio_ap_mdev_reset_queue(apid, apqi);
 	vfio_ap_irq_disable(q);
 	kfree(q);
-- 
2.7.4


  parent reply	other threads:[~2019-09-13 21:27 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-09-13 21:26 [PATCH v6 00/10] s390: vfio-ap: dynamic configuration support Tony Krowiak
2019-09-13 21:26 ` [PATCH v6 01/10] s390: vfio-ap: Refactor vfio_ap driver probe and remove callbacks Tony Krowiak
2019-09-13 21:26 ` [PATCH v6 02/10] s390: vfio-ap: allow assignment of unavailable AP resources to mdev device Tony Krowiak
2019-09-13 21:26 ` [PATCH v6 03/10] s390: vfio-ap: allow hot plug/unplug of AP resources using " Tony Krowiak
2019-09-13 21:26 ` [PATCH v6 04/10] s390: vfio-ap: filter CRYCB bits for unavailable queue devices Tony Krowiak
2019-09-18 17:04   ` Halil Pasic
2019-09-18 21:22     ` Tony Krowiak
2019-09-19 10:34   ` Halil Pasic
2019-09-20 14:24     ` Tony Krowiak
2019-09-20 15:44       ` Tony Krowiak
2019-09-13 21:26 ` [PATCH v6 05/10] s390: vfio-ap: sysfs attribute to display the guest CRYCB Tony Krowiak
2019-09-13 21:26 ` Tony Krowiak [this message]
2019-09-13 21:26 ` [PATCH v6 07/10] s390: zcrypt: driver callback to indicate resource in use Tony Krowiak
2019-09-13 21:26 ` [PATCH v6 08/10] s390: vfio-ap: implement in-use callback for vfio_ap driver Tony Krowiak
2019-09-13 21:26 ` [PATCH v6 09/10] s390: vfio-ap: added versioning to vfio_ap module Tony Krowiak
2019-09-13 21:26 ` [PATCH v6 10/10] s390: vfio-ap: update documentation Tony Krowiak
2019-10-08 10:48 ` [PATCH v6 00/10] s390: vfio-ap: dynamic configuration support Halil Pasic
2019-10-08 12:57   ` Pierre Morel
2019-10-15 20:33     ` Tony Krowiak
2019-10-15 20:27   ` 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=1568410018-10833-7-git-send-email-akrowiak@linux.ibm.com \
    --to=akrowiak@linux.ibm.com \
    --cc=alex.williamson@redhat.com \
    --cc=borntraeger@de.ibm.com \
    --cc=cohuck@redhat.com \
    --cc=freude@linux.ibm.com \
    --cc=jjherne@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 \
    --cc=pmorel@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).