]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
s390/zcrypt: Rework ep11 findcard() implementation and callers
authorHarald Freudenberger <freude@linux.ibm.com>
Thu, 24 Apr 2025 13:36:08 +0000 (15:36 +0200)
committerHeiko Carstens <hca@linux.ibm.com>
Wed, 30 Apr 2025 09:34:02 +0000 (11:34 +0200)
Rework the memory usage of the ep11 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 <freude@linux.ibm.com>
Reviewed-by: Holger Dengler <dengler@linux.ibm.com>
Link: https://lore.kernel.org/r/20250424133619.16495-15-freude@linux.ibm.com
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
drivers/s390/crypto/pkey_ep11.c
drivers/s390/crypto/zcrypt_ep11misc.c
drivers/s390/crypto/zcrypt_ep11misc.h

index 5b033ca3e8285a5287965fdb34f79fb7a34c0a99..b970f0be84beca93ab3879e9c9a821d4116c2cea 100644 (file)
@@ -73,7 +73,7 @@ static int ep11_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)
@@ -98,7 +98,7 @@ static int ep11_apqns4key(const u8 *key, u32 keylen, u32 flags,
                        minhwtype = ZCRYPT_CEX7;
                        api = ap_is_se_guest() ? EP11_API_V6 : EP11_API_V4;
                }
-               rc = ep11_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
+               rc = ep11_findcard2(_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
                                    minhwtype, api, kb->wkvp);
                if (rc)
                        goto out;
@@ -115,7 +115,7 @@ static int ep11_apqns4key(const u8 *key, u32 keylen, u32 flags,
                        minhwtype = ZCRYPT_CEX7;
                        api = ap_is_se_guest() ? EP11_API_V6 : EP11_API_V4;
                }
-               rc = ep11_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
+               rc = ep11_findcard2(_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
                                    minhwtype, api, kb->wkvp);
                if (rc)
                        goto out;
@@ -135,7 +135,6 @@ static int ep11_apqns4key(const u8 *key, u32 keylen, u32 flags,
        *nr_apqns = _nr_apqns;
 
 out:
-       kfree(_apqns);
        pr_debug("rc=%d\n", rc);
        return rc;
 }
@@ -144,7 +143,7 @@ static int ep11_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();
@@ -158,7 +157,7 @@ static int ep11_apqns4type(enum pkey_key_type ktype,
                if (flags & PKEY_FLAGS_MATCH_CUR_MKVP)
                        wkvp = cur_mkvp;
                api = ap_is_se_guest() ? EP11_API_V6 : EP11_API_V4;
-               rc = ep11_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
+               rc = ep11_findcard2(_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
                                    ZCRYPT_CEX7, api, wkvp);
                if (rc)
                        goto out;
@@ -178,7 +177,6 @@ static int ep11_apqns4type(enum pkey_key_type ktype,
        *nr_apqns = _nr_apqns;
 
 out:
-       kfree(_apqns);
        pr_debug("rc=%d\n", rc);
        return rc;
 }
@@ -423,7 +421,7 @@ static int ep11_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))
@@ -443,7 +441,7 @@ static int ep11_verifykey(const u8 *key, u32 keylen,
                *keybitsize = kb->head.bitlen;
 
                api = ap_is_se_guest() ? EP11_API_V6 : EP11_API_V4;
-               rc = ep11_findcard2(&apqns, &nr_apqns, *card, *dom,
+               rc = ep11_findcard2(apqns, &nr_apqns, *card, *dom,
                                    ZCRYPT_CEX7, api,
                                    ep11_kb_wkvp(key, keylen));
                if (rc)
@@ -467,7 +465,7 @@ static int ep11_verifykey(const u8 *key, u32 keylen,
                *keybitsize = kh->bitlen;
 
                api = ap_is_se_guest() ? EP11_API_V6 : EP11_API_V4;
-               rc = ep11_findcard2(&apqns, &nr_apqns, *card, *dom,
+               rc = ep11_findcard2(apqns, &nr_apqns, *card, *dom,
                                    ZCRYPT_CEX7, api,
                                    ep11_kb_wkvp(key, keylen));
                if (rc)
@@ -484,7 +482,6 @@ static int ep11_verifykey(const u8 *key, u32 keylen,
        }
 
 out:
-       kfree(apqns);
        pr_debug("rc=%d\n", rc);
        return rc;
 }
index c368022624158ce7705b1a6a29935744d7de19c4..5bb72ca40105b85dbbbeb6cfbaa99ae1356685c1 100644 (file)
@@ -1522,14 +1522,14 @@ out:
 }
 EXPORT_SYMBOL(ep11_kblob2protkey);
 
-int ep11_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
+int ep11_findcard2(u32 *apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
                   int minhwtype, int minapi, const u8 *wkvp)
 {
        struct zcrypt_device_status_ext *device_status;
-       u32 *_apqns = NULL, _nr_apqns = 0;
-       int i, card, dom, rc;
        struct ep11_domain_info edi;
        struct ep11_card_info eci;
+       u32 _nr_apqns = 0;
+       int i, card, dom;
 
        /* occupy the device status memory */
        mutex_lock(&dev_status_mem_mutex);
@@ -1541,13 +1541,6 @@ int ep11_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);
@@ -1584,25 +1577,15 @@ int ep11_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:
        mutex_unlock(&dev_status_mem_mutex);
 
-       return rc;
+       return _nr_apqns ? 0 : -ENODEV;
 }
 EXPORT_SYMBOL(ep11_findcard2);
 
index dc1e418a6db1d9709bd66cc857a376ba6fed7027..2abd77aa16cf4180dd4e63894521aa68b2412dc5 100644 (file)
@@ -136,14 +136,12 @@ int ep11_clr2keyblob(u16 cardnr, u16 domain, u32 keybitsize, u32 keygenflags,
  *   key for this domain. When a wkvp is given there will always be a re-fetch
  *   of the domain info for the potential apqn - so this triggers an request
  *   reply to each apqn eligible.
- * 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 ep11_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
+int ep11_findcard2(u32 *apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
                   int minhwtype, int minapi, const u8 *wkvp);
 
 /*