Commit 0daf9878 authored by Tony Krowiak's avatar Tony Krowiak Committed by Heiko Carstens
Browse files

s390/vfio_ap: check TAPQ response code when waiting for queue reset



The vfio_ap_mdev_reset_queue() function does not check the status
response code returned form the PQAP(TAPQ) function when verifying the
queue's status; consequently, there is no way of knowing whether
verification failed because the wait time was exceeded, or because the
PQAP(TAPQ) failed.

This patch adds a function to check the status response code from the
PQAP(TAPQ) instruction and logs an appropriate message if it fails.

Signed-off-by: default avatarTony Krowiak <akrowiak@linux.ibm.com>
Reviewed-by: default avatarJason J. Herne <jjherne@linux.ibm.com>
Reviewed-by: default avatarHarald Freudenberger <freude@linux.ibm.com>
Link: https://lore.kernel.org/r/20230118203111.529766-3-akrowiak@linux.ibm.com


Signed-off-by: default avatarChristian Borntraeger <borntraeger@linux.ibm.com>
Signed-off-by: default avatarHeiko Carstens <hca@linux.ibm.com>
parent 62414d90
Loading
Loading
Loading
Loading
+31 −5
Original line number Diff line number Diff line
@@ -1598,23 +1598,49 @@ static struct vfio_ap_queue *vfio_ap_find_queue(int apqn)
	return q;
}

static int apq_status_check(int apqn, struct ap_queue_status *status)
{
	switch (status->response_code) {
	case AP_RESPONSE_NORMAL:
	case AP_RESPONSE_RESET_IN_PROGRESS:
		if (status->queue_empty && !status->irq_enabled)
			return 0;
		return -EBUSY;
	case AP_RESPONSE_DECONFIGURED:
		/*
		 * If the AP queue is deconfigured, any subsequent AP command
		 * targeting the queue will fail with the same response code. On the
		 * other hand, when an AP adapter is deconfigured, the associated
		 * queues are reset, so let's return a value indicating the reset
		 * for which we're waiting completed successfully.
		 */
		return 0;
	default:
		WARN(true,
		     "failed to verify reset of queue %02x.%04x: TAPQ rc=%u\n",
		     AP_QID_CARD(apqn), AP_QID_QUEUE(apqn),
		     status->response_code);
		return -EIO;
	}
}

static int apq_reset_check(struct vfio_ap_queue *q)
{
	int iters = 2;
	int iters = 2, ret;
	struct ap_queue_status status;

	while (iters--) {
		msleep(20);
		status = ap_tapq(q->apqn, NULL);
		if (status.queue_empty && !status.irq_enabled)
			return 0;
		ret = apq_status_check(q->apqn, &status);
		if (ret != -EBUSY)
			return ret;
	}
	WARN_ONCE(iters <= 0,
		  "timeout verifying reset of queue %02x.%04x (%u, %u, %u)",
		  AP_QID_CARD(q->apqn), AP_QID_QUEUE(q->apqn),
		  status.queue_empty, status.irq_enabled, status.response_code);

	return -EBUSY;
	return ret;
}

static int vfio_ap_mdev_reset_queue(struct vfio_ap_queue *q,