diff options
| -rw-r--r-- | drivers/s390/crypto/ap_bus.h | 17 | ||||
| -rw-r--r-- | drivers/s390/crypto/zcrypt_api.c | 15 | ||||
| -rw-r--r-- | drivers/s390/crypto/zcrypt_msgtype6.c | 51 |
3 files changed, 43 insertions, 40 deletions
diff --git a/drivers/s390/crypto/ap_bus.h b/drivers/s390/crypto/ap_bus.h index 02184cf35834..6a273c5ebca5 100644 --- a/drivers/s390/crypto/ap_bus.h +++ b/drivers/s390/crypto/ap_bus.h | |||
| @@ -198,11 +198,18 @@ struct ap_message { | |||
| 198 | */ | 198 | */ |
| 199 | static inline void ap_init_message(struct ap_message *ap_msg) | 199 | static inline void ap_init_message(struct ap_message *ap_msg) |
| 200 | { | 200 | { |
| 201 | ap_msg->psmid = 0; | 201 | memset(ap_msg, 0, sizeof(*ap_msg)); |
| 202 | ap_msg->length = 0; | 202 | } |
| 203 | ap_msg->rc = 0; | 203 | |
| 204 | ap_msg->special = 0; | 204 | /** |
| 205 | ap_msg->receive = NULL; | 205 | * ap_release_message() - Release ap_message. |
| 206 | * Releases all memory used internal within the ap_message struct | ||
| 207 | * Currently this is the message and private field. | ||
| 208 | */ | ||
| 209 | static inline void ap_release_message(struct ap_message *ap_msg) | ||
| 210 | { | ||
| 211 | kzfree(ap_msg->message); | ||
| 212 | kzfree(ap_msg->private); | ||
| 206 | } | 213 | } |
| 207 | 214 | ||
| 208 | #define for_each_ap_card(_ac) \ | 215 | #define for_each_ap_card(_ac) \ |
diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c index 5efd84862ccb..febcdb5135bf 100644 --- a/drivers/s390/crypto/zcrypt_api.c +++ b/drivers/s390/crypto/zcrypt_api.c | |||
| @@ -371,6 +371,7 @@ long zcrypt_send_cprb(struct ica_xcRB *xcRB) | |||
| 371 | 371 | ||
| 372 | trace_s390_zcrypt_req(xcRB, TB_ZSECSENDCPRB); | 372 | trace_s390_zcrypt_req(xcRB, TB_ZSECSENDCPRB); |
| 373 | 373 | ||
| 374 | ap_init_message(&ap_msg); | ||
| 374 | rc = get_cprb_fc(xcRB, &ap_msg, &func_code, &domain); | 375 | rc = get_cprb_fc(xcRB, &ap_msg, &func_code, &domain); |
| 375 | if (rc) | 376 | if (rc) |
| 376 | goto out; | 377 | goto out; |
| @@ -425,6 +426,7 @@ long zcrypt_send_cprb(struct ica_xcRB *xcRB) | |||
| 425 | spin_unlock(&zcrypt_list_lock); | 426 | spin_unlock(&zcrypt_list_lock); |
| 426 | 427 | ||
| 427 | out: | 428 | out: |
| 429 | ap_release_message(&ap_msg); | ||
| 428 | trace_s390_zcrypt_rep(xcRB, func_code, rc, | 430 | trace_s390_zcrypt_rep(xcRB, func_code, rc, |
| 429 | AP_QID_CARD(qid), AP_QID_QUEUE(qid)); | 431 | AP_QID_CARD(qid), AP_QID_QUEUE(qid)); |
| 430 | return rc; | 432 | return rc; |
| @@ -468,6 +470,8 @@ static long zcrypt_send_ep11_cprb(struct ep11_urb *xcrb) | |||
| 468 | 470 | ||
| 469 | trace_s390_zcrypt_req(xcrb, TP_ZSENDEP11CPRB); | 471 | trace_s390_zcrypt_req(xcrb, TP_ZSENDEP11CPRB); |
| 470 | 472 | ||
| 473 | ap_init_message(&ap_msg); | ||
| 474 | |||
| 471 | target_num = (unsigned short) xcrb->targets_num; | 475 | target_num = (unsigned short) xcrb->targets_num; |
| 472 | 476 | ||
| 473 | /* empty list indicates autoselect (all available targets) */ | 477 | /* empty list indicates autoselect (all available targets) */ |
| @@ -485,7 +489,7 @@ static long zcrypt_send_ep11_cprb(struct ep11_urb *xcrb) | |||
| 485 | if (copy_from_user(targets, uptr, | 489 | if (copy_from_user(targets, uptr, |
| 486 | target_num * sizeof(*targets))) { | 490 | target_num * sizeof(*targets))) { |
| 487 | rc = -EFAULT; | 491 | rc = -EFAULT; |
| 488 | goto out; | 492 | goto out_free; |
| 489 | } | 493 | } |
| 490 | } | 494 | } |
| 491 | 495 | ||
| @@ -542,6 +546,7 @@ static long zcrypt_send_ep11_cprb(struct ep11_urb *xcrb) | |||
| 542 | out_free: | 546 | out_free: |
| 543 | kfree(targets); | 547 | kfree(targets); |
| 544 | out: | 548 | out: |
| 549 | ap_release_message(&ap_msg); | ||
| 545 | trace_s390_zcrypt_rep(xcrb, func_code, rc, | 550 | trace_s390_zcrypt_rep(xcrb, func_code, rc, |
| 546 | AP_QID_CARD(qid), AP_QID_QUEUE(qid)); | 551 | AP_QID_CARD(qid), AP_QID_QUEUE(qid)); |
| 547 | return rc; | 552 | return rc; |
| @@ -559,6 +564,7 @@ static long zcrypt_rng(char *buffer) | |||
| 559 | 564 | ||
| 560 | trace_s390_zcrypt_req(buffer, TP_HWRNGCPRB); | 565 | trace_s390_zcrypt_req(buffer, TP_HWRNGCPRB); |
| 561 | 566 | ||
| 567 | ap_init_message(&ap_msg); | ||
| 562 | rc = get_rng_fc(&ap_msg, &func_code, &domain); | 568 | rc = get_rng_fc(&ap_msg, &func_code, &domain); |
| 563 | if (rc) | 569 | if (rc) |
| 564 | goto out; | 570 | goto out; |
| @@ -589,8 +595,10 @@ static long zcrypt_rng(char *buffer) | |||
| 589 | pref_zq = zcrypt_pick_queue(pref_zc, pref_zq, weight); | 595 | pref_zq = zcrypt_pick_queue(pref_zc, pref_zq, weight); |
| 590 | spin_unlock(&zcrypt_list_lock); | 596 | spin_unlock(&zcrypt_list_lock); |
| 591 | 597 | ||
| 592 | if (!pref_zq) | 598 | if (!pref_zq) { |
| 593 | return -ENODEV; | 599 | rc = -ENODEV; |
| 600 | goto out; | ||
| 601 | } | ||
| 594 | 602 | ||
| 595 | qid = pref_zq->queue->qid; | 603 | qid = pref_zq->queue->qid; |
| 596 | rc = pref_zq->ops->rng(pref_zq, buffer, &ap_msg); | 604 | rc = pref_zq->ops->rng(pref_zq, buffer, &ap_msg); |
| @@ -600,6 +608,7 @@ static long zcrypt_rng(char *buffer) | |||
| 600 | spin_unlock(&zcrypt_list_lock); | 608 | spin_unlock(&zcrypt_list_lock); |
| 601 | 609 | ||
| 602 | out: | 610 | out: |
| 611 | ap_release_message(&ap_msg); | ||
| 603 | trace_s390_zcrypt_rep(buffer, func_code, rc, | 612 | trace_s390_zcrypt_rep(buffer, func_code, rc, |
| 604 | AP_QID_CARD(qid), AP_QID_QUEUE(qid)); | 613 | AP_QID_CARD(qid), AP_QID_QUEUE(qid)); |
| 605 | return rc; | 614 | return rc; |
diff --git a/drivers/s390/crypto/zcrypt_msgtype6.c b/drivers/s390/crypto/zcrypt_msgtype6.c index f54bef4a928e..97d4bacbc442 100644 --- a/drivers/s390/crypto/zcrypt_msgtype6.c +++ b/drivers/s390/crypto/zcrypt_msgtype6.c | |||
| @@ -1084,6 +1084,13 @@ out_free: | |||
| 1084 | return rc; | 1084 | return rc; |
| 1085 | } | 1085 | } |
| 1086 | 1086 | ||
| 1087 | /** | ||
| 1088 | * Fetch function code from cprb. | ||
| 1089 | * Extracting the fc requires to copy the cprb from userspace. | ||
| 1090 | * So this function allocates memory and needs an ap_msg prepared | ||
| 1091 | * by the caller with ap_init_message(). Also the caller has to | ||
| 1092 | * make sure ap_release_message() is always called even on failure. | ||
| 1093 | */ | ||
| 1087 | unsigned int get_cprb_fc(struct ica_xcRB *xcRB, | 1094 | unsigned int get_cprb_fc(struct ica_xcRB *xcRB, |
| 1088 | struct ap_message *ap_msg, | 1095 | struct ap_message *ap_msg, |
| 1089 | unsigned int *func_code, unsigned short **dom) | 1096 | unsigned int *func_code, unsigned short **dom) |
| @@ -1091,9 +1098,7 @@ unsigned int get_cprb_fc(struct ica_xcRB *xcRB, | |||
| 1091 | struct response_type resp_type = { | 1098 | struct response_type resp_type = { |
| 1092 | .type = PCIXCC_RESPONSE_TYPE_XCRB, | 1099 | .type = PCIXCC_RESPONSE_TYPE_XCRB, |
| 1093 | }; | 1100 | }; |
| 1094 | int rc; | ||
| 1095 | 1101 | ||
| 1096 | ap_init_message(ap_msg); | ||
| 1097 | ap_msg->message = kmalloc(MSGTYPE06_MAX_MSG_SIZE, GFP_KERNEL); | 1102 | ap_msg->message = kmalloc(MSGTYPE06_MAX_MSG_SIZE, GFP_KERNEL); |
| 1098 | if (!ap_msg->message) | 1103 | if (!ap_msg->message) |
| 1099 | return -ENOMEM; | 1104 | return -ENOMEM; |
| @@ -1101,17 +1106,10 @@ unsigned int get_cprb_fc(struct ica_xcRB *xcRB, | |||
| 1101 | ap_msg->psmid = (((unsigned long long) current->pid) << 32) + | 1106 | ap_msg->psmid = (((unsigned long long) current->pid) << 32) + |
| 1102 | atomic_inc_return(&zcrypt_step); | 1107 | atomic_inc_return(&zcrypt_step); |
| 1103 | ap_msg->private = kmalloc(sizeof(resp_type), GFP_KERNEL); | 1108 | ap_msg->private = kmalloc(sizeof(resp_type), GFP_KERNEL); |
| 1104 | if (!ap_msg->private) { | 1109 | if (!ap_msg->private) |
| 1105 | kzfree(ap_msg->message); | ||
| 1106 | return -ENOMEM; | 1110 | return -ENOMEM; |
| 1107 | } | ||
| 1108 | memcpy(ap_msg->private, &resp_type, sizeof(resp_type)); | 1111 | memcpy(ap_msg->private, &resp_type, sizeof(resp_type)); |
| 1109 | rc = XCRB_msg_to_type6CPRB_msgX(ap_msg, xcRB, func_code, dom); | 1112 | return XCRB_msg_to_type6CPRB_msgX(ap_msg, xcRB, func_code, dom); |
| 1110 | if (rc) { | ||
| 1111 | kzfree(ap_msg->message); | ||
| 1112 | kzfree(ap_msg->private); | ||
| 1113 | } | ||
| 1114 | return rc; | ||
| 1115 | } | 1113 | } |
| 1116 | 1114 | ||
| 1117 | /** | 1115 | /** |
| @@ -1139,11 +1137,16 @@ static long zcrypt_msgtype6_send_cprb(struct zcrypt_queue *zq, | |||
| 1139 | /* Signal pending. */ | 1137 | /* Signal pending. */ |
| 1140 | ap_cancel_message(zq->queue, ap_msg); | 1138 | ap_cancel_message(zq->queue, ap_msg); |
| 1141 | 1139 | ||
| 1142 | kzfree(ap_msg->message); | ||
| 1143 | kzfree(ap_msg->private); | ||
| 1144 | return rc; | 1140 | return rc; |
| 1145 | } | 1141 | } |
| 1146 | 1142 | ||
| 1143 | /** | ||
| 1144 | * Fetch function code from ep11 cprb. | ||
| 1145 | * Extracting the fc requires to copy the ep11 cprb from userspace. | ||
| 1146 | * So 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. | ||
| 1149 | */ | ||
| 1147 | unsigned int get_ep11cprb_fc(struct ep11_urb *xcrb, | 1150 | unsigned int get_ep11cprb_fc(struct ep11_urb *xcrb, |
| 1148 | struct ap_message *ap_msg, | 1151 | struct ap_message *ap_msg, |
| 1149 | unsigned int *func_code) | 1152 | unsigned int *func_code) |
| @@ -1151,9 +1154,7 @@ unsigned int get_ep11cprb_fc(struct ep11_urb *xcrb, | |||
| 1151 | struct response_type resp_type = { | 1154 | struct response_type resp_type = { |
| 1152 | .type = PCIXCC_RESPONSE_TYPE_EP11, | 1155 | .type = PCIXCC_RESPONSE_TYPE_EP11, |
| 1153 | }; | 1156 | }; |
| 1154 | int rc; | ||
| 1155 | 1157 | ||
| 1156 | ap_init_message(ap_msg); | ||
| 1157 | ap_msg->message = kmalloc(MSGTYPE06_MAX_MSG_SIZE, GFP_KERNEL); | 1158 | ap_msg->message = kmalloc(MSGTYPE06_MAX_MSG_SIZE, GFP_KERNEL); |
| 1158 | if (!ap_msg->message) | 1159 | if (!ap_msg->message) |
| 1159 | return -ENOMEM; | 1160 | return -ENOMEM; |
| @@ -1161,17 +1162,10 @@ unsigned int get_ep11cprb_fc(struct ep11_urb *xcrb, | |||
| 1161 | ap_msg->psmid = (((unsigned long long) current->pid) << 32) + | 1162 | ap_msg->psmid = (((unsigned long long) current->pid) << 32) + |
| 1162 | atomic_inc_return(&zcrypt_step); | 1163 | atomic_inc_return(&zcrypt_step); |
| 1163 | ap_msg->private = kmalloc(sizeof(resp_type), GFP_KERNEL); | 1164 | ap_msg->private = kmalloc(sizeof(resp_type), GFP_KERNEL); |
| 1164 | if (!ap_msg->private) { | 1165 | if (!ap_msg->private) |
| 1165 | kzfree(ap_msg->message); | ||
| 1166 | return -ENOMEM; | 1166 | return -ENOMEM; |
| 1167 | } | ||
| 1168 | memcpy(ap_msg->private, &resp_type, sizeof(resp_type)); | 1167 | memcpy(ap_msg->private, &resp_type, sizeof(resp_type)); |
| 1169 | rc = xcrb_msg_to_type6_ep11cprb_msgx(ap_msg, xcrb, func_code); | 1168 | return xcrb_msg_to_type6_ep11cprb_msgx(ap_msg, xcrb, func_code); |
| 1170 | if (rc) { | ||
| 1171 | kzfree(ap_msg->message); | ||
| 1172 | kzfree(ap_msg->private); | ||
| 1173 | } | ||
| 1174 | return rc; | ||
| 1175 | } | 1169 | } |
| 1176 | 1170 | ||
| 1177 | /** | 1171 | /** |
| @@ -1246,8 +1240,6 @@ static long zcrypt_msgtype6_send_ep11_cprb(struct zcrypt_queue *zq, | |||
| 1246 | /* Signal pending. */ | 1240 | /* Signal pending. */ |
| 1247 | ap_cancel_message(zq->queue, ap_msg); | 1241 | ap_cancel_message(zq->queue, ap_msg); |
| 1248 | 1242 | ||
| 1249 | kzfree(ap_msg->message); | ||
| 1250 | kzfree(ap_msg->private); | ||
| 1251 | return rc; | 1243 | return rc; |
| 1252 | } | 1244 | } |
| 1253 | 1245 | ||
| @@ -1258,7 +1250,6 @@ unsigned int get_rng_fc(struct ap_message *ap_msg, int *func_code, | |||
| 1258 | .type = PCIXCC_RESPONSE_TYPE_XCRB, | 1250 | .type = PCIXCC_RESPONSE_TYPE_XCRB, |
| 1259 | }; | 1251 | }; |
| 1260 | 1252 | ||
| 1261 | ap_init_message(ap_msg); | ||
| 1262 | ap_msg->message = kmalloc(MSGTYPE06_MAX_MSG_SIZE, GFP_KERNEL); | 1253 | ap_msg->message = kmalloc(MSGTYPE06_MAX_MSG_SIZE, GFP_KERNEL); |
| 1263 | if (!ap_msg->message) | 1254 | if (!ap_msg->message) |
| 1264 | return -ENOMEM; | 1255 | return -ENOMEM; |
| @@ -1266,10 +1257,8 @@ unsigned int get_rng_fc(struct ap_message *ap_msg, int *func_code, | |||
| 1266 | ap_msg->psmid = (((unsigned long long) current->pid) << 32) + | 1257 | ap_msg->psmid = (((unsigned long long) current->pid) << 32) + |
| 1267 | atomic_inc_return(&zcrypt_step); | 1258 | atomic_inc_return(&zcrypt_step); |
| 1268 | ap_msg->private = kmalloc(sizeof(resp_type), GFP_KERNEL); | 1259 | ap_msg->private = kmalloc(sizeof(resp_type), GFP_KERNEL); |
| 1269 | if (!ap_msg->private) { | 1260 | if (!ap_msg->private) |
| 1270 | kzfree(ap_msg->message); | ||
| 1271 | return -ENOMEM; | 1261 | return -ENOMEM; |
| 1272 | } | ||
| 1273 | memcpy(ap_msg->private, &resp_type, sizeof(resp_type)); | 1262 | memcpy(ap_msg->private, &resp_type, sizeof(resp_type)); |
| 1274 | 1263 | ||
| 1275 | rng_type6CPRB_msgX(ap_msg, ZCRYPT_RNG_BUFFER_SIZE, domain); | 1264 | rng_type6CPRB_msgX(ap_msg, ZCRYPT_RNG_BUFFER_SIZE, domain); |
| @@ -1313,8 +1302,6 @@ static long zcrypt_msgtype6_rng(struct zcrypt_queue *zq, | |||
| 1313 | /* Signal pending. */ | 1302 | /* Signal pending. */ |
| 1314 | ap_cancel_message(zq->queue, ap_msg); | 1303 | ap_cancel_message(zq->queue, ap_msg); |
| 1315 | 1304 | ||
| 1316 | kzfree(ap_msg->message); | ||
| 1317 | kzfree(ap_msg->private); | ||
| 1318 | return rc; | 1305 | return rc; |
| 1319 | } | 1306 | } |
| 1320 | 1307 | ||
