Blob Blame History Raw
From: Harald Freudenberger <freude@linux.ibm.com>
Date: Tue, 23 Nov 2021 16:02:47 +0100
Subject: s390/zcrypt: change reply buffer size offering
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Git-commit: 252a1ff777639ad13978a614f2cde1f0c43a7c2f
Patch-mainline: v5.18-rc1
References: LTC#203322 bsc#1213950

Instead of offering the user space given receive buffer size to
the crypto card firmware as limit for the reply message offer
the internal per queue reply buffer size. As the queue's reply
buffer is always adjusted to the max message size possible for
this card this may offer more buffer space. However, now it is
important to check the user space reply buffer on pushing back
the reply. If the reply does not fit into the user space provided
buffer the ioctl will fail with errno EMSGSIZE.

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: Miroslav Franc <mfranc@suse.cz>
---
 drivers/s390/crypto/zcrypt_msgtype6.c | 23 ++++++++++++++++++++++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/drivers/s390/crypto/zcrypt_msgtype6.c b/drivers/s390/crypto/zcrypt_msgtype6.c
index 98755b57104f..be3f46a014f4 100644
--- a/drivers/s390/crypto/zcrypt_msgtype6.c
+++ b/drivers/s390/crypto/zcrypt_msgtype6.c
@@ -1197,6 +1197,21 @@ static long zcrypt_msgtype6_send_cprb(bool userspace, struct zcrypt_queue *zq,
 {
 	int rc;
 	struct response_type *rtype = (struct response_type *)(ap_msg->private);
+	struct {
+		struct type6_hdr hdr;
+		struct CPRBX cprbx;
+		/* ... more data blocks ... */
+	} __packed * msg = ap_msg->message;
+
+	/*
+	 * Set the queue's reply buffer length minus 128 byte padding
+	 * as reply limit for the card firmware.
+	 */
+	msg->hdr.FromCardLen1 = min_t(unsigned int, msg->hdr.FromCardLen1,
+				      zq->reply.bufsize - 128);
+	if (msg->hdr.FromCardLen2)
+		msg->hdr.FromCardLen2 =
+			zq->reply.bufsize - msg->hdr.FromCardLen1 - 128;
 
 	init_completion(&rtype->work);
 	ap_queue_message(zq->queue, ap_msg);
@@ -1277,7 +1292,6 @@ static long zcrypt_msgtype6_send_ep11_cprb(bool userspace, struct zcrypt_queue *
 		unsigned int	dom_val;	/* domain id	   */
 	} __packed * payload_hdr = NULL;
 
-
 	/**
 	 * The target domain field within the cprb body/payload block will be
 	 * replaced by the usage domain for non-management commands only.
@@ -1309,6 +1323,13 @@ static long zcrypt_msgtype6_send_ep11_cprb(bool userspace, struct zcrypt_queue *
 					AP_QID_QUEUE(zq->queue->qid);
 	}
 
+	/*
+	 * Set the queue's reply buffer length minus the two prepend headers
+	 * as reply limit for the card firmware.
+	 */
+	msg->hdr.FromCardLen1 = zq->reply.bufsize -
+		sizeof(struct type86_hdr) - sizeof(struct type86_fmt2_ext);
+
 	init_completion(&rtype->work);
 	ap_queue_message(zq->queue, ap_msg);
 	rc = wait_for_completion_interruptible(&rtype->work);