summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHarald Freudenberger <freude@linux.ibm.com>2018-10-19 10:36:28 +0200
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2018-10-22 08:37:46 +0200
commitf822ad2c2c03af85a531c5174136b6d5b1abc566 (patch)
tree7920d436f4b88071942e684051500d0218b3a052
parentcf3dbe5dacb3a95d497ace9c714306d17cb05b11 (diff)
s390/pkey: move pckmo subfunction available checks away from module init
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>
-rw-r--r--drivers/s390/crypto/pkey_api.c26
1 files changed, 20 insertions, 6 deletions
diff --git a/drivers/s390/crypto/pkey_api.c b/drivers/s390/crypto/pkey_api.c
index 86a8799475e9..2f92bbed4bf6 100644
--- a/drivers/s390/crypto/pkey_api.c
+++ b/drivers/s390/crypto/pkey_api.c
@@ -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))