From: Harald Freudenberger Date: Thu, 24 Apr 2025 13:36:07 +0000 (+0200) Subject: s390/zcrypt: Rework cca findcard() implementation and callers X-Git-Tag: block-6.16-20250606~29^2~16^2~12 X-Git-Url: https://git.kernel.dk/?a=commitdiff_plain;h=95de56ae0db0fb039f3ae3ddfa1a281508fcef4f;p=linux-block.git s390/zcrypt: Rework cca findcard() implementation and callers Rework the memory usage of the cca findcard() implementation: - findcard does not allocate memory for the list of apqns any more. - the callers are now responsible to provide an array of apqns to store the matching apqns into. Signed-off-by: Harald Freudenberger Reviewed-by: Holger Dengler Link: https://lore.kernel.org/r/20250424133619.16495-14-freude@linux.ibm.com Signed-off-by: Heiko Carstens --- diff --git a/drivers/s390/crypto/pkey_cca.c b/drivers/s390/crypto/pkey_cca.c index 83b02a466346..50cbcb91565f 100644 --- a/drivers/s390/crypto/pkey_cca.c +++ b/drivers/s390/crypto/pkey_cca.c @@ -73,7 +73,7 @@ static int cca_apqns4key(const u8 *key, u32 keylen, u32 flags, struct pkey_apqn *apqns, size_t *nr_apqns) { struct keytoken_header *hdr = (struct keytoken_header *)key; - u32 _nr_apqns, *_apqns = NULL; + u32 _apqns[MAXAPQNSINLIST], _nr_apqns = ARRAY_SIZE(_apqns); int rc; if (!flags) @@ -107,7 +107,7 @@ static int cca_apqns4key(const u8 *key, u32 keylen, u32 flags, /* unknown CCA internal token type */ return -EINVAL; } - rc = cca_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF, + rc = cca_findcard2(_apqns, &_nr_apqns, 0xFFFF, 0xFFFF, minhwtype, AES_MK_SET, cur_mkvp, old_mkvp); if (rc) @@ -126,7 +126,7 @@ static int cca_apqns4key(const u8 *key, u32 keylen, u32 flags, /* unknown CCA internal 2 token type */ return -EINVAL; } - rc = cca_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF, + rc = cca_findcard2(_apqns, &_nr_apqns, 0xFFFF, 0xFFFF, ZCRYPT_CEX7, APKA_MK_SET, cur_mkvp, old_mkvp); if (rc) @@ -147,7 +147,6 @@ static int cca_apqns4key(const u8 *key, u32 keylen, u32 flags, *nr_apqns = _nr_apqns; out: - kfree(_apqns); pr_debug("rc=%d\n", rc); return rc; } @@ -156,7 +155,7 @@ static int cca_apqns4type(enum pkey_key_type ktype, u8 cur_mkvp[32], u8 alt_mkvp[32], u32 flags, struct pkey_apqn *apqns, size_t *nr_apqns) { - u32 _nr_apqns, *_apqns = NULL; + u32 _apqns[MAXAPQNSINLIST], _nr_apqns = ARRAY_SIZE(_apqns); int rc; zcrypt_wait_api_operational(); @@ -171,7 +170,7 @@ static int cca_apqns4type(enum pkey_key_type ktype, old_mkvp = *((u64 *)alt_mkvp); if (ktype == PKEY_TYPE_CCA_CIPHER) minhwtype = ZCRYPT_CEX6; - rc = cca_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF, + rc = cca_findcard2(_apqns, &_nr_apqns, 0xFFFF, 0xFFFF, minhwtype, AES_MK_SET, cur_mkvp, old_mkvp); if (rc) @@ -184,7 +183,7 @@ static int cca_apqns4type(enum pkey_key_type ktype, cur_mkvp = *((u64 *)cur_mkvp); if (flags & PKEY_FLAGS_MATCH_ALT_MKVP) old_mkvp = *((u64 *)alt_mkvp); - rc = cca_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF, + rc = cca_findcard2(_apqns, &_nr_apqns, 0xFFFF, 0xFFFF, ZCRYPT_CEX7, APKA_MK_SET, cur_mkvp, old_mkvp); if (rc) @@ -205,7 +204,6 @@ static int cca_apqns4type(enum pkey_key_type ktype, *nr_apqns = _nr_apqns; out: - kfree(_apqns); pr_debug("rc=%d\n", rc); return rc; } @@ -461,7 +459,7 @@ static int cca_verifykey(const u8 *key, u32 keylen, u32 *keytype, u32 *keybitsize, u32 *flags) { struct keytoken_header *hdr = (struct keytoken_header *)key; - u32 nr_apqns, *apqns = NULL; + u32 apqns[MAXAPQNSINLIST], nr_apqns = ARRAY_SIZE(apqns); int rc; if (keylen < sizeof(*hdr)) @@ -478,13 +476,14 @@ static int cca_verifykey(const u8 *key, u32 keylen, goto out; *keytype = PKEY_TYPE_CCA_DATA; *keybitsize = t->bitsize; - rc = cca_findcard2(&apqns, &nr_apqns, *card, *dom, + rc = cca_findcard2(apqns, &nr_apqns, *card, *dom, ZCRYPT_CEX3C, AES_MK_SET, t->mkvp, 0); if (!rc) *flags = PKEY_FLAGS_MATCH_CUR_MKVP; if (rc == -ENODEV) { - rc = cca_findcard2(&apqns, &nr_apqns, *card, *dom, + nr_apqns = ARRAY_SIZE(apqns); + rc = cca_findcard2(apqns, &nr_apqns, *card, *dom, ZCRYPT_CEX3C, AES_MK_SET, 0, t->mkvp); if (!rc) @@ -511,13 +510,14 @@ static int cca_verifykey(const u8 *key, u32 keylen, *keybitsize = PKEY_SIZE_AES_192; else if (!t->plfver && t->wpllen == 640) *keybitsize = PKEY_SIZE_AES_256; - rc = cca_findcard2(&apqns, &nr_apqns, *card, *dom, + rc = cca_findcard2(apqns, &nr_apqns, *card, *dom, ZCRYPT_CEX6, AES_MK_SET, t->mkvp0, 0); if (!rc) *flags = PKEY_FLAGS_MATCH_CUR_MKVP; if (rc == -ENODEV) { - rc = cca_findcard2(&apqns, &nr_apqns, *card, *dom, + nr_apqns = ARRAY_SIZE(apqns); + rc = cca_findcard2(apqns, &nr_apqns, *card, *dom, ZCRYPT_CEX6, AES_MK_SET, 0, t->mkvp0); if (!rc) @@ -535,7 +535,6 @@ static int cca_verifykey(const u8 *key, u32 keylen, } out: - kfree(apqns); pr_debug("rc=%d\n", rc); return rc; } diff --git a/drivers/s390/crypto/zcrypt_ccamisc.c b/drivers/s390/crypto/zcrypt_ccamisc.c index 1f4e14905ee5..b2ad377e1877 100644 --- a/drivers/s390/crypto/zcrypt_ccamisc.c +++ b/drivers/s390/crypto/zcrypt_ccamisc.c @@ -1698,13 +1698,13 @@ out: } EXPORT_SYMBOL(cca_get_info); -int cca_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain, +int cca_findcard2(u32 *apqns, u32 *nr_apqns, u16 cardnr, u16 domain, int minhwtype, int mktype, u64 cur_mkvp, u64 old_mkvp) { struct zcrypt_device_status_ext *device_status; - u32 *_apqns = NULL, _nr_apqns = 0; - int i, card, dom, curmatch, oldmatch, rc; + int i, card, dom, curmatch, oldmatch; struct cca_info ci; + u32 _nr_apqns = 0; /* occupy the device status memory */ mutex_lock(&dev_status_mem_mutex); @@ -1716,13 +1716,6 @@ int cca_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain, ZCRYPT_DEV_STATUS_CARD_MAX, ZCRYPT_DEV_STATUS_QUEUE_MAX); - /* allocate 1k space for up to 256 apqns */ - _apqns = kmalloc_array(256, sizeof(u32), GFP_KERNEL); - if (!_apqns) { - rc = -ENOMEM; - goto out; - } - /* walk through all the crypto apqnss */ for (i = 0; i < ZCRYPT_DEV_STATUS_ENTRIES; i++) { card = AP_QID_CARD(device_status[i].qid); @@ -1770,26 +1763,16 @@ int cca_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain, continue; } /* apqn passed all filtering criterons, add to the array */ - if (_nr_apqns < 256) - _apqns[_nr_apqns++] = (((u16)card) << 16) | ((u16)dom); + if (_nr_apqns < *nr_apqns) + apqns[_nr_apqns++] = (((u16)card) << 16) | ((u16)dom); } - /* nothing found ? */ - if (!_nr_apqns) { - kfree(_apqns); - rc = -ENODEV; - } else { - /* no re-allocation, simple return the _apqns array */ - *apqns = _apqns; - *nr_apqns = _nr_apqns; - rc = 0; - } + *nr_apqns = _nr_apqns; -out: /* release the device status memory */ mutex_unlock(&dev_status_mem_mutex); - return rc; + return _nr_apqns ? 0 : -ENODEV; } EXPORT_SYMBOL(cca_findcard2); diff --git a/drivers/s390/crypto/zcrypt_ccamisc.h b/drivers/s390/crypto/zcrypt_ccamisc.h index cc7d362a2bad..ca41a675dd3b 100644 --- a/drivers/s390/crypto/zcrypt_ccamisc.h +++ b/drivers/s390/crypto/zcrypt_ccamisc.h @@ -217,14 +217,12 @@ int cca_query_crypto_facility(u16 cardnr, u16 domain, * - if old_mkvp != 0 only apqns where old_mkvp == mkvp * The mktype determines which set of master keys to use: * 0 = AES_MK_SET - AES MK set, 1 = APKA MK_SET - APKA MK set - * The array of apqn entries is allocated with kmalloc and returned in *apqns; - * the number of apqns stored into the list is returned in *nr_apqns. One apqn - * entry is simple a 32 bit value with 16 bit cardnr and 16 bit domain nr and - * may be casted to struct pkey_apqn. The return value is either 0 for success - * or a negative errno value. If no apqn meeting the criteria is found, - * -ENODEV is returned. + * The caller should set *nr_apqns to the nr of elements available in *apqns. + * On return *nr_apqns is then updated with the nr of apqns filled into *apqns. + * The return value is either 0 for success or a negative errno value. + * If no apqn meeting the criteria is found, -ENODEV is returned. */ -int cca_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain, +int cca_findcard2(u32 *apqns, u32 *nr_apqns, u16 cardnr, u16 domain, int minhwtype, int mktype, u64 cur_mkvp, u64 old_mkvp); #define AES_MK_SET 0