diff options
Diffstat (limited to 'drivers/s390/crypto/zcrypt_api.c')
| -rw-r--r-- | drivers/s390/crypto/zcrypt_api.c | 34 | 
1 files changed, 22 insertions, 12 deletions
| diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c index eb93c2d27d0a..c31b2d31cd83 100644 --- a/drivers/s390/crypto/zcrypt_api.c +++ b/drivers/s390/crypto/zcrypt_api.c @@ -586,6 +586,7 @@ static inline bool zcrypt_check_queue(struct ap_perms *perms, int queue)  static inline struct zcrypt_queue *zcrypt_pick_queue(struct zcrypt_card *zc,  						     struct zcrypt_queue *zq, +						     struct module **pmod,  						     unsigned int weight)  {  	if (!zq || !try_module_get(zq->queue->ap_dev.drv->driver.owner)) @@ -595,15 +596,15 @@ static inline struct zcrypt_queue *zcrypt_pick_queue(struct zcrypt_card *zc,  	atomic_add(weight, &zc->load);  	atomic_add(weight, &zq->load);  	zq->request_count++; +	*pmod = zq->queue->ap_dev.drv->driver.owner;  	return zq;  }  static inline void zcrypt_drop_queue(struct zcrypt_card *zc,  				     struct zcrypt_queue *zq, +				     struct module *mod,  				     unsigned int weight)  { -	struct module *mod = zq->queue->ap_dev.drv->driver.owner; -  	zq->request_count--;  	atomic_sub(weight, &zc->load);  	atomic_sub(weight, &zq->load); @@ -653,10 +654,12 @@ static long zcrypt_rsa_modexpo(struct ap_perms *perms,  	unsigned int weight, pref_weight;  	unsigned int func_code;  	int qid = 0, rc = -ENODEV; +	struct module *mod;  	trace_s390_zcrypt_req(mex, TP_ICARSAMODEXPO);  	if (mex->outputdatalength < mex->inputdatalength) { +		func_code = 0;  		rc = -EINVAL;  		goto out;  	} @@ -706,7 +709,7 @@ static long zcrypt_rsa_modexpo(struct ap_perms *perms,  			pref_weight = weight;  		}  	} -	pref_zq = zcrypt_pick_queue(pref_zc, pref_zq, weight); +	pref_zq = zcrypt_pick_queue(pref_zc, pref_zq, &mod, weight);  	spin_unlock(&zcrypt_list_lock);  	if (!pref_zq) { @@ -718,7 +721,7 @@ static long zcrypt_rsa_modexpo(struct ap_perms *perms,  	rc = pref_zq->ops->rsa_modexpo(pref_zq, mex);  	spin_lock(&zcrypt_list_lock); -	zcrypt_drop_queue(pref_zc, pref_zq, weight); +	zcrypt_drop_queue(pref_zc, pref_zq, mod, weight);  	spin_unlock(&zcrypt_list_lock);  out: @@ -735,10 +738,12 @@ static long zcrypt_rsa_crt(struct ap_perms *perms,  	unsigned int weight, pref_weight;  	unsigned int func_code;  	int qid = 0, rc = -ENODEV; +	struct module *mod;  	trace_s390_zcrypt_req(crt, TP_ICARSACRT);  	if (crt->outputdatalength < crt->inputdatalength) { +		func_code = 0;  		rc = -EINVAL;  		goto out;  	} @@ -788,7 +793,7 @@ static long zcrypt_rsa_crt(struct ap_perms *perms,  			pref_weight = weight;  		}  	} -	pref_zq = zcrypt_pick_queue(pref_zc, pref_zq, weight); +	pref_zq = zcrypt_pick_queue(pref_zc, pref_zq, &mod, weight);  	spin_unlock(&zcrypt_list_lock);  	if (!pref_zq) { @@ -800,7 +805,7 @@ static long zcrypt_rsa_crt(struct ap_perms *perms,  	rc = pref_zq->ops->rsa_modexpo_crt(pref_zq, crt);  	spin_lock(&zcrypt_list_lock); -	zcrypt_drop_queue(pref_zc, pref_zq, weight); +	zcrypt_drop_queue(pref_zc, pref_zq, mod, weight);  	spin_unlock(&zcrypt_list_lock);  out: @@ -819,6 +824,7 @@ static long _zcrypt_send_cprb(struct ap_perms *perms,  	unsigned int func_code;  	unsigned short *domain;  	int qid = 0, rc = -ENODEV; +	struct module *mod;  	trace_s390_zcrypt_req(xcRB, TB_ZSECSENDCPRB); @@ -865,7 +871,7 @@ static long _zcrypt_send_cprb(struct ap_perms *perms,  			pref_weight = weight;  		}  	} -	pref_zq = zcrypt_pick_queue(pref_zc, pref_zq, weight); +	pref_zq = zcrypt_pick_queue(pref_zc, pref_zq, &mod, weight);  	spin_unlock(&zcrypt_list_lock);  	if (!pref_zq) { @@ -881,7 +887,7 @@ static long _zcrypt_send_cprb(struct ap_perms *perms,  	rc = pref_zq->ops->send_cprb(pref_zq, xcRB, &ap_msg);  	spin_lock(&zcrypt_list_lock); -	zcrypt_drop_queue(pref_zc, pref_zq, weight); +	zcrypt_drop_queue(pref_zc, pref_zq, mod, weight);  	spin_unlock(&zcrypt_list_lock);  out: @@ -932,6 +938,7 @@ static long zcrypt_send_ep11_cprb(struct ap_perms *perms,  	unsigned int func_code;  	struct ap_message ap_msg;  	int qid = 0, rc = -ENODEV; +	struct module *mod;  	trace_s390_zcrypt_req(xcrb, TP_ZSENDEP11CPRB); @@ -946,6 +953,7 @@ static long zcrypt_send_ep11_cprb(struct ap_perms *perms,  		targets = kcalloc(target_num, sizeof(*targets), GFP_KERNEL);  		if (!targets) { +			func_code = 0;  			rc = -ENOMEM;  			goto out;  		} @@ -953,6 +961,7 @@ static long zcrypt_send_ep11_cprb(struct ap_perms *perms,  		uptr = (struct ep11_target_dev __force __user *) xcrb->targets;  		if (copy_from_user(targets, uptr,  				   target_num * sizeof(*targets))) { +			func_code = 0;  			rc = -EFAULT;  			goto out_free;  		} @@ -1000,7 +1009,7 @@ static long zcrypt_send_ep11_cprb(struct ap_perms *perms,  			pref_weight = weight;  		}  	} -	pref_zq = zcrypt_pick_queue(pref_zc, pref_zq, weight); +	pref_zq = zcrypt_pick_queue(pref_zc, pref_zq, &mod, weight);  	spin_unlock(&zcrypt_list_lock);  	if (!pref_zq) { @@ -1012,7 +1021,7 @@ static long zcrypt_send_ep11_cprb(struct ap_perms *perms,  	rc = pref_zq->ops->send_ep11_cprb(pref_zq, xcrb, &ap_msg);  	spin_lock(&zcrypt_list_lock); -	zcrypt_drop_queue(pref_zc, pref_zq, weight); +	zcrypt_drop_queue(pref_zc, pref_zq, mod, weight);  	spin_unlock(&zcrypt_list_lock);  out_free: @@ -1033,6 +1042,7 @@ static long zcrypt_rng(char *buffer)  	struct ap_message ap_msg;  	unsigned int domain;  	int qid = 0, rc = -ENODEV; +	struct module *mod;  	trace_s390_zcrypt_req(buffer, TP_HWRNGCPRB); @@ -1064,7 +1074,7 @@ static long zcrypt_rng(char *buffer)  			pref_weight = weight;  		}  	} -	pref_zq = zcrypt_pick_queue(pref_zc, pref_zq, weight); +	pref_zq = zcrypt_pick_queue(pref_zc, pref_zq, &mod, weight);  	spin_unlock(&zcrypt_list_lock);  	if (!pref_zq) { @@ -1076,7 +1086,7 @@ static long zcrypt_rng(char *buffer)  	rc = pref_zq->ops->rng(pref_zq, buffer, &ap_msg);  	spin_lock(&zcrypt_list_lock); -	zcrypt_drop_queue(pref_zc, pref_zq, weight); +	zcrypt_drop_queue(pref_zc, pref_zq, mod, weight);  	spin_unlock(&zcrypt_list_lock);  out: | 
