s390/crypto: simplify init / exit functions
authorMartin Schwidefsky <schwidefsky@de.ibm.com>
Thu, 18 Aug 2016 10:34:34 +0000 (12:34 +0200)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Mon, 29 Aug 2016 09:05:08 +0000 (11:05 +0200)
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>
arch/s390/crypto/aes_s390.c
arch/s390/crypto/des_s390.c

index 4eb8de4174197e79585307b2170523a5474487be..be87575270ff446b2eb64df0081b5d590a2453db 100644 (file)
@@ -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);
index 99987859733165c48c94f87048799135061f7926..b77a546f1e763d0e544dbecdfeab3452e89e23b4 100644 (file)
@@ -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);