s390/pkey: move pckmo subfunction available checks away from module init
authorHarald Freudenberger <freude@linux.ibm.com>
Fri, 19 Oct 2018 08:36:28 +0000 (10:36 +0200)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Mon, 22 Oct 2018 06:37:46 +0000 (08:37 +0200)
The init of the pkey module currently fails if the pckmo instruction
or the subfunctions are not available.  However, customers may
restrict their LPAR to switch off exactly these functions and work
with secure key only. So it is a valid case to have the pkey module
active and use it for secure key to protected key transfer only.

This patch moves the pckmo subfunction check from the pkey module init
function into the internal function where the pckmo instruction is
called. So now only on invocation of the pckmo instruction the check
for the required subfunction is done. If not available EOPNOTSUPP is
returned to the caller.

The check for having the pckmo instruction available is still done
during module init. This instruction came in with MSA 3 together with
the basic set of kmc instructions needed to work with protected keys.

Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Reviewed-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
drivers/s390/crypto/pkey_api.c

index 86a8799475e90ba2c29cd4e5a058c4c56e0fe607..2f92bbed4bf6891f199b34e0002bc12dc9a2e5ea 100644 (file)
@@ -35,6 +35,9 @@ MODULE_DESCRIPTION("s390 protected key interface");
 /* Size of vardata block used for some of the cca requests/replies */
 #define VARDATASIZE 4096
 
+/* mask of available pckmo subfunctions, fetched once at module init */
+static cpacf_mask_t pckmo_functions;
+
 /*
  * debug feature data and functions
  */
@@ -679,6 +682,16 @@ 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.
+        */
+       if (!cpacf_test_func(&pckmo_functions, fc)) {
+               DEBUG_ERR("%s pckmo functions not available\n", __func__);
+               return -EOPNOTSUPP;
+       }
+
        /* prepare param block */
        memset(paramblock, 0, sizeof(paramblock));
        memcpy(paramblock, clrkey->clrkey, keysize);
@@ -1672,15 +1685,16 @@ static struct miscdevice pkey_dev = {
  */
 static int __init pkey_init(void)
 {
-       cpacf_mask_t pckmo_functions, kmc_functions;
+       cpacf_mask_t kmc_functions;
 
-       /* check for pckmo instructions available */
+       /*
+        * The pckmo instruction should be available - even if we don't
+        * actually invoke it. This instruction comes with MSA 3 which
+        * is also the minimum level for the kmc instructions which
+        * are able to work with protected keys.
+        */
        if (!cpacf_query(CPACF_PCKMO, &pckmo_functions))
                return -EOPNOTSUPP;
-       if (!cpacf_test_func(&pckmo_functions, CPACF_PCKMO_ENC_AES_128_KEY) ||
-           !cpacf_test_func(&pckmo_functions, CPACF_PCKMO_ENC_AES_192_KEY) ||
-           !cpacf_test_func(&pckmo_functions, CPACF_PCKMO_ENC_AES_256_KEY))
-               return -EOPNOTSUPP;
 
        /* check for kmc instructions available */
        if (!cpacf_query(CPACF_KMC, &kmc_functions))