]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
s390/pkey: fix paes selftest failure with paes and pkey static build
authorHarald Freudenberger <freude@linux.ibm.com>
Tue, 15 Sep 2020 09:00:17 +0000 (11:00 +0200)
committerHeiko Carstens <hca@linux.ibm.com>
Tue, 3 Nov 2020 14:12:16 +0000 (15:12 +0100)
When both the paes and the pkey kernel module are statically build
into the kernel, the paes cipher selftests run before the pkey
kernel module is initialized. So a static variable set in the pkey
init function and used in the pkey_clr2protkey function is not
initialized when the paes cipher's selftests request to call pckmo for
transforming a clear key value into a protected key.

This patch moves the initial setup of the static variable into
the function pck_clr2protkey. So it's possible, to use the function
for transforming a clear to a protected key even before the pkey
init function has been called and the paes selftests may run
successful.

Reported-by: Alexander Egorenkov <Alexander.Egorenkov@ibm.com>
Cc: <stable@vger.kernel.org> # 4.20
Fixes: f822ad2c2c03 ("s390/pkey: move pckmo subfunction available checks away from module init")
Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
drivers/s390/crypto/pkey_api.c

index 99cb60ea663d95ee3eeef7550db014cac238362d..dd84995049b9173e4db609462345ecbf3824ee8b 100644 (file)
@@ -35,9 +35,6 @@ MODULE_DESCRIPTION("s390 protected key interface");
 #define PROTKEYBLOBBUFSIZE 256 /* protected key buffer size used internal */
 #define MAXAPQNSINLIST 64      /* max 64 apqns within a apqn list */
 
-/* mask of available pckmo subfunctions, fetched once at module init */
-static cpacf_mask_t pckmo_functions;
-
 /*
  * debug feature data and functions
  */
@@ -91,6 +88,9 @@ static int pkey_clr2protkey(u32 keytype,
                            const struct pkey_clrkey *clrkey,
                            struct pkey_protkey *protkey)
 {
+       /* mask of available pckmo subfunctions */
+       static cpacf_mask_t pckmo_functions;
+
        long fc;
        int keysize;
        u8 paramblock[64];
@@ -114,11 +114,13 @@ static int pkey_clr2protkey(u32 keytype,
                return -EINVAL;
        }
 
-       /*
-        * Check if the needed pckmo subfunction is available.
-        * These subfunctions can be enabled/disabled by customers
-        * in the LPAR profile or may even change on the fly.
-        */
+       /* Did we already check for PCKMO ? */
+       if (!pckmo_functions.bytes[0]) {
+               /* no, so check now */
+               if (!cpacf_query(CPACF_PCKMO, &pckmo_functions))
+                       return -ENODEV;
+       }
+       /* check for the pckmo subfunction we need now */
        if (!cpacf_test_func(&pckmo_functions, fc)) {
                DEBUG_ERR("%s pckmo functions not available\n", __func__);
                return -ENODEV;
@@ -2058,7 +2060,7 @@ static struct miscdevice pkey_dev = {
  */
 static int __init pkey_init(void)
 {
-       cpacf_mask_t kmc_functions;
+       cpacf_mask_t func_mask;
 
        /*
         * The pckmo instruction should be available - even if we don't
@@ -2066,15 +2068,15 @@ static int __init pkey_init(void)
         * is also the minimum level for the kmc instructions which
         * are able to work with protected keys.
         */
-       if (!cpacf_query(CPACF_PCKMO, &pckmo_functions))
+       if (!cpacf_query(CPACF_PCKMO, &func_mask))
                return -ENODEV;
 
        /* check for kmc instructions available */
-       if (!cpacf_query(CPACF_KMC, &kmc_functions))
+       if (!cpacf_query(CPACF_KMC, &func_mask))
                return -ENODEV;
-       if (!cpacf_test_func(&kmc_functions, CPACF_KMC_PAES_128) ||
-           !cpacf_test_func(&kmc_functions, CPACF_KMC_PAES_192) ||
-           !cpacf_test_func(&kmc_functions, CPACF_KMC_PAES_256))
+       if (!cpacf_test_func(&func_mask, CPACF_KMC_PAES_128) ||
+           !cpacf_test_func(&func_mask, CPACF_KMC_PAES_192) ||
+           !cpacf_test_func(&func_mask, CPACF_KMC_PAES_256))
                return -ENODEV;
 
        pkey_debug_init();