Skip to content

Commit 15cdc6f

Browse files
hfreudehcahca
authored andcommitted
s390/pkey: Rework EP11 pkey handler to use stack for small memory allocs
There have been some places in the EP11 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-21-freude@linux.ibm.com Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
1 parent c45dabf commit 15cdc6f

1 file changed

Lines changed: 10 additions & 33 deletions

File tree

drivers/s390/crypto/pkey_ep11.c

Lines changed: 10 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ static int ep11_key2protkey(const struct pkey_apqn *apqns, size_t nr_apqns,
186186
u8 *protkey, u32 *protkeylen, u32 *protkeytype)
187187
{
188188
struct keytoken_header *hdr = (struct keytoken_header *)key;
189-
struct pkey_apqn *local_apqns = NULL;
189+
struct pkey_apqn _apqns[MAXAPQNSINLIST];
190190
int i, rc;
191191

192192
if (keylen < sizeof(*hdr))
@@ -223,14 +223,10 @@ static int ep11_key2protkey(const struct pkey_apqn *apqns, size_t nr_apqns,
223223
if (!apqns || (nr_apqns == 1 &&
224224
apqns[0].card == 0xFFFF && apqns[0].domain == 0xFFFF)) {
225225
nr_apqns = MAXAPQNSINLIST;
226-
local_apqns = kmalloc_array(nr_apqns, sizeof(struct pkey_apqn),
227-
GFP_KERNEL);
228-
if (!local_apqns)
229-
return -ENOMEM;
230-
rc = ep11_apqns4key(key, keylen, 0, local_apqns, &nr_apqns);
226+
rc = ep11_apqns4key(key, keylen, 0, _apqns, &nr_apqns);
231227
if (rc)
232228
goto out;
233-
apqns = local_apqns;
229+
apqns = _apqns;
234230
}
235231

236232
for (rc = -ENODEV, i = 0; rc && i < nr_apqns; i++) {
@@ -259,7 +255,6 @@ static int ep11_key2protkey(const struct pkey_apqn *apqns, size_t nr_apqns,
259255
}
260256

261257
out:
262-
kfree(local_apqns);
263258
pr_debug("rc=%d\n", rc);
264259
return rc;
265260
}
@@ -278,7 +273,7 @@ static int ep11_gen_key(const struct pkey_apqn *apqns, size_t nr_apqns,
278273
u32 keybitsize, u32 flags,
279274
u8 *keybuf, u32 *keybuflen, u32 *_keyinfo)
280275
{
281-
struct pkey_apqn *local_apqns = NULL;
276+
struct pkey_apqn _apqns[MAXAPQNSINLIST];
282277
int i, len, rc;
283278
const u32 xflags = 0;
284279

@@ -315,15 +310,10 @@ static int ep11_gen_key(const struct pkey_apqn *apqns, size_t nr_apqns,
315310
if (!apqns || (nr_apqns == 1 &&
316311
apqns[0].card == 0xFFFF && apqns[0].domain == 0xFFFF)) {
317312
nr_apqns = MAXAPQNSINLIST;
318-
local_apqns = kmalloc_array(nr_apqns, sizeof(struct pkey_apqn),
319-
GFP_KERNEL);
320-
if (!local_apqns)
321-
return -ENOMEM;
322-
rc = ep11_apqns4type(subtype, NULL, NULL, 0,
323-
local_apqns, &nr_apqns);
313+
rc = ep11_apqns4type(subtype, NULL, NULL, 0, _apqns, &nr_apqns);
324314
if (rc)
325315
goto out;
326-
apqns = local_apqns;
316+
apqns = _apqns;
327317
}
328318

329319
for (rc = -ENODEV, i = 0; rc && i < nr_apqns; i++) {
@@ -333,7 +323,6 @@ static int ep11_gen_key(const struct pkey_apqn *apqns, size_t nr_apqns,
333323
}
334324

335325
out:
336-
kfree(local_apqns);
337326
pr_debug("rc=%d\n", rc);
338327
return rc;
339328
}
@@ -353,7 +342,7 @@ static int ep11_clr2key(const struct pkey_apqn *apqns, size_t nr_apqns,
353342
const u8 *clrkey, u32 clrkeylen,
354343
u8 *keybuf, u32 *keybuflen, u32 *_keyinfo)
355344
{
356-
struct pkey_apqn *local_apqns = NULL;
345+
struct pkey_apqn _apqns[MAXAPQNSINLIST];
357346
int i, len, rc;
358347

359348
/* check keytype, subtype, clrkeylen, keybitsize */
@@ -394,15 +383,10 @@ static int ep11_clr2key(const struct pkey_apqn *apqns, size_t nr_apqns,
394383
if (!apqns || (nr_apqns == 1 &&
395384
apqns[0].card == 0xFFFF && apqns[0].domain == 0xFFFF)) {
396385
nr_apqns = MAXAPQNSINLIST;
397-
local_apqns = kmalloc_array(nr_apqns, sizeof(struct pkey_apqn),
398-
GFP_KERNEL);
399-
if (!local_apqns)
400-
return -ENOMEM;
401-
rc = ep11_apqns4type(subtype, NULL, NULL, 0,
402-
local_apqns, &nr_apqns);
386+
rc = ep11_apqns4type(subtype, NULL, NULL, 0, _apqns, &nr_apqns);
403387
if (rc)
404388
goto out;
405-
apqns = local_apqns;
389+
apqns = _apqns;
406390
}
407391

408392
for (rc = -ENODEV, i = 0; rc && i < nr_apqns; i++) {
@@ -412,7 +396,6 @@ static int ep11_clr2key(const struct pkey_apqn *apqns, size_t nr_apqns,
412396
}
413397

414398
out:
415-
kfree(local_apqns);
416399
pr_debug("rc=%d\n", rc);
417400
return rc;
418401
}
@@ -502,8 +485,8 @@ static int ep11_slowpath_key2protkey(const struct pkey_apqn *apqns,
502485
{
503486
const struct keytoken_header *hdr = (const struct keytoken_header *)key;
504487
const struct clearkeytoken *t = (const struct clearkeytoken *)key;
488+
u8 tmpbuf[MAXEP11AESKEYBLOBSIZE]; /* 336 bytes */
505489
u32 tmplen, keysize = 0;
506-
u8 *tmpbuf;
507490
int i, rc;
508491

509492
if (keylen < sizeof(*hdr))
@@ -515,11 +498,6 @@ static int ep11_slowpath_key2protkey(const struct pkey_apqn *apqns,
515498
if (!keysize || t->len != keysize)
516499
return -EINVAL;
517500

518-
/* alloc tmp key buffer */
519-
tmpbuf = kmalloc(MAXEP11AESKEYBLOBSIZE, GFP_ATOMIC);
520-
if (!tmpbuf)
521-
return -ENOMEM;
522-
523501
/* try two times in case of failure */
524502
for (i = 0, rc = -ENODEV; i < 2 && rc; i++) {
525503
tmplen = MAXEP11AESKEYBLOBSIZE;
@@ -534,7 +512,6 @@ static int ep11_slowpath_key2protkey(const struct pkey_apqn *apqns,
534512
pr_debug("ep11_key2protkey()=%d\n", rc);
535513
}
536514

537-
kfree(tmpbuf);
538515
pr_debug("rc=%d\n", rc);
539516
return rc;
540517
}

0 commit comments

Comments
 (0)