Blob Blame History Raw
From: Harald Freudenberger <freude@linux.ibm.com>
Subject: s390/zcrypt: remove VLA usage from the AP bus
Patch-mainline: v4.19-rc4
Git-commit: fa108f95c6769ec15ea59b7db00454b82afc6121
References: FATE#325689, LTC#167899, bsc#1113520

Summary:     zcrypt: AP bus support for alternate driver(s)
Description: AP bus support for alternate driver(s) and deterministic
             driver binding. For details please read the patch header
             for commit 7e0bdbe5c21cb8316a694e46ad5aad339f6894a6

Upstream-Description:

             s390/zcrypt: remove VLA usage from the AP bus

             The use of variable length arrays on the stack is deprecated.
             git commit 3d8f60d38e249f989a7fca9c2370c31c3d5487e1
             "s390/zcrypt: hex string mask improvements for apmask and aqmask."
             added three new VLA arrays. Remove them again.

             Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
             Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>

Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Acked-by: Petr Tesarik <ptesarik@suse.com>
---
 drivers/s390/crypto/ap_bus.c |   86 ++++++++++++++++---------------------------
 1 file changed, 33 insertions(+), 53 deletions(-)

--- a/drivers/s390/crypto/ap_bus.c
+++ b/drivers/s390/crypto/ap_bus.c
@@ -886,8 +886,6 @@ static int hex2bitmap(const char *str, u
 	if (bits & 0x07)
 		return -EINVAL;
 
-	memset(bitmap, 0, bits / 8);
-
 	if (str[0] == '0' && str[1] == 'x')
 		str++;
 	if (*str == 'x')
@@ -909,25 +907,23 @@ static int hex2bitmap(const char *str, u
 }
 
 /*
- * str2clrsetmasks() - parse bitmask argument and set the clear and
- * the set bitmap mask. A concatenation (done with ',') of these terms
- * is recognized:
+ * modify_bitmap() - parse bitmask argument and modify an existing
+ * bit mask accordingly. A concatenation (done with ',') of these
+ * terms is recognized:
  *   +<bitnr>[-<bitnr>] or -<bitnr>[-<bitnr>]
  * <bitnr> may be any valid number (hex, decimal or octal) in the range
  * 0...bits-1; the leading + or - is required. Here are some examples:
  *   +0-15,+32,-128,-0xFF
  *   -0-255,+1-16,+0x128
  *   +1,+2,+3,+4,-5,-7-10
- * Returns a clear and a set bitmask. Every positive value in the string
- * results in a bit set in the set mask and every negative value in the
- * string results in a bit SET in the clear mask. As a bit may be touched
- * more than once, the last 'operation' wins: +0-255,-128 = all but bit
- * 128 set in the set mask, only bit 128 set in the clear mask.
+ * Returns the new bitmap after all changes have been applied. Every
+ * positive value in the string will set a bit and every negative value
+ * in the string will clear a bit. As a bit may be touched more than once,
+ * the last 'operation' wins:
+ * +0-255,-128 = first bits 0-255 will be set, then bit 128 will be
+ * cleared again. All other bits are unmodified.
  */
-static int str2clrsetmasks(const char *str,
-			   unsigned long *clrmap,
-			   unsigned long *setmap,
-			   int bits)
+static int modify_bitmap(const char *str, unsigned long *bitmap, int bits)
 {
 	int a, i, z;
 	char *np, sign;
@@ -936,9 +932,6 @@ static int str2clrsetmasks(const char *s
 	if (bits & 0x07)
 		return -EINVAL;
 
-	memset(clrmap, 0, bits / 8);
-	memset(setmap, 0, bits / 8);
-
 	while (*str) {
 		sign = *str++;
 		if (sign != '+' && sign != '-')
@@ -954,13 +947,10 @@ static int str2clrsetmasks(const char *s
 			str = np;
 		}
 		for (i = a; i <= z; i++)
-			if (sign == '+') {
-				set_bit_inv(i, setmap);
-				clear_bit_inv(i, clrmap);
-			} else {
-				clear_bit_inv(i, setmap);
-				set_bit_inv(i, clrmap);
-			}
+			if (sign == '+')
+				set_bit_inv(i, bitmap);
+			else
+				clear_bit_inv(i, bitmap);
 		while (*str == ',' || *str == '\n')
 			str++;
 	}
@@ -984,44 +974,34 @@ static int process_mask_arg(const char *
 			    unsigned long *bitmap, int bits,
 			    struct mutex *lock)
 {
-	int i;
+	unsigned long *newmap, size;
+	int rc;
 
 	/* bits needs to be a multiple of 8 */
 	if (bits & 0x07)
 		return -EINVAL;
 
+	size = BITS_TO_LONGS(bits)*sizeof(unsigned long);
+	newmap = kmalloc(size, GFP_KERNEL);
+	if (!newmap)
+		return -ENOMEM;
+	if (mutex_lock_interruptible(lock)) {
+		kfree(newmap);
+		return -ERESTARTSYS;
+	}
+
 	if (*str == '+' || *str == '-') {
-		DECLARE_BITMAP(clrm, bits);
-		DECLARE_BITMAP(setm, bits);
-
-		i = str2clrsetmasks(str, clrm, setm, bits);
-		if (i)
-			return i;
-		if (mutex_lock_interruptible(lock))
-			return -ERESTARTSYS;
-		for (i = 0; i < bits; i++) {
-			if (test_bit_inv(i, clrm))
-				clear_bit_inv(i, bitmap);
-			if (test_bit_inv(i, setm))
-				set_bit_inv(i, bitmap);
-		}
+		memcpy(newmap, bitmap, size);
+		rc = modify_bitmap(str, newmap, bits);
 	} else {
-		DECLARE_BITMAP(setm, bits);
-
-		i = hex2bitmap(str, setm, bits);
-		if (i)
-			return i;
-		if (mutex_lock_interruptible(lock))
-			return -ERESTARTSYS;
-		for (i = 0; i < bits; i++)
-			if (test_bit_inv(i, setm))
-				set_bit_inv(i, bitmap);
-			else
-				clear_bit_inv(i, bitmap);
+		memset(newmap, 0, size);
+		rc = hex2bitmap(str, newmap, bits);
 	}
+	if (rc == 0)
+		memcpy(bitmap, newmap, size);
 	mutex_unlock(lock);
-
-	return 0;
+	kfree(newmap);
+	return rc;
 }
 
 /*