Browse Source

s390/crypto: simplify init / exit functions

The aes and the des module register multiple crypto algorithms
dependent on the availability of specific CPACF instructions.
To simplify the deregistration with crypto_unregister_alg add
an array with pointers to the successfully registered algorithms
and use it for the error handling in the init function and in
the module exit function.

Reviewed-by: Harald Freudenberger <freude@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Martin Schwidefsky 9 years ago
parent
commit
d863d5945f
2 changed files with 79 additions and 98 deletions
  1. 35 44
      arch/s390/crypto/aes_s390.c
  2. 44 54
      arch/s390/crypto/des_s390.c

+ 35 - 44
arch/s390/crypto/aes_s390.c

@@ -731,8 +731,6 @@ static struct crypto_alg xts_aes_alg = {
 	}
 };
 
-static int xts_aes_alg_reg;
-
 static int ctr_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
 			   unsigned int key_len)
 {
@@ -870,7 +868,26 @@ static struct crypto_alg ctr_aes_alg = {
 	}
 };
 
-static int ctr_aes_alg_reg;
+static struct crypto_alg *aes_s390_algs_ptr[5];
+static int aes_s390_algs_num;
+
+static int aes_s390_register_alg(struct crypto_alg *alg)
+{
+	int ret;
+
+	ret = crypto_register_alg(alg);
+	if (!ret)
+		aes_s390_algs_ptr[aes_s390_algs_num++] = alg;
+	return ret;
+}
+
+static void aes_s390_fini(void)
+{
+	while (aes_s390_algs_num--)
+		crypto_unregister_alg(aes_s390_algs_ptr[aes_s390_algs_num]);
+	if (ctrblk)
+		free_page((unsigned long) ctrblk);
+}
 
 static int __init aes_s390_init(void)
 {
@@ -891,24 +908,23 @@ static int __init aes_s390_init(void)
 		pr_info("AES hardware acceleration is only available for"
 			" 128-bit keys\n");
 
-	ret = crypto_register_alg(&aes_alg);
+	ret = aes_s390_register_alg(&aes_alg);
 	if (ret)
-		goto aes_err;
+		goto out_err;
 
-	ret = crypto_register_alg(&ecb_aes_alg);
+	ret = aes_s390_register_alg(&ecb_aes_alg);
 	if (ret)
-		goto ecb_aes_err;
+		goto out_err;
 
-	ret = crypto_register_alg(&cbc_aes_alg);
+	ret = aes_s390_register_alg(&cbc_aes_alg);
 	if (ret)
-		goto cbc_aes_err;
+		goto out_err;
 
 	if (cpacf_query(CPACF_KM, CPACF_KM_XTS_128) &&
 	    cpacf_query(CPACF_KM, CPACF_KM_XTS_256)) {
-		ret = crypto_register_alg(&xts_aes_alg);
+		ret = aes_s390_register_alg(&xts_aes_alg);
 		if (ret)
-			goto xts_aes_err;
-		xts_aes_alg_reg = 1;
+			goto out_err;
 	}
 
 	if (cpacf_query(CPACF_KMCTR, CPACF_KMCTR_AES_128) &&
@@ -917,42 +933,17 @@ static int __init aes_s390_init(void)
 		ctrblk = (u8 *) __get_free_page(GFP_KERNEL);
 		if (!ctrblk) {
 			ret = -ENOMEM;
-			goto ctr_aes_err;
+			goto out_err;
 		}
-		ret = crypto_register_alg(&ctr_aes_alg);
-		if (ret) {
-			free_page((unsigned long) ctrblk);
-			goto ctr_aes_err;
-		}
-		ctr_aes_alg_reg = 1;
+		ret = aes_s390_register_alg(&ctr_aes_alg);
+		if (ret)
+			goto out_err;
 	}
 
-out:
+	return 0;
+out_err:
+	aes_s390_fini();
 	return ret;
-
-ctr_aes_err:
-	crypto_unregister_alg(&xts_aes_alg);
-xts_aes_err:
-	crypto_unregister_alg(&cbc_aes_alg);
-cbc_aes_err:
-	crypto_unregister_alg(&ecb_aes_alg);
-ecb_aes_err:
-	crypto_unregister_alg(&aes_alg);
-aes_err:
-	goto out;
-}
-
-static void __exit aes_s390_fini(void)
-{
-	if (ctr_aes_alg_reg) {
-		crypto_unregister_alg(&ctr_aes_alg);
-		free_page((unsigned long) ctrblk);
-	}
-	if (xts_aes_alg_reg)
-		crypto_unregister_alg(&xts_aes_alg);
-	crypto_unregister_alg(&cbc_aes_alg);
-	crypto_unregister_alg(&ecb_aes_alg);
-	crypto_unregister_alg(&aes_alg);
 }
 
 module_cpu_feature_match(MSA, aes_s390_init);

+ 44 - 54
arch/s390/crypto/des_s390.c

@@ -529,6 +529,27 @@ static struct crypto_alg ctr_des3_alg = {
 	}
 };
 
+static struct crypto_alg *des_s390_algs_ptr[8];
+static int des_s390_algs_num;
+
+static int des_s390_register_alg(struct crypto_alg *alg)
+{
+	int ret;
+
+	ret = crypto_register_alg(alg);
+	if (!ret)
+		des_s390_algs_ptr[des_s390_algs_num++] = alg;
+	return ret;
+}
+
+static void des_s390_exit(void)
+{
+	while (des_s390_algs_num--)
+		crypto_unregister_alg(des_s390_algs_ptr[des_s390_algs_num]);
+	if (ctrblk)
+		free_page((unsigned long) ctrblk);
+}
+
 static int __init des_s390_init(void)
 {
 	int ret;
@@ -537,75 +558,44 @@ static int __init des_s390_init(void)
 	    !cpacf_query(CPACF_KM, CPACF_KM_TDEA_192))
 		return -EOPNOTSUPP;
 
-	ret = crypto_register_alg(&des_alg);
+	ret = des_s390_register_alg(&des_alg);
 	if (ret)
-		goto des_err;
-	ret = crypto_register_alg(&ecb_des_alg);
+		goto out_err;
+	ret = des_s390_register_alg(&ecb_des_alg);
 	if (ret)
-		goto ecb_des_err;
-	ret = crypto_register_alg(&cbc_des_alg);
+		goto out_err;
+	ret = des_s390_register_alg(&cbc_des_alg);
 	if (ret)
-		goto cbc_des_err;
-	ret = crypto_register_alg(&des3_alg);
+		goto out_err;
+	ret = des_s390_register_alg(&des3_alg);
 	if (ret)
-		goto des3_err;
-	ret = crypto_register_alg(&ecb_des3_alg);
+		goto out_err;
+	ret = des_s390_register_alg(&ecb_des3_alg);
 	if (ret)
-		goto ecb_des3_err;
-	ret = crypto_register_alg(&cbc_des3_alg);
+		goto out_err;
+	ret = des_s390_register_alg(&cbc_des3_alg);
 	if (ret)
-		goto cbc_des3_err;
+		goto out_err;
 
 	if (cpacf_query(CPACF_KMCTR, CPACF_KMCTR_DEA) &&
 	    cpacf_query(CPACF_KMCTR, CPACF_KMCTR_TDEA_192)) {
-		ret = crypto_register_alg(&ctr_des_alg);
-		if (ret)
-			goto ctr_des_err;
-		ret = crypto_register_alg(&ctr_des3_alg);
-		if (ret)
-			goto ctr_des3_err;
 		ctrblk = (u8 *) __get_free_page(GFP_KERNEL);
 		if (!ctrblk) {
 			ret = -ENOMEM;
-			goto ctr_mem_err;
+			goto out_err;
 		}
+		ret = des_s390_register_alg(&ctr_des_alg);
+		if (ret)
+			goto out_err;
+		ret = des_s390_register_alg(&ctr_des3_alg);
+		if (ret)
+			goto out_err;
 	}
-out:
-	return ret;
-
-ctr_mem_err:
-	crypto_unregister_alg(&ctr_des3_alg);
-ctr_des3_err:
-	crypto_unregister_alg(&ctr_des_alg);
-ctr_des_err:
-	crypto_unregister_alg(&cbc_des3_alg);
-cbc_des3_err:
-	crypto_unregister_alg(&ecb_des3_alg);
-ecb_des3_err:
-	crypto_unregister_alg(&des3_alg);
-des3_err:
-	crypto_unregister_alg(&cbc_des_alg);
-cbc_des_err:
-	crypto_unregister_alg(&ecb_des_alg);
-ecb_des_err:
-	crypto_unregister_alg(&des_alg);
-des_err:
-	goto out;
-}
 
-static void __exit des_s390_exit(void)
-{
-	if (ctrblk) {
-		crypto_unregister_alg(&ctr_des_alg);
-		crypto_unregister_alg(&ctr_des3_alg);
-		free_page((unsigned long) ctrblk);
-	}
-	crypto_unregister_alg(&cbc_des3_alg);
-	crypto_unregister_alg(&ecb_des3_alg);
-	crypto_unregister_alg(&des3_alg);
-	crypto_unregister_alg(&cbc_des_alg);
-	crypto_unregister_alg(&ecb_des_alg);
-	crypto_unregister_alg(&des_alg);
+	return 0;
+out_err:
+	des_s390_exit();
+	return ret;
 }
 
 module_cpu_feature_match(MSA, des_s390_init);