Skip to content

Commit f91bb85

Browse files
hfreudehcahca
authored andcommitted
s390/zcrypt: Avoid alloc and copy of ep11 targets if kernelspace cprb
If there is a target list of APQNs given when an CPRB is to be send via zcrypt_send_ep11_cprb() there is always a kmalloc() done and the targets are copied via z_copy_from_user. As there are callers from kernel space (zcrypt_ep11misc.c) which signal this via the userspace parameter improve this code to directly use the given target list in case of kernelspace thus removing the unnecessary memory alloc and mem copy. 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-5-freude@linux.ibm.com Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
1 parent dcc160b commit f91bb85

1 file changed

Lines changed: 19 additions & 23 deletions

File tree

drivers/s390/crypto/zcrypt_api.c

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1035,7 +1035,7 @@ static long _zcrypt_send_ep11_cprb(bool userspace, struct ap_perms *perms,
10351035
{
10361036
struct zcrypt_card *zc, *pref_zc;
10371037
struct zcrypt_queue *zq, *pref_zq;
1038-
struct ep11_target_dev *targets;
1038+
struct ep11_target_dev *targets = NULL;
10391039
unsigned short target_num;
10401040
unsigned int wgt = 0, pref_wgt = 0;
10411041
unsigned int func_code = 0, domain;
@@ -1052,41 +1052,37 @@ static long _zcrypt_send_ep11_cprb(bool userspace, struct ap_perms *perms,
10521052
target_num = (unsigned short)xcrb->targets_num;
10531053

10541054
/* empty list indicates autoselect (all available targets) */
1055-
targets = NULL;
1055+
rc = -ENOMEM;
10561056
if (target_num != 0) {
1057-
struct ep11_target_dev __user *uptr;
1058-
1059-
targets = kcalloc(target_num, sizeof(*targets), GFP_KERNEL);
1060-
if (!targets) {
1061-
func_code = 0;
1062-
rc = -ENOMEM;
1063-
goto out;
1064-
}
1065-
1066-
uptr = (struct ep11_target_dev __force __user *)xcrb->targets;
1067-
if (z_copy_from_user(userspace, targets, uptr,
1068-
target_num * sizeof(*targets))) {
1069-
func_code = 0;
1070-
rc = -EFAULT;
1071-
goto out_free;
1057+
if (userspace) {
1058+
targets = kcalloc(target_num, sizeof(*targets), GFP_KERNEL);
1059+
if (!targets)
1060+
goto out;
1061+
if (copy_from_user(targets, xcrb->targets,
1062+
target_num * sizeof(*targets))) {
1063+
rc = -EFAULT;
1064+
goto out;
1065+
}
1066+
} else {
1067+
targets = (struct ep11_target_dev __force __kernel *)xcrb->targets;
10721068
}
10731069
}
10741070

10751071
rc = prep_ep11_ap_msg(userspace, xcrb, &ap_msg, &func_code, &domain);
10761072
if (rc)
1077-
goto out_free;
1073+
goto out;
10781074
print_hex_dump_debug("ep11req: ", DUMP_PREFIX_ADDRESS, 16, 1,
10791075
ap_msg.msg, ap_msg.len, false);
10801076

10811077
if (perms != &ap_perms && domain < AUTOSEL_DOM) {
10821078
if (ap_msg.flags & AP_MSG_FLAG_ADMIN) {
10831079
if (!test_bit_inv(domain, perms->adm)) {
10841080
rc = -ENODEV;
1085-
goto out_free;
1081+
goto out;
10861082
}
10871083
} else if ((ap_msg.flags & AP_MSG_FLAG_USAGE) == 0) {
10881084
rc = -EOPNOTSUPP;
1089-
goto out_free;
1085+
goto out;
10901086
}
10911087
}
10921088

@@ -1154,7 +1150,7 @@ static long _zcrypt_send_ep11_cprb(bool userspace, struct ap_perms *perms,
11541150
pr_debug("no match for address ff.ffff => ENODEV\n");
11551151
}
11561152
rc = -ENODEV;
1157-
goto out_free;
1153+
goto out;
11581154
}
11591155

11601156
qid = pref_zq->queue->qid;
@@ -1168,9 +1164,9 @@ static long _zcrypt_send_ep11_cprb(bool userspace, struct ap_perms *perms,
11681164
zcrypt_drop_queue(pref_zc, pref_zq, mod, wgt);
11691165
spin_unlock(&zcrypt_list_lock);
11701166

1171-
out_free:
1172-
kfree(targets);
11731167
out:
1168+
if (userspace)
1169+
kfree(targets);
11741170
ap_release_apmsg(&ap_msg);
11751171
if (tr) {
11761172
tr->last_rc = rc;

0 commit comments

Comments
 (0)