Skip to content

Commit 57db62a

Browse files
hfreudehcahca
authored andcommitted
s390/ap/zcrypt: Rework AP message buffer allocation
Slight rework on the way how AP message buffers are allocated. Instead of having multiple places with kmalloc() calls all the AP message buffers are now allocated and freed on exactly one place: ap_init_apmsg() allocates the current AP bus max limit of ap_max_msg_size (defaults to 12KB). The AP message buffer is then freed in ap_release_apmsg(). 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-3-freude@linux.ibm.com Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
1 parent 4343549 commit 57db62a

5 files changed

Lines changed: 87 additions & 66 deletions

File tree

drivers/s390/crypto/ap_bus.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,32 @@ static void ap_poll_thread_stop(void)
547547
#define is_card_dev(x) ((x)->parent == ap_root_device)
548548
#define is_queue_dev(x) ((x)->parent != ap_root_device)
549549

550+
/*
551+
* ap_init_apmsg() - Initialize ap_message.
552+
*/
553+
int ap_init_apmsg(struct ap_message *ap_msg)
554+
{
555+
unsigned int maxmsgsize = atomic_read(&ap_max_msg_size);
556+
557+
memset(ap_msg, 0, sizeof(*ap_msg));
558+
ap_msg->msg = kmalloc(maxmsgsize, GFP_KERNEL);
559+
if (!ap_msg->msg)
560+
return -ENOMEM;
561+
ap_msg->bufsize = maxmsgsize;
562+
563+
return 0;
564+
}
565+
EXPORT_SYMBOL(ap_init_apmsg);
566+
567+
/*
568+
* ap_release_apmsg() - Release ap_message.
569+
*/
570+
void ap_release_apmsg(struct ap_message *ap_msg)
571+
{
572+
kfree_sensitive(ap_msg->msg);
573+
}
574+
EXPORT_SYMBOL(ap_release_apmsg);
575+
550576
/**
551577
* ap_bus_match()
552578
* @dev: Pointer to device

drivers/s390/crypto/ap_bus.h

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -237,25 +237,8 @@ struct ap_message {
237237
#define AP_MSG_FLAG_USAGE 0x0002 /* CCA, EP11: usage (no admin) msg */
238238
#define AP_MSG_FLAG_ADMIN 0x0004 /* CCA, EP11: admin (=control) msg */
239239

240-
/**
241-
* ap_init_message() - Initialize ap_message.
242-
* Initialize a message before using. Otherwise this might result in
243-
* unexpected behaviour.
244-
*/
245-
static inline void ap_init_message(struct ap_message *ap_msg)
246-
{
247-
memset(ap_msg, 0, sizeof(*ap_msg));
248-
}
249-
250-
/**
251-
* ap_release_message() - Release ap_message.
252-
* Releases all memory used internal within the ap_message struct
253-
* Currently this is the message and private field.
254-
*/
255-
static inline void ap_release_message(struct ap_message *ap_msg)
256-
{
257-
kfree_sensitive(ap_msg->msg);
258-
}
240+
int ap_init_apmsg(struct ap_message *ap_msg);
241+
void ap_release_apmsg(struct ap_message *ap_msg);
259242

260243
enum ap_sm_wait ap_sm_event(struct ap_queue *aq, enum ap_sm_event event);
261244
enum ap_sm_wait ap_sm_event_loop(struct ap_queue *aq, enum ap_sm_event event);

drivers/s390/crypto/zcrypt_api.c

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -642,16 +642,17 @@ static long zcrypt_rsa_modexpo(struct ap_perms *perms,
642642
struct zcrypt_queue *zq, *pref_zq;
643643
struct ap_message ap_msg;
644644
unsigned int wgt = 0, pref_wgt = 0;
645-
unsigned int func_code;
646-
int cpen, qpen, qid = 0, rc = -ENODEV;
645+
unsigned int func_code = 0;
646+
int cpen, qpen, qid = 0, rc;
647647
struct module *mod;
648648

649649
trace_s390_zcrypt_req(mex, TP_ICARSAMODEXPO);
650650

651-
ap_init_message(&ap_msg);
651+
rc = ap_init_apmsg(&ap_msg);
652+
if (rc)
653+
goto out;
652654

653655
if (mex->outputdatalength < mex->inputdatalength) {
654-
func_code = 0;
655656
rc = -EINVAL;
656657
goto out;
657658
}
@@ -728,7 +729,7 @@ static long zcrypt_rsa_modexpo(struct ap_perms *perms,
728729
spin_unlock(&zcrypt_list_lock);
729730

730731
out:
731-
ap_release_message(&ap_msg);
732+
ap_release_apmsg(&ap_msg);
732733
if (tr) {
733734
tr->last_rc = rc;
734735
tr->last_qid = qid;
@@ -746,16 +747,17 @@ static long zcrypt_rsa_crt(struct ap_perms *perms,
746747
struct zcrypt_queue *zq, *pref_zq;
747748
struct ap_message ap_msg;
748749
unsigned int wgt = 0, pref_wgt = 0;
749-
unsigned int func_code;
750-
int cpen, qpen, qid = 0, rc = -ENODEV;
750+
unsigned int func_code = 0;
751+
int cpen, qpen, qid = 0, rc;
751752
struct module *mod;
752753

753754
trace_s390_zcrypt_req(crt, TP_ICARSACRT);
754755

755-
ap_init_message(&ap_msg);
756+
rc = ap_init_apmsg(&ap_msg);
757+
if (rc)
758+
goto out;
756759

757760
if (crt->outputdatalength < crt->inputdatalength) {
758-
func_code = 0;
759761
rc = -EINVAL;
760762
goto out;
761763
}
@@ -832,7 +834,7 @@ static long zcrypt_rsa_crt(struct ap_perms *perms,
832834
spin_unlock(&zcrypt_list_lock);
833835

834836
out:
835-
ap_release_message(&ap_msg);
837+
ap_release_apmsg(&ap_msg);
836838
if (tr) {
837839
tr->last_rc = rc;
838840
tr->last_qid = qid;
@@ -850,15 +852,18 @@ static long _zcrypt_send_cprb(bool userspace, struct ap_perms *perms,
850852
struct zcrypt_queue *zq, *pref_zq;
851853
struct ap_message ap_msg;
852854
unsigned int wgt = 0, pref_wgt = 0;
853-
unsigned int func_code;
855+
unsigned int func_code = 0;
854856
unsigned short *domain, tdom;
855-
int cpen, qpen, qid = 0, rc = -ENODEV;
857+
int cpen, qpen, qid = 0, rc;
856858
struct module *mod;
857859

858860
trace_s390_zcrypt_req(xcrb, TB_ZSECSENDCPRB);
859861

860862
xcrb->status = 0;
861-
ap_init_message(&ap_msg);
863+
864+
rc = ap_init_apmsg(&ap_msg);
865+
if (rc)
866+
goto out;
862867

863868
rc = prep_cca_ap_msg(userspace, xcrb, &ap_msg, &func_code, &domain);
864869
if (rc)
@@ -962,7 +967,7 @@ static long _zcrypt_send_cprb(bool userspace, struct ap_perms *perms,
962967
spin_unlock(&zcrypt_list_lock);
963968

964969
out:
965-
ap_release_message(&ap_msg);
970+
ap_release_apmsg(&ap_msg);
966971
if (tr) {
967972
tr->last_rc = rc;
968973
tr->last_qid = qid;
@@ -1033,14 +1038,16 @@ static long _zcrypt_send_ep11_cprb(bool userspace, struct ap_perms *perms,
10331038
struct ep11_target_dev *targets;
10341039
unsigned short target_num;
10351040
unsigned int wgt = 0, pref_wgt = 0;
1036-
unsigned int func_code, domain;
1041+
unsigned int func_code = 0, domain;
10371042
struct ap_message ap_msg;
1038-
int cpen, qpen, qid = 0, rc = -ENODEV;
1043+
int cpen, qpen, qid = 0, rc;
10391044
struct module *mod;
10401045

10411046
trace_s390_zcrypt_req(xcrb, TP_ZSENDEP11CPRB);
10421047

1043-
ap_init_message(&ap_msg);
1048+
rc = ap_init_apmsg(&ap_msg);
1049+
if (rc)
1050+
goto out;
10441051

10451052
target_num = (unsigned short)xcrb->targets_num;
10461053

@@ -1164,7 +1171,7 @@ static long _zcrypt_send_ep11_cprb(bool userspace, struct ap_perms *perms,
11641171
out_free:
11651172
kfree(targets);
11661173
out:
1167-
ap_release_message(&ap_msg);
1174+
ap_release_apmsg(&ap_msg);
11681175
if (tr) {
11691176
tr->last_rc = rc;
11701177
tr->last_qid = qid;
@@ -1204,15 +1211,17 @@ static long zcrypt_rng(char *buffer)
12041211
struct zcrypt_card *zc, *pref_zc;
12051212
struct zcrypt_queue *zq, *pref_zq;
12061213
unsigned int wgt = 0, pref_wgt = 0;
1207-
unsigned int func_code;
1214+
unsigned int func_code = 0;
12081215
struct ap_message ap_msg;
12091216
unsigned int domain;
12101217
int qid = 0, rc = -ENODEV;
12111218
struct module *mod;
12121219

12131220
trace_s390_zcrypt_req(buffer, TP_HWRNGCPRB);
12141221

1215-
ap_init_message(&ap_msg);
1222+
rc = ap_init_apmsg(&ap_msg);
1223+
if (rc)
1224+
goto out;
12161225
rc = prep_rng_ap_msg(&ap_msg, &func_code, &domain);
12171226
if (rc)
12181227
goto out;
@@ -1258,7 +1267,7 @@ static long zcrypt_rng(char *buffer)
12581267
spin_unlock(&zcrypt_list_lock);
12591268

12601269
out:
1261-
ap_release_message(&ap_msg);
1270+
ap_release_apmsg(&ap_msg);
12621271
trace_s390_zcrypt_rep(buffer, func_code, rc,
12631272
AP_QID_CARD(qid), AP_QID_QUEUE(qid));
12641273
return rc;

drivers/s390/crypto/zcrypt_msgtype50.c

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -449,17 +449,19 @@ static atomic_t zcrypt_step = ATOMIC_INIT(0);
449449
* @zq: pointer to zcrypt_queue structure that identifies the
450450
* CEXxA device to the request distributor
451451
* @mex: pointer to the modexpo request buffer
452+
* This function assumes that ap_msg has been initialized with
453+
* ap_init_apmsg() and thus a valid buffer with the size of
454+
* ap_msg->bufsize is available within ap_msg. Also the caller has
455+
* to make sure ap_release_apmsg() is always called even on failure.
452456
*/
453457
static long zcrypt_msgtype50_modexpo(struct zcrypt_queue *zq,
454458
struct ica_rsa_modexpo *mex,
455459
struct ap_message *ap_msg)
456460
{
457461
int rc;
458462

459-
ap_msg->bufsize = MSGTYPE50_CRB3_MAX_MSG_SIZE;
460-
ap_msg->msg = kmalloc(ap_msg->bufsize, GFP_KERNEL);
461-
if (!ap_msg->msg)
462-
return -ENOMEM;
463+
if (ap_msg->bufsize < MSGTYPE50_CRB3_MAX_MSG_SIZE)
464+
return -EMSGSIZE;
463465
ap_msg->receive = zcrypt_msgtype50_receive;
464466
ap_msg->psmid = (((unsigned long)current->pid) << 32) +
465467
atomic_inc_return(&zcrypt_step);
@@ -496,17 +498,19 @@ static long zcrypt_msgtype50_modexpo(struct zcrypt_queue *zq,
496498
* @zq: pointer to zcrypt_queue structure that identifies the
497499
* CEXxA device to the request distributor
498500
* @crt: pointer to the modexpoc_crt request buffer
501+
* This function assumes that ap_msg has been initialized with
502+
* ap_init_apmsg() and thus a valid buffer with the size of
503+
* ap_msg->bufsize is available within ap_msg. Also the caller has
504+
* to make sure ap_release_apmsg() is always called even on failure.
499505
*/
500506
static long zcrypt_msgtype50_modexpo_crt(struct zcrypt_queue *zq,
501507
struct ica_rsa_modexpo_crt *crt,
502508
struct ap_message *ap_msg)
503509
{
504510
int rc;
505511

506-
ap_msg->bufsize = MSGTYPE50_CRB3_MAX_MSG_SIZE;
507-
ap_msg->msg = kmalloc(ap_msg->bufsize, GFP_KERNEL);
508-
if (!ap_msg->msg)
509-
return -ENOMEM;
512+
if (ap_msg->bufsize < MSGTYPE50_CRB3_MAX_MSG_SIZE)
513+
return -EMSGSIZE;
510514
ap_msg->receive = zcrypt_msgtype50_receive;
511515
ap_msg->psmid = (((unsigned long)current->pid) << 32) +
512516
atomic_inc_return(&zcrypt_step);

drivers/s390/crypto/zcrypt_msgtype6.c

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1050,20 +1050,17 @@ static long zcrypt_msgtype6_modexpo_crt(struct zcrypt_queue *zq,
10501050
* Prepare a CCA AP msg: fetch the required data from userspace,
10511051
* prepare the AP msg, fill some info into the ap_message struct,
10521052
* extract some data from the CPRB and give back to the caller.
1053-
* This function allocates memory and needs an ap_msg prepared
1054-
* by the caller with ap_init_message(). Also the caller has to
1055-
* make sure ap_release_message() is always called even on failure.
1053+
* This function assumes that ap_msg has been initialized with
1054+
* ap_init_apmsg() and thus a valid buffer with the size of
1055+
* ap_msg->bufsize is available within ap_msg. Also the caller has
1056+
* to make sure ap_release_apmsg() is always called even on failure.
10561057
*/
10571058
int prep_cca_ap_msg(bool userspace, struct ica_xcRB *xcrb,
10581059
struct ap_message *ap_msg,
10591060
unsigned int *func_code, unsigned short **dom)
10601061
{
10611062
struct ap_response_type *resp_type = &ap_msg->response;
10621063

1063-
ap_msg->bufsize = atomic_read(&ap_max_msg_size);
1064-
ap_msg->msg = kmalloc(ap_msg->bufsize, GFP_KERNEL);
1065-
if (!ap_msg->msg)
1066-
return -ENOMEM;
10671064
ap_msg->receive = zcrypt_msgtype6_receive;
10681065
ap_msg->psmid = (((unsigned long)current->pid) << 32) +
10691066
atomic_inc_return(&zcrypt_step);
@@ -1143,20 +1140,17 @@ static long zcrypt_msgtype6_send_cprb(bool userspace, struct zcrypt_queue *zq,
11431140
* Prepare an EP11 AP msg: fetch the required data from userspace,
11441141
* prepare the AP msg, fill some info into the ap_message struct,
11451142
* extract some data from the CPRB and give back to the caller.
1146-
* This function allocates memory and needs an ap_msg prepared
1147-
* by the caller with ap_init_message(). Also the caller has to
1148-
* make sure ap_release_message() is always called even on failure.
1143+
* This function assumes that ap_msg has been initialized with
1144+
* ap_init_apmsg() and thus a valid buffer with the size of
1145+
* ap_msg->bufsize is available within ap_msg. Also the caller has
1146+
* to make sure ap_release_apmsg() is always called even on failure.
11491147
*/
11501148
int prep_ep11_ap_msg(bool userspace, struct ep11_urb *xcrb,
11511149
struct ap_message *ap_msg,
11521150
unsigned int *func_code, unsigned int *domain)
11531151
{
11541152
struct ap_response_type *resp_type = &ap_msg->response;
11551153

1156-
ap_msg->bufsize = atomic_read(&ap_max_msg_size);
1157-
ap_msg->msg = kmalloc(ap_msg->bufsize, GFP_KERNEL);
1158-
if (!ap_msg->msg)
1159-
return -ENOMEM;
11601154
ap_msg->receive = zcrypt_msgtype6_receive_ep11;
11611155
ap_msg->psmid = (((unsigned long)current->pid) << 32) +
11621156
atomic_inc_return(&zcrypt_step);
@@ -1257,15 +1251,20 @@ static long zcrypt_msgtype6_send_ep11_cprb(bool userspace, struct zcrypt_queue *
12571251
return rc;
12581252
}
12591253

1254+
/*
1255+
* Prepare a CEXXC get random request ap message.
1256+
* This function assumes that ap_msg has been initialized with
1257+
* ap_init_apmsg() and thus a valid buffer with the size of
1258+
* ap_max_msg_size is available within ap_msg. Also the caller has
1259+
* to make sure ap_release_apmsg() is always called even on failure.
1260+
*/
12601261
int prep_rng_ap_msg(struct ap_message *ap_msg, int *func_code,
12611262
unsigned int *domain)
12621263
{
12631264
struct ap_response_type *resp_type = &ap_msg->response;
12641265

1265-
ap_msg->bufsize = AP_DEFAULT_MAX_MSG_SIZE;
1266-
ap_msg->msg = kmalloc(ap_msg->bufsize, GFP_KERNEL);
1267-
if (!ap_msg->msg)
1268-
return -ENOMEM;
1266+
if (ap_msg->bufsize < AP_DEFAULT_MAX_MSG_SIZE)
1267+
return -EMSGSIZE;
12691268
ap_msg->receive = zcrypt_msgtype6_receive;
12701269
ap_msg->psmid = (((unsigned long)current->pid) << 32) +
12711270
atomic_inc_return(&zcrypt_step);

0 commit comments

Comments
 (0)