Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

s390/zcrypt: Introduce cprb mempool for ep11 misc functions

Introduce a cprb mempool for the zcrypt ep11 misc functions
(zcrypt_ep11misc.*) do some preparation rework to support
a do-not-allocate path through some zcrypt ep11 misc functions.

The mempool is controlled by the zcrypt module parameter
"mempool_threshold" which shall control the minimal amount
of memory items for CCA and EP11.

The mempool shall support "mempool_threshold" requests/replies
in parallel which means for EP11 to hold a send and receive
buffer memory per request. Each of this cprb space items is
limited to 8 KB. So by default the mempool consumes
5 * 2 * 8KB = 80KB

If the mempool is depleted upon one ep11 misc functions is
called with the ZCRYPT_XFLAG_NOMEMALLOC xflag set, the function
will fail with -ENOMEM and the caller is responsible for taking
further actions.

This is only part of an rework to support a new xflag
ZCRYPT_XFLAG_NOMEMALLOC but not yet complete.

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-8-freude@linux.ibm.com
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>

authored by

Harald Freudenberger and committed by
Heiko Carstens
366367a7 9bdb5f7e

+96 -62
+6
drivers/s390/crypto/zcrypt_api.c
··· 2166 2166 if (rc) 2167 2167 goto out_ccamisc_init_failed; 2168 2168 2169 + rc = zcrypt_ep11misc_init(); 2170 + if (rc) 2171 + goto out_ep11misc_init_failed; 2172 + 2169 2173 /* Register the request sprayer. */ 2170 2174 rc = misc_register(&zcrypt_misc_device); 2171 2175 if (rc < 0) ··· 2181 2177 return 0; 2182 2178 2183 2179 out_misc_register_failed: 2180 + zcrypt_ep11misc_exit(); 2181 + out_ep11misc_init_failed: 2184 2182 zcrypt_ccamisc_exit(); 2185 2183 out_ccamisc_init_failed: 2186 2184 zcdn_exit();
+89 -62
drivers/s390/crypto/zcrypt_ep11misc.c
··· 10 10 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 11 11 12 12 #include <linux/init.h> 13 + #include <linux/mempool.h> 13 14 #include <linux/module.h> 14 - #include <linux/slab.h> 15 15 #include <linux/random.h> 16 + #include <linux/slab.h> 16 17 #include <asm/zcrypt.h> 17 18 #include <asm/pkey.h> 18 19 #include <crypto/aes.h> ··· 30 29 /* default iv used here */ 31 30 static const u8 def_iv[16] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 32 31 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; 32 + 33 + /* 34 + * Cprb memory pool held for urgent cases where no memory 35 + * can be allocated via kmalloc. This pool is only used when 36 + * alloc_cprbmem() is called with the xflag ZCRYPT_XFLAG_NOMEMALLOC. 37 + */ 38 + #define CPRB_MEMPOOL_ITEM_SIZE (8 * 1024) 39 + static mempool_t *cprb_mempool; 33 40 34 41 /* ep11 card info cache */ 35 42 struct card_list_entry { ··· 420 411 /* 421 412 * Allocate and prepare ep11 cprb plus additional payload. 422 413 */ 423 - static inline struct ep11_cprb *alloc_cprb(size_t payload_len) 414 + static void *alloc_cprbmem(size_t payload_len, u32 xflags) 424 415 { 425 416 size_t len = sizeof(struct ep11_cprb) + payload_len; 426 - struct ep11_cprb *cprb; 417 + struct ep11_cprb *cprb = NULL; 427 418 428 - cprb = kzalloc(len, GFP_KERNEL); 419 + if (xflags & ZCRYPT_XFLAG_NOMEMALLOC) { 420 + if (len <= CPRB_MEMPOOL_ITEM_SIZE) 421 + cprb = mempool_alloc_preallocated(cprb_mempool); 422 + } else { 423 + cprb = kmalloc(len, GFP_KERNEL); 424 + } 429 425 if (!cprb) 430 426 return NULL; 427 + memset(cprb, 0, len); 431 428 432 429 cprb->cprb_len = sizeof(struct ep11_cprb); 433 430 cprb->cprb_ver_id = 0x04; ··· 442 427 cprb->payload_len = payload_len; 443 428 444 429 return cprb; 430 + } 431 + 432 + /* 433 + * Free ep11 cprb buffer space. 434 + */ 435 + static void free_cprbmem(void *mem, size_t payload_len, bool scrub, u32 xflags) 436 + { 437 + if (mem && scrub) 438 + memzero_explicit(mem, sizeof(struct ep11_cprb) + payload_len); 439 + 440 + if (xflags & ZCRYPT_XFLAG_NOMEMALLOC) 441 + mempool_free(mem, cprb_mempool); 442 + else 443 + kfree(mem); 445 444 } 446 445 447 446 /* ··· 518 489 struct ep11_cprb *req, size_t req_len, 519 490 struct ep11_cprb *rep, size_t rep_len) 520 491 { 492 + memset(u, 0, sizeof(*u)); 521 493 u->targets = (u8 __user *)t; 522 494 u->targets_num = nt; 523 495 u->req = (u8 __user *)req; ··· 635 605 } __packed * rep_pl; 636 606 struct ep11_cprb *req = NULL, *rep = NULL; 637 607 struct ep11_target_dev target; 638 - struct ep11_urb *urb = NULL; 608 + struct ep11_urb urb; 639 609 int api = EP11_API_V1, rc = -ENOMEM; 610 + const u32 xflags = 0; 640 611 641 612 /* request cprb and payload */ 642 - req = alloc_cprb(sizeof(struct ep11_info_req_pl)); 613 + req = alloc_cprbmem(sizeof(struct ep11_info_req_pl), xflags); 643 614 if (!req) 644 615 goto out; 645 616 req_pl = (struct ep11_info_req_pl *)(((u8 *)req) + sizeof(*req)); ··· 652 621 req_pl->query_subtype_len = sizeof(u32); 653 622 654 623 /* reply cprb and payload */ 655 - rep = alloc_cprb(sizeof(struct ep11_info_rep_pl) + buflen); 624 + rep = alloc_cprbmem(sizeof(struct ep11_info_rep_pl) + buflen, xflags); 656 625 if (!rep) 657 626 goto out; 658 627 rep_pl = (struct ep11_info_rep_pl *)(((u8 *)rep) + sizeof(*rep)); 659 628 660 629 /* urb and target */ 661 - urb = kmalloc(sizeof(*urb), GFP_KERNEL); 662 - if (!urb) 663 - goto out; 664 630 target.ap_id = cardnr; 665 631 target.dom_id = domain; 666 - prep_urb(urb, &target, 1, 632 + prep_urb(&urb, &target, 1, 667 633 req, sizeof(*req) + sizeof(*req_pl), 668 634 rep, sizeof(*rep) + sizeof(*rep_pl) + buflen); 669 635 670 - rc = zcrypt_send_ep11_cprb(urb, 0); 636 + rc = zcrypt_send_ep11_cprb(&urb, xflags); 671 637 if (rc) { 672 638 ZCRYPT_DBF_ERR("%s zcrypt_send_ep11_cprb(card=%d dom=%d) failed, rc=%d\n", 673 639 __func__, (int)cardnr, (int)domain, rc); ··· 695 667 memcpy(buf, ((u8 *)rep_pl) + sizeof(*rep_pl), rep_pl->data_len); 696 668 697 669 out: 698 - kfree(req); 699 - kfree(rep); 700 - kfree(urb); 670 + free_cprbmem(req, 0, false, xflags); 671 + free_cprbmem(rep, 0, false, xflags); 701 672 return rc; 702 673 } 703 674 ··· 850 823 struct ep11_cprb *req = NULL, *rep = NULL; 851 824 size_t req_pl_size, pinblob_size = 0; 852 825 struct ep11_target_dev target; 853 - struct ep11_urb *urb = NULL; 826 + struct ep11_urb urb; 854 827 int api, rc = -ENOMEM; 855 828 u8 *p; 829 + const u32 xflags = 0; 856 830 857 831 switch (keybitsize) { 858 832 case 128: ··· 879 851 pinblob_size = EP11_PINBLOB_V1_BYTES; 880 852 } 881 853 req_pl_size = sizeof(struct keygen_req_pl) + ASN1TAGLEN(pinblob_size); 882 - req = alloc_cprb(req_pl_size); 854 + req = alloc_cprbmem(req_pl_size, xflags); 883 855 if (!req) 884 856 goto out; 885 857 req_pl = (struct keygen_req_pl *)(((u8 *)req) + sizeof(*req)); ··· 905 877 *p++ = pinblob_size; 906 878 907 879 /* reply cprb and payload */ 908 - rep = alloc_cprb(sizeof(struct keygen_rep_pl)); 880 + rep = alloc_cprbmem(sizeof(struct keygen_rep_pl), xflags); 909 881 if (!rep) 910 882 goto out; 911 883 rep_pl = (struct keygen_rep_pl *)(((u8 *)rep) + sizeof(*rep)); 912 884 913 885 /* urb and target */ 914 - urb = kmalloc(sizeof(*urb), GFP_KERNEL); 915 - if (!urb) 916 - goto out; 917 886 target.ap_id = card; 918 887 target.dom_id = domain; 919 - prep_urb(urb, &target, 1, 888 + prep_urb(&urb, &target, 1, 920 889 req, sizeof(*req) + req_pl_size, 921 890 rep, sizeof(*rep) + sizeof(*rep_pl)); 922 891 923 - rc = zcrypt_send_ep11_cprb(urb, 0); 892 + rc = zcrypt_send_ep11_cprb(&urb, xflags); 924 893 if (rc) { 925 894 ZCRYPT_DBF_ERR("%s zcrypt_send_ep11_cprb(card=%d dom=%d) failed, rc=%d\n", 926 895 __func__, (int)card, (int)domain, rc); ··· 950 925 *keybufsize = rep_pl->data_len; 951 926 952 927 out: 953 - kfree(req); 954 - kfree(rep); 955 - kfree(urb); 928 + free_cprbmem(req, 0, false, xflags); 929 + free_cprbmem(rep, sizeof(struct keygen_rep_pl), true, xflags); 956 930 return rc; 957 931 } 958 932 ··· 1024 1000 } __packed * rep_pl; 1025 1001 struct ep11_cprb *req = NULL, *rep = NULL; 1026 1002 struct ep11_target_dev target; 1027 - struct ep11_urb *urb = NULL; 1028 - size_t req_pl_size, rep_pl_size; 1003 + struct ep11_urb urb; 1004 + size_t req_pl_size, rep_pl_size = 0; 1029 1005 int n, api = EP11_API_V1, rc = -ENOMEM; 1030 1006 u8 *p; 1007 + const u32 xflags = 0; 1031 1008 1032 1009 /* the simple asn1 coding used has length limits */ 1033 1010 if (keysize > 0xFFFF || inbufsize > 0xFFFF) ··· 1037 1012 /* request cprb and payload */ 1038 1013 req_pl_size = sizeof(struct crypt_req_pl) + (iv ? 16 : 0) 1039 1014 + ASN1TAGLEN(keysize) + ASN1TAGLEN(inbufsize); 1040 - req = alloc_cprb(req_pl_size); 1015 + req = alloc_cprbmem(req_pl_size, xflags); 1041 1016 if (!req) 1042 1017 goto out; 1043 1018 req_pl = (struct crypt_req_pl *)(((u8 *)req) + sizeof(*req)); ··· 1059 1034 1060 1035 /* reply cprb and payload, assume out data size <= in data size + 32 */ 1061 1036 rep_pl_size = sizeof(struct crypt_rep_pl) + ASN1TAGLEN(inbufsize + 32); 1062 - rep = alloc_cprb(rep_pl_size); 1037 + rep = alloc_cprbmem(rep_pl_size, xflags); 1063 1038 if (!rep) 1064 1039 goto out; 1065 1040 rep_pl = (struct crypt_rep_pl *)(((u8 *)rep) + sizeof(*rep)); 1066 1041 1067 1042 /* urb and target */ 1068 - urb = kmalloc(sizeof(*urb), GFP_KERNEL); 1069 - if (!urb) 1070 - goto out; 1071 1043 target.ap_id = card; 1072 1044 target.dom_id = domain; 1073 - prep_urb(urb, &target, 1, 1045 + prep_urb(&urb, &target, 1, 1074 1046 req, sizeof(*req) + req_pl_size, 1075 1047 rep, sizeof(*rep) + rep_pl_size); 1076 1048 1077 - rc = zcrypt_send_ep11_cprb(urb, 0); 1049 + rc = zcrypt_send_ep11_cprb(&urb, xflags); 1078 1050 if (rc) { 1079 1051 ZCRYPT_DBF_ERR("%s zcrypt_send_ep11_cprb(card=%d dom=%d) failed, rc=%d\n", 1080 1052 __func__, (int)card, (int)domain, rc); ··· 1117 1095 *outbufsize = n; 1118 1096 1119 1097 out: 1120 - kfree(req); 1121 - kfree(rep); 1122 - kfree(urb); 1098 + free_cprbmem(req, req_pl_size, true, xflags); 1099 + free_cprbmem(rep, rep_pl_size, true, xflags); 1123 1100 return rc; 1124 1101 } 1125 1102 ··· 1164 1143 struct ep11_cprb *req = NULL, *rep = NULL; 1165 1144 size_t req_pl_size, pinblob_size = 0; 1166 1145 struct ep11_target_dev target; 1167 - struct ep11_urb *urb = NULL; 1146 + struct ep11_urb urb; 1168 1147 int api, rc = -ENOMEM; 1169 1148 u8 *p; 1149 + const u32 xflags = 0; 1170 1150 1171 1151 /* request cprb and payload */ 1172 1152 api = (!keygenflags || keygenflags & 0x00200000) ? ··· 1183 1161 req_pl_size = sizeof(struct uw_req_pl) + (iv ? 16 : 0) 1184 1162 + ASN1TAGLEN(keksize) + ASN1TAGLEN(0) 1185 1163 + ASN1TAGLEN(pinblob_size) + ASN1TAGLEN(enckeysize); 1186 - req = alloc_cprb(req_pl_size); 1164 + req = alloc_cprbmem(req_pl_size, xflags); 1187 1165 if (!req) 1188 1166 goto out; 1189 1167 req_pl = (struct uw_req_pl *)(((u8 *)req) + sizeof(*req)); ··· 1219 1197 p += asn1tag_write(p, 0x04, enckey, enckeysize); 1220 1198 1221 1199 /* reply cprb and payload */ 1222 - rep = alloc_cprb(sizeof(struct uw_rep_pl)); 1200 + rep = alloc_cprbmem(sizeof(struct uw_rep_pl), xflags); 1223 1201 if (!rep) 1224 1202 goto out; 1225 1203 rep_pl = (struct uw_rep_pl *)(((u8 *)rep) + sizeof(*rep)); 1226 1204 1227 1205 /* urb and target */ 1228 - urb = kmalloc(sizeof(*urb), GFP_KERNEL); 1229 - if (!urb) 1230 - goto out; 1231 1206 target.ap_id = card; 1232 1207 target.dom_id = domain; 1233 - prep_urb(urb, &target, 1, 1208 + prep_urb(&urb, &target, 1, 1234 1209 req, sizeof(*req) + req_pl_size, 1235 1210 rep, sizeof(*rep) + sizeof(*rep_pl)); 1236 1211 1237 - rc = zcrypt_send_ep11_cprb(urb, 0); 1212 + rc = zcrypt_send_ep11_cprb(&urb, xflags); 1238 1213 if (rc) { 1239 1214 ZCRYPT_DBF_ERR("%s zcrypt_send_ep11_cprb(card=%d dom=%d) failed, rc=%d\n", 1240 1215 __func__, (int)card, (int)domain, rc); ··· 1264 1245 *keybufsize = rep_pl->data_len; 1265 1246 1266 1247 out: 1267 - kfree(req); 1268 - kfree(rep); 1269 - kfree(urb); 1248 + free_cprbmem(req, req_pl_size, true, xflags); 1249 + free_cprbmem(rep, sizeof(struct uw_rep_pl), true, xflags); 1270 1250 return rc; 1271 1251 } 1272 1252 ··· 1337 1319 } __packed * rep_pl; 1338 1320 struct ep11_cprb *req = NULL, *rep = NULL; 1339 1321 struct ep11_target_dev target; 1340 - struct ep11_urb *urb = NULL; 1322 + struct ep11_urb urb; 1341 1323 size_t req_pl_size; 1342 1324 int api, rc = -ENOMEM; 1343 1325 u8 *p; 1326 + const u32 xflags = 0; 1344 1327 1345 1328 /* request cprb and payload */ 1346 1329 req_pl_size = sizeof(struct wk_req_pl) + (iv ? 16 : 0) 1347 1330 + ASN1TAGLEN(keysize) + 4; 1348 - req = alloc_cprb(req_pl_size); 1331 + req = alloc_cprbmem(req_pl_size, xflags); 1349 1332 if (!req) 1350 1333 goto out; 1351 1334 if (!mech || mech == 0x80060001) ··· 1376 1357 *p++ = 0; 1377 1358 1378 1359 /* reply cprb and payload */ 1379 - rep = alloc_cprb(sizeof(struct wk_rep_pl)); 1360 + rep = alloc_cprbmem(sizeof(struct wk_rep_pl), xflags); 1380 1361 if (!rep) 1381 1362 goto out; 1382 1363 rep_pl = (struct wk_rep_pl *)(((u8 *)rep) + sizeof(*rep)); 1383 1364 1384 1365 /* urb and target */ 1385 - urb = kmalloc(sizeof(*urb), GFP_KERNEL); 1386 - if (!urb) 1387 - goto out; 1388 1366 target.ap_id = card; 1389 1367 target.dom_id = domain; 1390 - prep_urb(urb, &target, 1, 1368 + prep_urb(&urb, &target, 1, 1391 1369 req, sizeof(*req) + req_pl_size, 1392 1370 rep, sizeof(*rep) + sizeof(*rep_pl)); 1393 1371 1394 - rc = zcrypt_send_ep11_cprb(urb, 0); 1372 + rc = zcrypt_send_ep11_cprb(&urb, xflags); 1395 1373 if (rc) { 1396 1374 ZCRYPT_DBF_ERR("%s zcrypt_send_ep11_cprb(card=%d dom=%d) failed, rc=%d\n", 1397 1375 __func__, (int)card, (int)domain, rc); ··· 1421 1405 *datasize = rep_pl->data_len; 1422 1406 1423 1407 out: 1424 - kfree(req); 1425 - kfree(rep); 1426 - kfree(urb); 1408 + free_cprbmem(req, req_pl_size, true, xflags); 1409 + free_cprbmem(rep, sizeof(struct wk_rep_pl), true, xflags); 1427 1410 return rc; 1428 1411 } 1429 1412 ··· 1474 1459 encbuf, encbuflen, 0, def_iv, 1475 1460 keybitsize, 0, keybuf, keybufsize, keytype); 1476 1461 if (rc) { 1477 - ZCRYPT_DBF_ERR("%s importing key value as new key failed,, rc=%d\n", 1462 + ZCRYPT_DBF_ERR("%s importing key value as new key failed, rc=%d\n", 1478 1463 __func__, rc); 1479 1464 goto out; 1480 1465 } ··· 1673 1658 } 1674 1659 EXPORT_SYMBOL(ep11_findcard2); 1675 1660 1676 - void __exit zcrypt_ep11misc_exit(void) 1661 + int __init zcrypt_ep11misc_init(void) 1662 + { 1663 + /* Pre-allocate a small memory pool for ep11 cprbs. */ 1664 + cprb_mempool = mempool_create_kmalloc_pool(2 * zcrypt_mempool_threshold, 1665 + CPRB_MEMPOOL_ITEM_SIZE); 1666 + if (!cprb_mempool) 1667 + return -ENOMEM; 1668 + 1669 + return 0; 1670 + } 1671 + 1672 + void zcrypt_ep11misc_exit(void) 1677 1673 { 1678 1674 card_cache_free(); 1675 + mempool_destroy(cprb_mempool); 1679 1676 }
+1
drivers/s390/crypto/zcrypt_ep11misc.h
··· 152 152 int ep11_kblob2protkey(u16 card, u16 dom, const u8 *key, u32 keylen, 153 153 u8 *protkey, u32 *protkeylen, u32 *protkeytype); 154 154 155 + int zcrypt_ep11misc_init(void); 155 156 void zcrypt_ep11misc_exit(void); 156 157 157 158 #endif /* _ZCRYPT_EP11MISC_H_ */