Commit 62aab082 authored by Tony Krowiak's avatar Tony Krowiak Committed by Heiko Carstens
Browse files

s390/vfio-ap: store entire AP queue status word with the queue object



Store the entire AP queue status word returned from the ZAPQ command with
the struct vfio_ap_queue object instead of just the response code field.
The other information contained in the status word is need by the
apq_reset_check function to display a proper message to indicate that the
vfio_ap driver is waiting for the ZAPQ to complete because the queue is
not empty or IRQs are still enabled.

Signed-off-by: default avatarTony Krowiak <akrowiak@linux.ibm.com>
Tested-by: default avatarViktor Mihajlovski <mihajlov@linux.ibm.com>
Link: https://lore.kernel.org/r/20230815184333.6554-7-akrowiak@linux.ibm.com


Signed-off-by: default avatarHeiko Carstens <hca@linux.ibm.com>
parent dd174833
Loading
Loading
Loading
Loading
+15 −12
Original line number Diff line number Diff line
@@ -674,7 +674,7 @@ static bool vfio_ap_mdev_filter_matrix(unsigned long *apm, unsigned long *aqm,
			 */
			apqn = AP_MKQID(apid, apqi);
			q = vfio_ap_mdev_get_queue(matrix_mdev, apqn);
			if (!q || q->reset_rc) {
			if (!q || q->reset_status.response_code) {
				clear_bit_inv(apid,
					      matrix_mdev->shadow_apcb.apm);
				break;
@@ -1628,6 +1628,7 @@ static int apq_reset_check(struct vfio_ap_queue *q)
	int ret = -EBUSY, elapsed = 0;
	struct ap_queue_status status;

	memcpy(&status, &q->reset_status, sizeof(status));
	while (true) {
		msleep(AP_RESET_INTERVAL);
		elapsed += AP_RESET_INTERVAL;
@@ -1643,20 +1644,20 @@ static int apq_reset_check(struct vfio_ap_queue *q)
					      status.queue_empty,
					      status.irq_enabled);
		} else {
			if (q->reset_rc == AP_RESPONSE_RESET_IN_PROGRESS ||
			    q->reset_rc == AP_RESPONSE_BUSY) {
			if (q->reset_status.response_code == AP_RESPONSE_RESET_IN_PROGRESS ||
			    q->reset_status.response_code == AP_RESPONSE_BUSY) {
				status = ap_zapq(q->apqn, 0);
				q->reset_rc = status.response_code;
				memcpy(&q->reset_status, &status, sizeof(status));
				continue;
			}
			/*
			 * When an AP adapter is deconfigured, the associated
			 * queues are reset, so let's set the status response
			 * code to 0 so the queue may be passed through (i.e.,
			 * not filtered).
			 * When an AP adapter is deconfigured, the
			 * associated queues are reset, so let's set the
			 * status response code to 0 so the queue may be
			 * passed through (i.e., not filtered)
			 */
			if (q->reset_rc == AP_RESPONSE_DECONFIGURED)
				q->reset_rc = 0;
			if (status.response_code == AP_RESPONSE_DECONFIGURED)
				q->reset_status.response_code = 0;
			if (q->saved_isc != VFIO_AP_ISC_INVALID)
				vfio_ap_free_aqic_resources(q);
			break;
@@ -1673,7 +1674,7 @@ static int vfio_ap_mdev_reset_queue(struct vfio_ap_queue *q)
	if (!q)
		return 0;
	status = ap_zapq(q->apqn, 0);
	q->reset_rc = status.response_code;
	memcpy(&q->reset_status, &status, sizeof(status));
	switch (status.response_code) {
	case AP_RESPONSE_NORMAL:
	case AP_RESPONSE_RESET_IN_PROGRESS:
@@ -1688,7 +1689,8 @@ static int vfio_ap_mdev_reset_queue(struct vfio_ap_queue *q)
		 * so the queue may be passed through (i.e., not filtered) and
		 * return a value indicating the reset completed successfully.
		 */
		q->reset_rc = 0;
		q->reset_status.response_code = 0;
		ret = 0;
		vfio_ap_free_aqic_resources(q);
		break;
	default:
@@ -2042,6 +2044,7 @@ int vfio_ap_mdev_probe_queue(struct ap_device *apdev)

	q->apqn = to_ap_queue(&apdev->device)->qid;
	q->saved_isc = VFIO_AP_ISC_INVALID;
	memset(&q->reset_status, 0, sizeof(q->reset_status));
	matrix_mdev = get_update_locks_by_apqn(q->apqn);

	if (matrix_mdev) {
+2 −2
Original line number Diff line number Diff line
@@ -133,7 +133,7 @@ struct ap_matrix_mdev {
 * @apqn: the APQN of the AP queue device
 * @saved_isc: the guest ISC registered with the GIB interface
 * @mdev_qnode: allows the vfio_ap_queue struct to be added to a hashtable
 * @reset_rc: the status response code from the last reset of the queue
 * @reset_status: the status from the last reset of the queue
 */
struct vfio_ap_queue {
	struct ap_matrix_mdev *matrix_mdev;
@@ -142,7 +142,7 @@ struct vfio_ap_queue {
#define VFIO_AP_ISC_INVALID 0xff
	unsigned char saved_isc;
	struct hlist_node mdev_qnode;
	unsigned int reset_rc;
	struct ap_queue_status reset_status;
};

int vfio_ap_mdev_register(void);