Skip to content

Commit 9bdb5f7

Browse files
hfreudehcahca
authored andcommitted
s390/zcrypt: Introduce cprb mempool for cca misc functions
Introduce a new module parameter "zcrypt_mempool_threshold" for the zcrypt module. This parameter controls the minimal amount of mempool items which are pre-allocated for urgent requests/replies and will be used with the support for the new xflag ZCRYPT_XFLAG_NOMEMALLOC. The default value of 5 shall provide enough memory items to support up to 5 requests (and their associated reply) in parallel. The minimum value is 1 and is checked in zcrypt module init(). If the mempool is depleted upon one cca misc functions is called with the named xflag set, the function will fail with -ENOMEM and the caller is responsible for taking further actions. For CCA each mempool item is 16KB, as a CCA CPRB needs to hold the request and the reply. The pool items only support requests/replies with a limit of about 8KB. So by default the CCA mempool consumes 5 * 16KB = 80KB 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-7-freude@linux.ibm.com Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
1 parent 80c20b2 commit 9bdb5f7

4 files changed

Lines changed: 103 additions & 32 deletions

File tree

drivers/s390/crypto/zcrypt_api.c

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ MODULE_DESCRIPTION("Cryptographic Coprocessor interface, " \
5050
"Copyright IBM Corp. 2001, 2012");
5151
MODULE_LICENSE("GPL");
5252

53+
unsigned int zcrypt_mempool_threshold = 5;
54+
module_param_named(mempool_threshold, zcrypt_mempool_threshold, uint, 0440);
55+
MODULE_PARM_DESC(mempool_threshold, "CCA and EP11 request/reply mempool minimal items (min: 1)");
56+
5357
/*
5458
* zcrypt tracepoint functions
5559
*/
@@ -2144,13 +2148,23 @@ int __init zcrypt_api_init(void)
21442148
{
21452149
int rc;
21462150

2151+
/* make sure the mempool threshold is >= 1 */
2152+
if (zcrypt_mempool_threshold < 1) {
2153+
rc = -EINVAL;
2154+
goto out;
2155+
}
2156+
21472157
rc = zcrypt_debug_init();
21482158
if (rc)
21492159
goto out;
21502160

21512161
rc = zcdn_init();
21522162
if (rc)
2153-
goto out;
2163+
goto out_zcdn_init_failed;
2164+
2165+
rc = zcrypt_ccamisc_init();
2166+
if (rc)
2167+
goto out_ccamisc_init_failed;
21542168

21552169
/* Register the request sprayer. */
21562170
rc = misc_register(&zcrypt_misc_device);
@@ -2163,7 +2177,10 @@ int __init zcrypt_api_init(void)
21632177
return 0;
21642178

21652179
out_misc_register_failed:
2180+
zcrypt_ccamisc_exit();
2181+
out_ccamisc_init_failed:
21662182
zcdn_exit();
2183+
out_zcdn_init_failed:
21672184
zcrypt_debug_exit();
21682185
out:
21692186
return rc;

drivers/s390/crypto/zcrypt_api.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,8 @@ extern atomic_t zcrypt_rescan_req;
139139
extern spinlock_t zcrypt_list_lock;
140140
extern struct list_head zcrypt_card_list;
141141

142+
extern unsigned int zcrypt_mempool_threshold;
143+
142144
#define for_each_zcrypt_card(_zc) \
143145
list_for_each_entry(_zc, &zcrypt_card_list, list)
144146

drivers/s390/crypto/zcrypt_ccamisc.c

Lines changed: 82 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
1212

1313
#include <linux/init.h>
14+
#include <linux/mempool.h>
1415
#include <linux/module.h>
1516
#include <linux/slab.h>
1617
#include <linux/random.h>
@@ -40,6 +41,16 @@ struct cca_info_list_entry {
4041
static LIST_HEAD(cca_info_list);
4142
static DEFINE_SPINLOCK(cca_info_list_lock);
4243

44+
/*
45+
* Cprb memory pool held for urgent cases where no memory
46+
* can be allocated via kmalloc. This pool is only used
47+
* when alloc_and_prep_cprbmem() is called with the xflag
48+
* ZCRYPT_XFLAG_NOMEMALLOC. The cprb memory needs to hold
49+
* space for request AND reply!
50+
*/
51+
#define CPRB_MEMPOOL_ITEM_SIZE (16 * 1024)
52+
static mempool_t *cprb_mempool;
53+
4354
/*
4455
* Simple check if the token is a valid CCA secure AES data key
4556
* token. If keybitsize is given, the bitsize of the key is
@@ -219,19 +230,27 @@ EXPORT_SYMBOL(cca_check_sececckeytoken);
219230
static int alloc_and_prep_cprbmem(size_t paramblen,
220231
u8 **p_cprb_mem,
221232
struct CPRBX **p_req_cprb,
222-
struct CPRBX **p_rep_cprb)
233+
struct CPRBX **p_rep_cprb,
234+
u32 xflags)
223235
{
224-
u8 *cprbmem;
236+
u8 *cprbmem = NULL;
225237
size_t cprbplusparamblen = sizeof(struct CPRBX) + paramblen;
238+
size_t len = 2 * cprbplusparamblen;
226239
struct CPRBX *preqcblk, *prepcblk;
227240

228241
/*
229242
* allocate consecutive memory for request CPRB, request param
230243
* block, reply CPRB and reply param block
231244
*/
232-
cprbmem = kcalloc(2, cprbplusparamblen, GFP_KERNEL);
245+
if (xflags & ZCRYPT_XFLAG_NOMEMALLOC) {
246+
if (len <= CPRB_MEMPOOL_ITEM_SIZE)
247+
cprbmem = mempool_alloc_preallocated(cprb_mempool);
248+
} else {
249+
cprbmem = kmalloc(len, GFP_KERNEL);
250+
}
233251
if (!cprbmem)
234252
return -ENOMEM;
253+
memset(cprbmem, 0, len);
235254

236255
preqcblk = (struct CPRBX *)cprbmem;
237256
prepcblk = (struct CPRBX *)(cprbmem + cprbplusparamblen);
@@ -261,11 +280,15 @@ static int alloc_and_prep_cprbmem(size_t paramblen,
261280
* with zeros before freeing (useful if there was some
262281
* clear key material in there).
263282
*/
264-
static void free_cprbmem(void *mem, size_t paramblen, int scrub)
283+
static void free_cprbmem(void *mem, size_t paramblen, bool scrub, u32 xflags)
265284
{
266-
if (scrub)
285+
if (mem && scrub)
267286
memzero_explicit(mem, 2 * (sizeof(struct CPRBX) + paramblen));
268-
kfree(mem);
287+
288+
if (xflags & ZCRYPT_XFLAG_NOMEMALLOC)
289+
mempool_free(mem, cprb_mempool);
290+
else
291+
kfree(mem);
269292
}
270293

271294
/*
@@ -330,9 +353,11 @@ int cca_genseckey(u16 cardnr, u16 domain,
330353
} keyblock;
331354
} lv3;
332355
} __packed * prepparm;
356+
const u32 xflags = 0;
333357

334358
/* get already prepared memory for 2 cprbs with param block each */
335-
rc = alloc_and_prep_cprbmem(PARMBSIZE, &mem, &preqcblk, &prepcblk);
359+
rc = alloc_and_prep_cprbmem(PARMBSIZE, &mem,
360+
&preqcblk, &prepcblk, xflags);
336361
if (rc)
337362
return rc;
338363

@@ -379,7 +404,7 @@ int cca_genseckey(u16 cardnr, u16 domain,
379404
prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk);
380405

381406
/* forward xcrb with request CPRB and reply CPRB to zcrypt dd */
382-
rc = zcrypt_send_cprb(&xcrb, 0);
407+
rc = zcrypt_send_cprb(&xcrb, xflags);
383408
if (rc) {
384409
ZCRYPT_DBF_ERR("%s zcrypt_send_cprb (cardnr=%d domain=%d) failed, errno %d\n",
385410
__func__, (int)cardnr, (int)domain, rc);
@@ -424,7 +449,7 @@ int cca_genseckey(u16 cardnr, u16 domain,
424449
memcpy(seckey, prepparm->lv3.keyblock.tok, SECKEYBLOBSIZE);
425450

426451
out:
427-
free_cprbmem(mem, PARMBSIZE, 0);
452+
free_cprbmem(mem, PARMBSIZE, false, xflags);
428453
return rc;
429454
}
430455
EXPORT_SYMBOL(cca_genseckey);
@@ -471,9 +496,11 @@ int cca_clr2seckey(u16 cardnr, u16 domain, u32 keybitsize,
471496
} keyblock;
472497
} lv3;
473498
} __packed * prepparm;
499+
const u32 xflags = 0;
474500

475501
/* get already prepared memory for 2 cprbs with param block each */
476-
rc = alloc_and_prep_cprbmem(PARMBSIZE, &mem, &preqcblk, &prepcblk);
502+
rc = alloc_and_prep_cprbmem(PARMBSIZE, &mem,
503+
&preqcblk, &prepcblk, xflags);
477504
if (rc)
478505
return rc;
479506

@@ -517,7 +544,7 @@ int cca_clr2seckey(u16 cardnr, u16 domain, u32 keybitsize,
517544
prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk);
518545

519546
/* forward xcrb with request CPRB and reply CPRB to zcrypt dd */
520-
rc = zcrypt_send_cprb(&xcrb, 0);
547+
rc = zcrypt_send_cprb(&xcrb, xflags);
521548
if (rc) {
522549
ZCRYPT_DBF_ERR("%s zcrypt_send_cprb (cardnr=%d domain=%d) failed, rc=%d\n",
523550
__func__, (int)cardnr, (int)domain, rc);
@@ -563,7 +590,7 @@ int cca_clr2seckey(u16 cardnr, u16 domain, u32 keybitsize,
563590
memcpy(seckey, prepparm->lv3.keyblock.tok, SECKEYBLOBSIZE);
564591

565592
out:
566-
free_cprbmem(mem, PARMBSIZE, 1);
593+
free_cprbmem(mem, PARMBSIZE, true, xflags);
567594
return rc;
568595
}
569596
EXPORT_SYMBOL(cca_clr2seckey);
@@ -617,9 +644,11 @@ int cca_sec2protkey(u16 cardnr, u16 domain,
617644
} ckb;
618645
} lv3;
619646
} __packed * prepparm;
647+
const u32 xflags = 0;
620648

621649
/* get already prepared memory for 2 cprbs with param block each */
622-
rc = alloc_and_prep_cprbmem(PARMBSIZE, &mem, &preqcblk, &prepcblk);
650+
rc = alloc_and_prep_cprbmem(PARMBSIZE, &mem,
651+
&preqcblk, &prepcblk, xflags);
623652
if (rc)
624653
return rc;
625654

@@ -644,7 +673,7 @@ int cca_sec2protkey(u16 cardnr, u16 domain,
644673
prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk);
645674

646675
/* forward xcrb with request CPRB and reply CPRB to zcrypt dd */
647-
rc = zcrypt_send_cprb(&xcrb, 0);
676+
rc = zcrypt_send_cprb(&xcrb, xflags);
648677
if (rc) {
649678
ZCRYPT_DBF_ERR("%s zcrypt_send_cprb (cardnr=%d domain=%d) failed, rc=%d\n",
650679
__func__, (int)cardnr, (int)domain, rc);
@@ -712,7 +741,7 @@ int cca_sec2protkey(u16 cardnr, u16 domain,
712741
*protkeylen = prepparm->lv3.ckb.len;
713742

714743
out:
715-
free_cprbmem(mem, PARMBSIZE, 0);
744+
free_cprbmem(mem, PARMBSIZE, true, xflags);
716745
return rc;
717746
}
718747
EXPORT_SYMBOL(cca_sec2protkey);
@@ -811,9 +840,11 @@ int cca_gencipherkey(u16 cardnr, u16 domain, u32 keybitsize, u32 keygenflags,
811840
} kb;
812841
} __packed * prepparm;
813842
struct cipherkeytoken *t;
843+
const u32 xflags = 0;
814844

815845
/* get already prepared memory for 2 cprbs with param block each */
816-
rc = alloc_and_prep_cprbmem(PARMBSIZE, &mem, &preqcblk, &prepcblk);
846+
rc = alloc_and_prep_cprbmem(PARMBSIZE, &mem,
847+
&preqcblk, &prepcblk, xflags);
817848
if (rc)
818849
return rc;
819850

@@ -872,7 +903,7 @@ int cca_gencipherkey(u16 cardnr, u16 domain, u32 keybitsize, u32 keygenflags,
872903
prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk);
873904

874905
/* forward xcrb with request CPRB and reply CPRB to zcrypt dd */
875-
rc = zcrypt_send_cprb(&xcrb, 0);
906+
rc = zcrypt_send_cprb(&xcrb, xflags);
876907
if (rc) {
877908
ZCRYPT_DBF_ERR("%s zcrypt_send_cprb (cardnr=%d domain=%d) failed, rc=%d\n",
878909
__func__, (int)cardnr, (int)domain, rc);
@@ -923,7 +954,7 @@ int cca_gencipherkey(u16 cardnr, u16 domain, u32 keybitsize, u32 keygenflags,
923954
*keybufsize = t->len;
924955

925956
out:
926-
free_cprbmem(mem, PARMBSIZE, 0);
957+
free_cprbmem(mem, PARMBSIZE, false, xflags);
927958
return rc;
928959
}
929960
EXPORT_SYMBOL(cca_gencipherkey);
@@ -987,9 +1018,11 @@ static int _ip_cprb_helper(u16 cardnr, u16 domain,
9871018
} __packed * prepparm;
9881019
struct cipherkeytoken *t;
9891020
int complete = strncmp(rule_array_2, "COMPLETE", 8) ? 0 : 1;
1021+
const u32 xflags = 0;
9901022

9911023
/* get already prepared memory for 2 cprbs with param block each */
992-
rc = alloc_and_prep_cprbmem(PARMBSIZE, &mem, &preqcblk, &prepcblk);
1024+
rc = alloc_and_prep_cprbmem(PARMBSIZE, &mem,
1025+
&preqcblk, &prepcblk, xflags);
9931026
if (rc)
9941027
return rc;
9951028

@@ -1038,7 +1071,7 @@ static int _ip_cprb_helper(u16 cardnr, u16 domain,
10381071
prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk);
10391072

10401073
/* forward xcrb with request CPRB and reply CPRB to zcrypt dd */
1041-
rc = zcrypt_send_cprb(&xcrb, 0);
1074+
rc = zcrypt_send_cprb(&xcrb, xflags);
10421075
if (rc) {
10431076
ZCRYPT_DBF_ERR("%s zcrypt_send_cprb (cardnr=%d domain=%d) failed, rc=%d\n",
10441077
__func__, (int)cardnr, (int)domain, rc);
@@ -1077,7 +1110,7 @@ static int _ip_cprb_helper(u16 cardnr, u16 domain,
10771110
*key_token_size = t->len;
10781111

10791112
out:
1080-
free_cprbmem(mem, PARMBSIZE, 0);
1113+
free_cprbmem(mem, PARMBSIZE, false, xflags);
10811114
return rc;
10821115
}
10831116

@@ -1217,9 +1250,11 @@ int cca_cipher2protkey(u16 cardnr, u16 domain, const u8 *ckey,
12171250
} kb;
12181251
} __packed * prepparm;
12191252
int keytoklen = ((struct cipherkeytoken *)ckey)->len;
1253+
const u32 xflags = 0;
12201254

12211255
/* get already prepared memory for 2 cprbs with param block each */
1222-
rc = alloc_and_prep_cprbmem(PARMBSIZE, &mem, &preqcblk, &prepcblk);
1256+
rc = alloc_and_prep_cprbmem(PARMBSIZE, &mem,
1257+
&preqcblk, &prepcblk, xflags);
12231258
if (rc)
12241259
return rc;
12251260

@@ -1249,7 +1284,7 @@ int cca_cipher2protkey(u16 cardnr, u16 domain, const u8 *ckey,
12491284
prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk);
12501285

12511286
/* forward xcrb with request CPRB and reply CPRB to zcrypt dd */
1252-
rc = zcrypt_send_cprb(&xcrb, 0);
1287+
rc = zcrypt_send_cprb(&xcrb, xflags);
12531288
if (rc) {
12541289
ZCRYPT_DBF_ERR("%s zcrypt_send_cprb (cardnr=%d domain=%d) failed, rc=%d\n",
12551290
__func__, (int)cardnr, (int)domain, rc);
@@ -1323,7 +1358,7 @@ int cca_cipher2protkey(u16 cardnr, u16 domain, const u8 *ckey,
13231358
*protkeylen = prepparm->vud.ckb.keylen;
13241359

13251360
out:
1326-
free_cprbmem(mem, PARMBSIZE, 0);
1361+
free_cprbmem(mem, PARMBSIZE, true, xflags);
13271362
return rc;
13281363
}
13291364
EXPORT_SYMBOL(cca_cipher2protkey);
@@ -1380,9 +1415,11 @@ int cca_ecc2protkey(u16 cardnr, u16 domain, const u8 *key,
13801415
/* followed by a key block */
13811416
} __packed * prepparm;
13821417
int keylen = ((struct eccprivkeytoken *)key)->len;
1418+
const u32 xflags = 0;
13831419

13841420
/* get already prepared memory for 2 cprbs with param block each */
1385-
rc = alloc_and_prep_cprbmem(PARMBSIZE, &mem, &preqcblk, &prepcblk);
1421+
rc = alloc_and_prep_cprbmem(PARMBSIZE, &mem,
1422+
&preqcblk, &prepcblk, xflags);
13861423
if (rc)
13871424
return rc;
13881425

@@ -1412,7 +1449,7 @@ int cca_ecc2protkey(u16 cardnr, u16 domain, const u8 *key,
14121449
prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk);
14131450

14141451
/* forward xcrb with request CPRB and reply CPRB to zcrypt dd */
1415-
rc = zcrypt_send_cprb(&xcrb, 0);
1452+
rc = zcrypt_send_cprb(&xcrb, xflags);
14161453
if (rc) {
14171454
ZCRYPT_DBF_ERR("%s zcrypt_send_cprb (cardnr=%d domain=%d) failed, rc=%d\n",
14181455
__func__, (int)cardnr, (int)domain, rc);
@@ -1470,7 +1507,7 @@ int cca_ecc2protkey(u16 cardnr, u16 domain, const u8 *key,
14701507
*protkeytype = PKEY_KEYTYPE_ECC;
14711508

14721509
out:
1473-
free_cprbmem(mem, PARMBSIZE, 0);
1510+
free_cprbmem(mem, PARMBSIZE, true, xflags);
14741511
return rc;
14751512
}
14761513
EXPORT_SYMBOL(cca_ecc2protkey);
@@ -1503,9 +1540,11 @@ int cca_query_crypto_facility(u16 cardnr, u16 domain,
15031540
u8 subfunc_code[2];
15041541
u8 lvdata[];
15051542
} __packed * prepparm;
1543+
const u32 xflags = 0;
15061544

15071545
/* get already prepared memory for 2 cprbs with param block each */
1508-
rc = alloc_and_prep_cprbmem(parmbsize, &mem, &preqcblk, &prepcblk);
1546+
rc = alloc_and_prep_cprbmem(parmbsize, &mem,
1547+
&preqcblk, &prepcblk, xflags);
15091548
if (rc)
15101549
return rc;
15111550

@@ -1526,7 +1565,7 @@ int cca_query_crypto_facility(u16 cardnr, u16 domain,
15261565
prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk);
15271566

15281567
/* forward xcrb with request CPRB and reply CPRB to zcrypt dd */
1529-
rc = zcrypt_send_cprb(&xcrb, 0);
1568+
rc = zcrypt_send_cprb(&xcrb, xflags);
15301569
if (rc) {
15311570
ZCRYPT_DBF_ERR("%s zcrypt_send_cprb (cardnr=%d domain=%d) failed, rc=%d\n",
15321571
__func__, (int)cardnr, (int)domain, rc);
@@ -1573,7 +1612,7 @@ int cca_query_crypto_facility(u16 cardnr, u16 domain,
15731612
}
15741613

15751614
out:
1576-
free_cprbmem(mem, parmbsize, 0);
1615+
free_cprbmem(mem, parmbsize, false, xflags);
15771616
return rc;
15781617
}
15791618
EXPORT_SYMBOL(cca_query_crypto_facility);
@@ -1959,7 +1998,19 @@ int cca_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
19591998
}
19601999
EXPORT_SYMBOL(cca_findcard2);
19612000

1962-
void __exit zcrypt_ccamisc_exit(void)
2001+
int __init zcrypt_ccamisc_init(void)
2002+
{
2003+
/* Pre-allocate a small memory pool for cca cprbs. */
2004+
cprb_mempool = mempool_create_kmalloc_pool(zcrypt_mempool_threshold,
2005+
CPRB_MEMPOOL_ITEM_SIZE);
2006+
if (!cprb_mempool)
2007+
return -ENOMEM;
2008+
2009+
return 0;
2010+
}
2011+
2012+
void zcrypt_ccamisc_exit(void)
19632013
{
19642014
mkvp_cache_free();
2015+
mempool_destroy(cprb_mempool);
19652016
}

0 commit comments

Comments
 (0)