s390/zcrypt: Remove CCA and EP11 card and domain info caches
authorHarald Freudenberger <freude@linux.ibm.com>
Thu, 24 Apr 2025 13:36:06 +0000 (15:36 +0200)
committerHeiko Carstens <hca@linux.ibm.com>
Wed, 30 Apr 2025 09:34:01 +0000 (11:34 +0200)
Remove the caching of the CCA and EP11 card and domain info.
In nearly all places where the card or domain info is fetched
the verify param was enabled and thus the cache was bypassed.
The only real place where info from the cache was used was
in the sysfs pseudo files in cases where the card/queue was
switched to "offline". All other callers insisted on getting
fresh info and thus a communication to the card was enforced.

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-13-freude@linux.ibm.com
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
drivers/s390/crypto/pkey_cca.c
drivers/s390/crypto/zcrypt_ccamisc.c
drivers/s390/crypto/zcrypt_ccamisc.h
drivers/s390/crypto/zcrypt_cex4.c
drivers/s390/crypto/zcrypt_ep11misc.c
drivers/s390/crypto/zcrypt_ep11misc.h

index cda22db31f6c11bc67db0058582c11813d44678e..83b02a466346711ecc74fb18630652d658703c0a 100644 (file)
@@ -109,7 +109,7 @@ static int cca_apqns4key(const u8 *key, u32 keylen, u32 flags,
                }
                rc = cca_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
                                   minhwtype, AES_MK_SET,
-                                  cur_mkvp, old_mkvp, 1);
+                                  cur_mkvp, old_mkvp);
                if (rc)
                        goto out;
 
@@ -128,7 +128,7 @@ static int cca_apqns4key(const u8 *key, u32 keylen, u32 flags,
                }
                rc = cca_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
                                   ZCRYPT_CEX7, APKA_MK_SET,
-                                  cur_mkvp, old_mkvp, 1);
+                                  cur_mkvp, old_mkvp);
                if (rc)
                        goto out;
 
@@ -173,7 +173,7 @@ static int cca_apqns4type(enum pkey_key_type ktype,
                        minhwtype = ZCRYPT_CEX6;
                rc = cca_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
                                   minhwtype, AES_MK_SET,
-                                  cur_mkvp, old_mkvp, 1);
+                                  cur_mkvp, old_mkvp);
                if (rc)
                        goto out;
 
@@ -186,7 +186,7 @@ static int cca_apqns4type(enum pkey_key_type ktype,
                        old_mkvp = *((u64 *)alt_mkvp);
                rc = cca_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
                                   ZCRYPT_CEX7, APKA_MK_SET,
-                                  cur_mkvp, old_mkvp, 1);
+                                  cur_mkvp, old_mkvp);
                if (rc)
                        goto out;
 
@@ -480,13 +480,13 @@ static int cca_verifykey(const u8 *key, u32 keylen,
                *keybitsize = t->bitsize;
                rc = cca_findcard2(&apqns, &nr_apqns, *card, *dom,
                                   ZCRYPT_CEX3C, AES_MK_SET,
-                                  t->mkvp, 0, 1);
+                                  t->mkvp, 0);
                if (!rc)
                        *flags = PKEY_FLAGS_MATCH_CUR_MKVP;
                if (rc == -ENODEV) {
                        rc = cca_findcard2(&apqns, &nr_apqns, *card, *dom,
                                           ZCRYPT_CEX3C, AES_MK_SET,
-                                          0, t->mkvp, 1);
+                                          0, t->mkvp);
                        if (!rc)
                                *flags = PKEY_FLAGS_MATCH_ALT_MKVP;
                }
@@ -513,13 +513,13 @@ static int cca_verifykey(const u8 *key, u32 keylen,
                        *keybitsize = PKEY_SIZE_AES_256;
                rc = cca_findcard2(&apqns, &nr_apqns, *card, *dom,
                                   ZCRYPT_CEX6, AES_MK_SET,
-                                  t->mkvp0, 0, 1);
+                                  t->mkvp0, 0);
                if (!rc)
                        *flags = PKEY_FLAGS_MATCH_CUR_MKVP;
                if (rc == -ENODEV) {
                        rc = cca_findcard2(&apqns, &nr_apqns, *card, *dom,
                                           ZCRYPT_CEX6, AES_MK_SET,
-                                          0, t->mkvp0, 1);
+                                          0, t->mkvp0);
                        if (!rc)
                                *flags = PKEY_FLAGS_MATCH_ALT_MKVP;
                }
index 2dc2aa32859e3810a943a77aa97068c2e8540a92..1f4e14905ee5b8c35c0331a9962f7c254654b882 100644 (file)
 /* Size of vardata block used for some of the cca requests/replies */
 #define VARDATASIZE 4096
 
-struct cca_info_list_entry {
-       struct list_head list;
-       u16 cardnr;
-       u16 domain;
-       struct cca_info info;
-};
-
-/* a list with cca_info_list_entry entries */
-static LIST_HEAD(cca_info_list);
-static DEFINE_SPINLOCK(cca_info_list_lock);
-
 /*
  * Cprb memory pool held for urgent cases where no memory
  * can be allocated via kmalloc. This pool is only used
@@ -1633,69 +1622,11 @@ out:
 }
 EXPORT_SYMBOL(cca_query_crypto_facility);
 
-static int cca_info_cache_fetch(u16 cardnr, u16 domain, struct cca_info *ci)
-{
-       int rc = -ENOENT;
-       struct cca_info_list_entry *ptr;
-
-       spin_lock_bh(&cca_info_list_lock);
-       list_for_each_entry(ptr, &cca_info_list, list) {
-               if (ptr->cardnr == cardnr && ptr->domain == domain) {
-                       memcpy(ci, &ptr->info, sizeof(*ci));
-                       rc = 0;
-                       break;
-               }
-       }
-       spin_unlock_bh(&cca_info_list_lock);
-
-       return rc;
-}
-
-static void cca_info_cache_update(u16 cardnr, u16 domain,
-                                 const struct cca_info *ci)
-{
-       int found = 0;
-       struct cca_info_list_entry *ptr;
-
-       spin_lock_bh(&cca_info_list_lock);
-       list_for_each_entry(ptr, &cca_info_list, list) {
-               if (ptr->cardnr == cardnr &&
-                   ptr->domain == domain) {
-                       memcpy(&ptr->info, ci, sizeof(*ci));
-                       found = 1;
-                       break;
-               }
-       }
-       if (!found) {
-               ptr = kmalloc(sizeof(*ptr), GFP_ATOMIC);
-               if (!ptr) {
-                       spin_unlock_bh(&cca_info_list_lock);
-                       return;
-               }
-               ptr->cardnr = cardnr;
-               ptr->domain = domain;
-               memcpy(&ptr->info, ci, sizeof(*ci));
-               list_add(&ptr->list, &cca_info_list);
-       }
-       spin_unlock_bh(&cca_info_list_lock);
-}
-
-static void __exit mkvp_cache_free(void)
-{
-       struct cca_info_list_entry *ptr, *pnext;
-
-       spin_lock_bh(&cca_info_list_lock);
-       list_for_each_entry_safe(ptr, pnext, &cca_info_list, list) {
-               list_del(&ptr->list);
-               kfree(ptr);
-       }
-       spin_unlock_bh(&cca_info_list_lock);
-}
-
 /*
- * Fetch cca_info values via query_crypto_facility from adapter.
+ * Fetch cca_info values about a CCA queue via
+ * query_crypto_facility from adapter.
  */
-static int fetch_cca_info(u16 cardnr, u16 domain, struct cca_info *ci)
+int cca_get_info(u16 cardnr, u16 domain, struct cca_info *ci)
 {
        int rc, found = 0;
        size_t rlen, vlen;
@@ -1765,28 +1696,10 @@ out:
        free_page((unsigned long)pg);
        return found == 2 ? 0 : -ENOENT;
 }
-
-/*
- * Fetch cca information about a CCA queue.
- */
-int cca_get_info(u16 card, u16 dom, struct cca_info *ci, int verify)
-{
-       int rc;
-
-       rc = cca_info_cache_fetch(card, dom, ci);
-       if (rc || verify) {
-               rc = fetch_cca_info(card, dom, ci);
-               if (rc == 0)
-                       cca_info_cache_update(card, dom, ci);
-       }
-
-       return rc;
-}
 EXPORT_SYMBOL(cca_get_info);
 
 int cca_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
-                 int minhwtype, int mktype, u64 cur_mkvp, u64 old_mkvp,
-                 int verify)
+                 int minhwtype, int mktype, u64 cur_mkvp, u64 old_mkvp)
 {
        struct zcrypt_device_status_ext *device_status;
        u32 *_apqns = NULL, _nr_apqns = 0;
@@ -1827,7 +1740,7 @@ int cca_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
                if (domain != 0xFFFF && dom != domain)
                        continue;
                /* get cca info on this apqn */
-               if (cca_get_info(card, dom, &ci, verify))
+               if (cca_get_info(card, dom, &ci))
                        continue;
                /* current master key needs to be valid */
                if (mktype == AES_MK_SET && ci.cur_aes_mk_state != '2')
@@ -1900,7 +1813,6 @@ int __init zcrypt_ccamisc_init(void)
 
 void zcrypt_ccamisc_exit(void)
 {
-       mkvp_cache_free();
        mutex_lock(&dev_status_mem_mutex);
        kvfree(dev_status_mem);
        mutex_unlock(&dev_status_mem_mutex);
index 0662fe39e425739fa2cee10dbd3bf5638dabd163..cc7d362a2bada9c74786f556c4e409360ab10d48 100644 (file)
@@ -215,9 +215,6 @@ int cca_query_crypto_facility(u16 cardnr, u16 domain,
  * - if minhwtype > 0 only apqns with hwtype >= minhwtype
  * - if cur_mkvp != 0 only apqns where cur_mkvp == mkvp
  * - if old_mkvp != 0 only apqns where old_mkvp == mkvp
- * - if verify is enabled and a cur_mkvp and/or old_mkvp
- *   value is given, then refetch the cca_info and make sure the current
- *   cur_mkvp or old_mkvp values of the apqn are used.
  * 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;
@@ -228,8 +225,7 @@ int cca_query_crypto_facility(u16 cardnr, u16 domain,
  * -ENODEV is returned.
  */
 int cca_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
-                 int minhwtype, int mktype, u64 cur_mkvp, u64 old_mkvp,
-                 int verify);
+                 int minhwtype, int mktype, u64 cur_mkvp, u64 old_mkvp);
 
 #define AES_MK_SET  0
 #define APKA_MK_SET 1
@@ -261,7 +257,7 @@ struct cca_info {
 /*
  * Fetch cca information about an CCA queue.
  */
-int cca_get_info(u16 card, u16 dom, struct cca_info *ci, int verify);
+int cca_get_info(u16 card, u16 dom, struct cca_info *ci);
 
 int zcrypt_ccamisc_init(void);
 void zcrypt_ccamisc_exit(void);
index 64df7d2f6266c46785279eb50ff1121692755d1c..ecf1fcc6315edcab5c69e13467d0eafb844ae9e6 100644 (file)
@@ -79,14 +79,13 @@ static ssize_t cca_serialnr_show(struct device *dev,
                                 struct device_attribute *attr,
                                 char *buf)
 {
-       struct zcrypt_card *zc = dev_get_drvdata(dev);
-       struct cca_info ci;
        struct ap_card *ac = to_ap_card(dev);
+       struct cca_info ci;
 
        memset(&ci, 0, sizeof(ci));
 
        if (ap_domain_index >= 0)
-               cca_get_info(ac->id, ap_domain_index, &ci, zc->online);
+               cca_get_info(ac->id, ap_domain_index, &ci);
 
        return sysfs_emit(buf, "%s\n", ci.serial);
 }
@@ -110,17 +109,17 @@ static ssize_t cca_mkvps_show(struct device *dev,
                              struct device_attribute *attr,
                              char *buf)
 {
+       static const char * const new_state[] = { "empty", "partial", "full" };
+       static const char * const cao_state[] = { "invalid", "valid" };
        struct zcrypt_queue *zq = dev_get_drvdata(dev);
-       int n = 0;
        struct cca_info ci;
-       static const char * const cao_state[] = { "invalid", "valid" };
-       static const char * const new_state[] = { "empty", "partial", "full" };
+       int n = 0;
 
        memset(&ci, 0, sizeof(ci));
 
        cca_get_info(AP_QID_CARD(zq->queue->qid),
                     AP_QID_QUEUE(zq->queue->qid),
-                    &ci, zq->online);
+                    &ci);
 
        if (ci.new_aes_mk_state >= '1' && ci.new_aes_mk_state <= '3')
                n += sysfs_emit_at(buf, n, "AES NEW: %s 0x%016llx\n",
@@ -210,13 +209,12 @@ static ssize_t ep11_api_ordinalnr_show(struct device *dev,
                                       struct device_attribute *attr,
                                       char *buf)
 {
-       struct zcrypt_card *zc = dev_get_drvdata(dev);
-       struct ep11_card_info ci;
        struct ap_card *ac = to_ap_card(dev);
+       struct ep11_card_info ci;
 
        memset(&ci, 0, sizeof(ci));
 
-       ep11_get_card_info(ac->id, &ci, zc->online);
+       ep11_get_card_info(ac->id, &ci);
 
        if (ci.API_ord_nr > 0)
                return sysfs_emit(buf, "%u\n", ci.API_ord_nr);
@@ -231,13 +229,12 @@ static ssize_t ep11_fw_version_show(struct device *dev,
                                    struct device_attribute *attr,
                                    char *buf)
 {
-       struct zcrypt_card *zc = dev_get_drvdata(dev);
-       struct ep11_card_info ci;
        struct ap_card *ac = to_ap_card(dev);
+       struct ep11_card_info ci;
 
        memset(&ci, 0, sizeof(ci));
 
-       ep11_get_card_info(ac->id, &ci, zc->online);
+       ep11_get_card_info(ac->id, &ci);
 
        if (ci.FW_version > 0)
                return sysfs_emit(buf, "%d.%d\n",
@@ -254,13 +251,12 @@ static ssize_t ep11_serialnr_show(struct device *dev,
                                  struct device_attribute *attr,
                                  char *buf)
 {
-       struct zcrypt_card *zc = dev_get_drvdata(dev);
-       struct ep11_card_info ci;
        struct ap_card *ac = to_ap_card(dev);
+       struct ep11_card_info ci;
 
        memset(&ci, 0, sizeof(ci));
 
-       ep11_get_card_info(ac->id, &ci, zc->online);
+       ep11_get_card_info(ac->id, &ci);
 
        if (ci.serial[0])
                return sysfs_emit(buf, "%16.16s\n", ci.serial);
@@ -291,14 +287,13 @@ static ssize_t ep11_card_op_modes_show(struct device *dev,
                                       struct device_attribute *attr,
                                       char *buf)
 {
-       struct zcrypt_card *zc = dev_get_drvdata(dev);
-       int i, n = 0;
-       struct ep11_card_info ci;
        struct ap_card *ac = to_ap_card(dev);
+       struct ep11_card_info ci;
+       int i, n = 0;
 
        memset(&ci, 0, sizeof(ci));
 
-       ep11_get_card_info(ac->id, &ci, zc->online);
+       ep11_get_card_info(ac->id, &ci);
 
        for (i = 0; ep11_op_modes[i].mode_txt; i++) {
                if (ci.op_mode & (1ULL << ep11_op_modes[i].mode_bit)) {
index df50b38dc7b9f94248f4b41f5ff7c381c9df6436..c368022624158ce7705b1a6a29935744d7de19c4 100644 (file)
@@ -55,86 +55,6 @@ static mempool_t *cprb_mempool;
 static void *dev_status_mem;
 static DEFINE_MUTEX(dev_status_mem_mutex);
 
-/* ep11 card info cache */
-struct card_list_entry {
-       struct list_head list;
-       u16 cardnr;
-       struct ep11_card_info info;
-};
-static LIST_HEAD(card_list);
-static DEFINE_SPINLOCK(card_list_lock);
-
-static int card_cache_fetch(u16 cardnr, struct ep11_card_info *ci)
-{
-       int rc = -ENOENT;
-       struct card_list_entry *ptr;
-
-       spin_lock_bh(&card_list_lock);
-       list_for_each_entry(ptr, &card_list, list) {
-               if (ptr->cardnr == cardnr) {
-                       memcpy(ci, &ptr->info, sizeof(*ci));
-                       rc = 0;
-                       break;
-               }
-       }
-       spin_unlock_bh(&card_list_lock);
-
-       return rc;
-}
-
-static void card_cache_update(u16 cardnr, const struct ep11_card_info *ci)
-{
-       int found = 0;
-       struct card_list_entry *ptr;
-
-       spin_lock_bh(&card_list_lock);
-       list_for_each_entry(ptr, &card_list, list) {
-               if (ptr->cardnr == cardnr) {
-                       memcpy(&ptr->info, ci, sizeof(*ci));
-                       found = 1;
-                       break;
-               }
-       }
-       if (!found) {
-               ptr = kmalloc(sizeof(*ptr), GFP_ATOMIC);
-               if (!ptr) {
-                       spin_unlock_bh(&card_list_lock);
-                       return;
-               }
-               ptr->cardnr = cardnr;
-               memcpy(&ptr->info, ci, sizeof(*ci));
-               list_add(&ptr->list, &card_list);
-       }
-       spin_unlock_bh(&card_list_lock);
-}
-
-static void card_cache_scrub(u16 cardnr)
-{
-       struct card_list_entry *ptr;
-
-       spin_lock_bh(&card_list_lock);
-       list_for_each_entry(ptr, &card_list, list) {
-               if (ptr->cardnr == cardnr) {
-                       list_del(&ptr->list);
-                       kfree(ptr);
-                       break;
-               }
-       }
-       spin_unlock_bh(&card_list_lock);
-}
-
-static void __exit card_cache_free(void)
-{
-       struct card_list_entry *ptr, *pnext;
-
-       spin_lock_bh(&card_list_lock);
-       list_for_each_entry_safe(ptr, pnext, &card_list, list) {
-               list_del(&ptr->list);
-               kfree(ptr);
-       }
-       spin_unlock_bh(&card_list_lock);
-}
-
 static int ep11_kb_split(const u8 *kb, size_t kblen, u32 kbver,
                         struct ep11kblob_header **kbhdr, size_t *kbhdrsize,
                         u8 **kbpl, size_t *kbplsize)
@@ -719,7 +639,7 @@ out:
 /*
  * Provide information about an EP11 card.
  */
-int ep11_get_card_info(u16 card, struct ep11_card_info *info, int verify)
+int ep11_get_card_info(u16 card, struct ep11_card_info *info)
 {
        int rc;
        struct ep11_module_query_info {
@@ -749,27 +669,20 @@ int ep11_get_card_info(u16 card, struct ep11_card_info *info, int verify)
                u32 max_CP_index;
        } __packed * pmqi = NULL;
 
-       rc = card_cache_fetch(card, info);
-       if (rc || verify) {
-               pmqi = kmalloc(sizeof(*pmqi), GFP_KERNEL);
-               if (!pmqi)
-                       return -ENOMEM;
-               rc = ep11_query_info(card, AUTOSEL_DOM,
-                                    0x01 /* module info query */,
-                                    sizeof(*pmqi), (u8 *)pmqi);
-               if (rc) {
-                       if (rc == -ENODEV)
-                               card_cache_scrub(card);
-                       goto out;
-               }
-               memset(info, 0, sizeof(*info));
-               info->API_ord_nr = pmqi->API_ord_nr;
-               info->FW_version =
-                       (pmqi->FW_major_vers << 8) + pmqi->FW_minor_vers;
-               memcpy(info->serial, pmqi->serial, sizeof(info->serial));
-               info->op_mode = pmqi->op_mode;
-               card_cache_update(card, info);
-       }
+       pmqi = kmalloc(sizeof(*pmqi), GFP_KERNEL);
+       if (!pmqi)
+               return -ENOMEM;
+       rc = ep11_query_info(card, AUTOSEL_DOM,
+                            0x01 /* module info query */,
+                            sizeof(*pmqi), (u8 *)pmqi);
+       if (rc)
+               goto out;
+
+       memset(info, 0, sizeof(*info));
+       info->API_ord_nr = pmqi->API_ord_nr;
+       info->FW_version = (pmqi->FW_major_vers << 8) + pmqi->FW_minor_vers;
+       memcpy(info->serial, pmqi->serial, sizeof(info->serial));
+       info->op_mode = pmqi->op_mode;
 
 out:
        kfree(pmqi);
@@ -1656,7 +1569,7 @@ int ep11_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
                        continue;
                /* check min api version if given */
                if (minapi > 0) {
-                       if (ep11_get_card_info(card, &eci, 0))
+                       if (ep11_get_card_info(card, &eci))
                                continue;
                        if (minapi > eci.API_ord_nr)
                                continue;
@@ -1713,7 +1626,6 @@ int __init zcrypt_ep11misc_init(void)
 
 void zcrypt_ep11misc_exit(void)
 {
-       card_cache_free();
        mutex_lock(&dev_status_mem_mutex);
        kvfree(dev_status_mem);
        mutex_unlock(&dev_status_mem_mutex);
index a4b98eca8431df0af2050556b22f3cd717115092..dc1e418a6db1d9709bd66cc857a376ba6fed7027 100644 (file)
@@ -104,7 +104,7 @@ struct ep11_domain_info {
 /*
  * Provide information about an EP11 card.
  */
-int ep11_get_card_info(u16 card, struct ep11_card_info *info, int verify);
+int ep11_get_card_info(u16 card, struct ep11_card_info *info);
 
 /*
  * Provide information about a domain within an EP11 card.