Skip to content

Commit c45dabf

Browse files
hfreudehcahca
authored andcommitted
s390/pkey: Rework CCA pkey handler to use stack for small memory allocs
There have been some places in the CCA handler code where relatively small amounts of memory have been allocated an freed at the end of the function. This code has been reworked to use the stack instead. 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-20-freude@linux.ibm.com Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
1 parent 6fecab9 commit c45dabf

1 file changed

Lines changed: 10 additions & 33 deletions

File tree

drivers/s390/crypto/pkey_cca.c

Lines changed: 10 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ static int cca_key2protkey(const struct pkey_apqn *apqns, size_t nr_apqns,
213213
u8 *protkey, u32 *protkeylen, u32 *protkeytype)
214214
{
215215
struct keytoken_header *hdr = (struct keytoken_header *)key;
216-
struct pkey_apqn *local_apqns = NULL;
216+
struct pkey_apqn _apqns[MAXAPQNSINLIST];
217217
int i, rc;
218218

219219
if (keylen < sizeof(*hdr))
@@ -251,14 +251,10 @@ static int cca_key2protkey(const struct pkey_apqn *apqns, size_t nr_apqns,
251251
if (!apqns || (nr_apqns == 1 &&
252252
apqns[0].card == 0xFFFF && apqns[0].domain == 0xFFFF)) {
253253
nr_apqns = MAXAPQNSINLIST;
254-
local_apqns = kmalloc_array(nr_apqns, sizeof(struct pkey_apqn),
255-
GFP_KERNEL);
256-
if (!local_apqns)
257-
return -ENOMEM;
258-
rc = cca_apqns4key(key, keylen, 0, local_apqns, &nr_apqns);
254+
rc = cca_apqns4key(key, keylen, 0, _apqns, &nr_apqns);
259255
if (rc)
260256
goto out;
261-
apqns = local_apqns;
257+
apqns = _apqns;
262258
}
263259

264260
for (rc = -ENODEV, i = 0; rc && i < nr_apqns; i++) {
@@ -283,7 +279,6 @@ static int cca_key2protkey(const struct pkey_apqn *apqns, size_t nr_apqns,
283279
}
284280

285281
out:
286-
kfree(local_apqns);
287282
pr_debug("rc=%d\n", rc);
288283
return rc;
289284
}
@@ -302,7 +297,7 @@ static int cca_gen_key(const struct pkey_apqn *apqns, size_t nr_apqns,
302297
u32 keybitsize, u32 flags,
303298
u8 *keybuf, u32 *keybuflen, u32 *_keyinfo)
304299
{
305-
struct pkey_apqn *local_apqns = NULL;
300+
struct pkey_apqn _apqns[MAXAPQNSINLIST];
306301
int i, len, rc;
307302

308303
/* check keytype, subtype, keybitsize */
@@ -338,15 +333,10 @@ static int cca_gen_key(const struct pkey_apqn *apqns, size_t nr_apqns,
338333
if (!apqns || (nr_apqns == 1 &&
339334
apqns[0].card == 0xFFFF && apqns[0].domain == 0xFFFF)) {
340335
nr_apqns = MAXAPQNSINLIST;
341-
local_apqns = kmalloc_array(nr_apqns, sizeof(struct pkey_apqn),
342-
GFP_KERNEL);
343-
if (!local_apqns)
344-
return -ENOMEM;
345-
rc = cca_apqns4type(subtype, NULL, NULL, 0,
346-
local_apqns, &nr_apqns);
336+
rc = cca_apqns4type(subtype, NULL, NULL, 0, _apqns, &nr_apqns);
347337
if (rc)
348338
goto out;
349-
apqns = local_apqns;
339+
apqns = _apqns;
350340
}
351341

352342
for (rc = -ENODEV, i = 0; rc && i < nr_apqns; i++) {
@@ -363,7 +353,6 @@ static int cca_gen_key(const struct pkey_apqn *apqns, size_t nr_apqns,
363353
}
364354

365355
out:
366-
kfree(local_apqns);
367356
pr_debug("rc=%d\n", rc);
368357
return rc;
369358
}
@@ -383,7 +372,7 @@ static int cca_clr2key(const struct pkey_apqn *apqns, size_t nr_apqns,
383372
const u8 *clrkey, u32 clrkeylen,
384373
u8 *keybuf, u32 *keybuflen, u32 *_keyinfo)
385374
{
386-
struct pkey_apqn *local_apqns = NULL;
375+
struct pkey_apqn _apqns[MAXAPQNSINLIST];
387376
int i, len, rc;
388377

389378
/* check keytype, subtype, clrkeylen, keybitsize */
@@ -424,15 +413,10 @@ static int cca_clr2key(const struct pkey_apqn *apqns, size_t nr_apqns,
424413
if (!apqns || (nr_apqns == 1 &&
425414
apqns[0].card == 0xFFFF && apqns[0].domain == 0xFFFF)) {
426415
nr_apqns = MAXAPQNSINLIST;
427-
local_apqns = kmalloc_array(nr_apqns, sizeof(struct pkey_apqn),
428-
GFP_KERNEL);
429-
if (!local_apqns)
430-
return -ENOMEM;
431-
rc = cca_apqns4type(subtype, NULL, NULL, 0,
432-
local_apqns, &nr_apqns);
416+
rc = cca_apqns4type(subtype, NULL, NULL, 0, _apqns, &nr_apqns);
433417
if (rc)
434418
goto out;
435-
apqns = local_apqns;
419+
apqns = _apqns;
436420
}
437421

438422
for (rc = -ENODEV, i = 0; rc && i < nr_apqns; i++) {
@@ -449,7 +433,6 @@ static int cca_clr2key(const struct pkey_apqn *apqns, size_t nr_apqns,
449433
}
450434

451435
out:
452-
kfree(local_apqns);
453436
pr_debug("rc=%d\n", rc);
454437
return rc;
455438
}
@@ -554,8 +537,8 @@ static int cca_slowpath_key2protkey(const struct pkey_apqn *apqns,
554537
{
555538
const struct keytoken_header *hdr = (const struct keytoken_header *)key;
556539
const struct clearkeytoken *t = (const struct clearkeytoken *)key;
540+
u8 tmpbuf[SECKEYBLOBSIZE]; /* 64 bytes */
557541
u32 tmplen, keysize = 0;
558-
u8 *tmpbuf;
559542
int i, rc;
560543

561544
if (keylen < sizeof(*hdr))
@@ -567,11 +550,6 @@ static int cca_slowpath_key2protkey(const struct pkey_apqn *apqns,
567550
if (!keysize || t->len != keysize)
568551
return -EINVAL;
569552

570-
/* alloc tmp key buffer */
571-
tmpbuf = kmalloc(SECKEYBLOBSIZE, GFP_ATOMIC);
572-
if (!tmpbuf)
573-
return -ENOMEM;
574-
575553
/* try two times in case of failure */
576554
for (i = 0, rc = -ENODEV; i < 2 && rc; i++) {
577555
tmplen = SECKEYBLOBSIZE;
@@ -586,7 +564,6 @@ static int cca_slowpath_key2protkey(const struct pkey_apqn *apqns,
586564
pr_debug("cca_key2protkey()=%d\n", rc);
587565
}
588566

589-
kfree(tmpbuf);
590567
pr_debug("rc=%d\n", rc);
591568
return rc;
592569
}

0 commit comments

Comments
 (0)