Blob Blame History Raw
From: Harald Freudenberger <freude@linux.ibm.com>
Date: Thu, 11 Nov 2021 14:31:46 +0100
Subject: s390/ap/zcrypt: debug feature improvements
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Git-commit: d64e5e9120a6afc8ebb9e9b46c1302f13b16b68d
Patch-mainline: v5.18-rc1
References: jsc#PED-596

This patch adds some debug feature improvements related
to some failures happened in the past. With CEX8 the max
request and response sizes have been extended but the
user space applications did not rework their code and
thus ran into receive buffer issues. This ffdc patch
here helps with additional checks and debug feature
messages in debugging and pointing to the root cause of
some failures related to wrong buffer sizes.

Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Reviewed-by: Jürgen Christ <jchrist@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Acked-by: Petr Tesarik <ptesarik@suse.com>
---
 drivers/s390/crypto/ap_queue.c         |    3 ++-
 drivers/s390/crypto/zcrypt_api.c       |   19 +++++++++++++++++++
 drivers/s390/crypto/zcrypt_msgtype50.c |    8 ++++++++
 drivers/s390/crypto/zcrypt_msgtype6.c  |   32 +++++++++++++++++++++++++++++---
 4 files changed, 58 insertions(+), 4 deletions(-)

--- a/drivers/s390/crypto/ap_queue.c
+++ b/drivers/s390/crypto/ap_queue.c
@@ -455,7 +455,7 @@ static ap_func_t *ap_jumptable[NR_AP_SM_
 
 enum ap_sm_wait ap_sm_event(struct ap_queue *aq, enum ap_sm_event event)
 {
-	if (aq->dev_state > AP_DEV_STATE_UNINITIATED)
+	if (aq->config && aq->dev_state > AP_DEV_STATE_UNINITIATED)
 		return ap_jumptable[aq->sm_state][event](aq);
 	else
 		return AP_SM_WAIT_NONE;
@@ -915,6 +915,7 @@ void ap_queue_init_state(struct ap_queue
 	spin_lock_bh(&aq->lock);
 	aq->dev_state = AP_DEV_STATE_OPERATING;
 	aq->sm_state = AP_SM_STATE_RESET_START;
+	aq->last_err_rc = 0;
 	ap_wait(ap_sm_event(aq, AP_SM_EVENT_POLL));
 	spin_unlock_bh(&aq->lock);
 }
--- a/drivers/s390/crypto/zcrypt_api.c
+++ b/drivers/s390/crypto/zcrypt_api.c
@@ -714,6 +714,8 @@ static long zcrypt_rsa_modexpo(struct ap
 	spin_unlock(&zcrypt_list_lock);
 
 	if (!pref_zq) {
+		ZCRYPT_DBF_DBG("%s no matching queue found => ENODEV\n",
+			       __func__);
 		rc = -ENODEV;
 		goto out;
 	}
@@ -822,6 +824,8 @@ static long zcrypt_rsa_crt(struct ap_per
 	spin_unlock(&zcrypt_list_lock);
 
 	if (!pref_zq) {
+		ZCRYPT_DBF_DBG("%s no matching queue found => ENODEV\n",
+			       __func__);
 		rc = -ENODEV;
 		goto out;
 	}
@@ -941,6 +945,8 @@ static long _zcrypt_send_cprb(bool users
 	spin_unlock(&zcrypt_list_lock);
 
 	if (!pref_zq) {
+		ZCRYPT_DBF_DBG("%s no match for address %02x.%04x => ENODEV\n",
+			       __func__, xcRB->user_defined, *domain);
 		rc = -ENODEV;
 		goto out;
 	}
@@ -1113,6 +1119,17 @@ static long _zcrypt_send_ep11_cprb(bool
 	spin_unlock(&zcrypt_list_lock);
 
 	if (!pref_zq) {
+		if (targets && target_num == 1) {
+			ZCRYPT_DBF_DBG("%s no match for address %02x.%04x => ENODEV\n",
+				       __func__, (int) targets->ap_id,
+				       (int) targets->dom_id);
+		} else if (targets) {
+			ZCRYPT_DBF_DBG("%s no match for %d target addrs => ENODEV\n",
+				       __func__, (int) target_num);
+		} else {
+			ZCRYPT_DBF_DBG("%s no match for address ff.ffff => ENODEV\n",
+				       __func__);
+		}
 		rc = -ENODEV;
 		goto out_free;
 	}
@@ -1189,6 +1206,8 @@ static long zcrypt_rng(char *buffer)
 	spin_unlock(&zcrypt_list_lock);
 
 	if (!pref_zq) {
+		ZCRYPT_DBF_DBG("%s no matching queue found => ENODEV\n",
+			__func__);
 		rc = -ENODEV;
 		goto out;
 	}
--- a/drivers/s390/crypto/zcrypt_msgtype50.c
+++ b/drivers/s390/crypto/zcrypt_msgtype50.c
@@ -497,6 +497,10 @@ static long zcrypt_cex2a_modexpo(struct
 		ap_cancel_message(zq->queue, ap_msg);
 out:
 	ap_msg->private = NULL;
+	if (rc)
+		ZCRYPT_DBF_DBG("%s send me cprb at dev=%02x.%04x rc=%d\n",
+			       __func__, AP_QID_CARD(zq->queue->qid),
+			       AP_QID_QUEUE(zq->queue->qid), rc);
 	return rc;
 }
 
@@ -542,6 +546,10 @@ static long zcrypt_cex2a_modexpo_crt(str
 		ap_cancel_message(zq->queue, ap_msg);
 out:
 	ap_msg->private = NULL;
+	if (rc)
+		ZCRYPT_DBF_DBG("%s send crt cprb at dev=%02x.%04x rc=%d\n",
+			       __func__, AP_QID_CARD(zq->queue->qid),
+			       AP_QID_QUEUE(zq->queue->qid), rc);
 	return rc;
 }
 
--- a/drivers/s390/crypto/zcrypt_msgtype6.c
+++ b/drivers/s390/crypto/zcrypt_msgtype6.c
@@ -714,17 +714,31 @@ static int convert_type86_xcrb(bool user
 	char *data = reply->msg;
 
 	/* Copy CPRB to user */
+	if (xcRB->reply_control_blk_length < msg->fmt2.count1) {
+		ZCRYPT_DBF_DBG("%s reply_control_blk_length %u < required %u => EMSGSIZE\n",
+			       __func__, xcRB->reply_control_blk_length,
+			       msg->fmt2.count1);
+		return -EMSGSIZE;
+	}
 	if (z_copy_to_user(userspace, xcRB->reply_control_blk_addr,
 			   data + msg->fmt2.offset1, msg->fmt2.count1))
 		return -EFAULT;
 	xcRB->reply_control_blk_length = msg->fmt2.count1;
 
 	/* Copy data buffer to user */
-	if (msg->fmt2.count2)
+	if (msg->fmt2.count2) {
+		if (xcRB->reply_data_length < msg->fmt2.count2) {
+			ZCRYPT_DBF_DBG("%s reply_data_length %u < required %u => EMSGSIZE\n",
+				       __func__, xcRB->reply_data_length,
+				       msg->fmt2.count2);
+			return -EMSGSIZE;
+		}
 		if (z_copy_to_user(userspace, xcRB->reply_data_addr,
 				   data + msg->fmt2.offset2, msg->fmt2.count2))
 			return -EFAULT;
+	}
 	xcRB->reply_data_length = msg->fmt2.count2;
+
 	return 0;
 }
 
@@ -744,8 +758,12 @@ static int convert_type86_ep11_xcrb(bool
 	struct type86_fmt2_msg *msg = reply->msg;
 	char *data = reply->msg;
 
-	if (xcRB->resp_len < msg->fmt2.count1)
-		return -EINVAL;
+	if (xcRB->resp_len < msg->fmt2.count1) {
+		ZCRYPT_DBF_DBG("%s resp_len %u < required %u => EMSGSIZE\n",
+			       __func__, (unsigned int)xcRB->resp_len,
+			       msg->fmt2.count1);
+		return -EMSGSIZE;
+	}
 
 	/* Copy response CPRB to user */
 	if (z_copy_to_user(userspace, (char __force __user *)xcRB->resp,
@@ -1167,6 +1185,10 @@ static long zcrypt_msgtype6_send_cprb(bo
 		/* Signal pending. */
 		ap_cancel_message(zq->queue, ap_msg);
 out:
+	if (rc)
+		ZCRYPT_DBF_DBG("%s send cprb at dev=%02x.%04x rc=%d\n",
+			       __func__, AP_QID_CARD(zq->queue->qid),
+			       AP_QID_QUEUE(zq->queue->qid), rc);
 	return rc;
 }
 
@@ -1272,6 +1294,10 @@ static long zcrypt_msgtype6_send_ep11_cp
 		/* Signal pending. */
 		ap_cancel_message(zq->queue, ap_msg);
 out:
+	if (rc)
+		ZCRYPT_DBF_DBG("%s send cprb at dev=%02x.%04x rc=%d\n",
+			       __func__, AP_QID_CARD(zq->queue->qid),
+			       AP_QID_QUEUE(zq->queue->qid), rc);
 	return rc;
 }