diff options
| author | Jani Nikula <jani.nikula@intel.com> | 2025-06-09 12:40:46 +0300 | 
|---|---|---|
| committer | Jani Nikula <jani.nikula@intel.com> | 2025-06-09 12:40:46 +0300 | 
| commit | 34c55367af96f62e89221444f04487440ebc6487 (patch) | |
| tree | fdb36ba67d7dea09455b55037e26043b7e051ef9 /drivers/s390/crypto/zcrypt_api.c | |
| parent | 7247efca0dcbc8ac6147db9200ed1549c0662465 (diff) | |
| parent | 19272b37aa4f83ca52bdf9c16d5d81bdd1354494 (diff) | |
| download | linux-34c55367af96f62e89221444f04487440ebc6487.tar.xz | |
Merge drm/drm-next into drm-intel-next
Sync to v6.16-rc1, among other things to get the fixed size GENMASK_U*()
and BIT_U*() macros.
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Diffstat (limited to 'drivers/s390/crypto/zcrypt_api.c')
| -rw-r--r-- | drivers/s390/crypto/zcrypt_api.c | 167 | 
1 files changed, 105 insertions, 62 deletions
diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c index 5020696f1379..89baa87a13fc 100644 --- a/drivers/s390/crypto/zcrypt_api.c +++ b/drivers/s390/crypto/zcrypt_api.c @@ -50,6 +50,10 @@ MODULE_DESCRIPTION("Cryptographic Coprocessor interface, " \  		   "Copyright IBM Corp. 2001, 2012");  MODULE_LICENSE("GPL"); +unsigned int zcrypt_mempool_threshold = 5; +module_param_named(mempool_threshold, zcrypt_mempool_threshold, uint, 0440); +MODULE_PARM_DESC(mempool_threshold, "CCA and EP11 request/reply mempool minimal items (min: 1)"); +  /*   * zcrypt tracepoint functions   */ @@ -642,16 +646,17 @@ static long zcrypt_rsa_modexpo(struct ap_perms *perms,  	struct zcrypt_queue *zq, *pref_zq;  	struct ap_message ap_msg;  	unsigned int wgt = 0, pref_wgt = 0; -	unsigned int func_code; -	int cpen, qpen, qid = 0, rc = -ENODEV; +	unsigned int func_code = 0; +	int cpen, qpen, qid = 0, rc;  	struct module *mod;  	trace_s390_zcrypt_req(mex, TP_ICARSAMODEXPO); -	ap_init_message(&ap_msg); +	rc = ap_init_apmsg(&ap_msg, 0); +	if (rc) +		goto out;  	if (mex->outputdatalength < mex->inputdatalength) { -		func_code = 0;  		rc = -EINVAL;  		goto out;  	} @@ -728,7 +733,7 @@ static long zcrypt_rsa_modexpo(struct ap_perms *perms,  	spin_unlock(&zcrypt_list_lock);  out: -	ap_release_message(&ap_msg); +	ap_release_apmsg(&ap_msg);  	if (tr) {  		tr->last_rc = rc;  		tr->last_qid = qid; @@ -746,16 +751,17 @@ static long zcrypt_rsa_crt(struct ap_perms *perms,  	struct zcrypt_queue *zq, *pref_zq;  	struct ap_message ap_msg;  	unsigned int wgt = 0, pref_wgt = 0; -	unsigned int func_code; -	int cpen, qpen, qid = 0, rc = -ENODEV; +	unsigned int func_code = 0; +	int cpen, qpen, qid = 0, rc;  	struct module *mod;  	trace_s390_zcrypt_req(crt, TP_ICARSACRT); -	ap_init_message(&ap_msg); +	rc = ap_init_apmsg(&ap_msg, 0); +	if (rc) +		goto out;  	if (crt->outputdatalength < crt->inputdatalength) { -		func_code = 0;  		rc = -EINVAL;  		goto out;  	} @@ -832,7 +838,7 @@ static long zcrypt_rsa_crt(struct ap_perms *perms,  	spin_unlock(&zcrypt_list_lock);  out: -	ap_release_message(&ap_msg); +	ap_release_apmsg(&ap_msg);  	if (tr) {  		tr->last_rc = rc;  		tr->last_qid = qid; @@ -842,23 +848,28 @@ out:  	return rc;  } -static long _zcrypt_send_cprb(bool userspace, struct ap_perms *perms, +static long _zcrypt_send_cprb(u32 xflags, struct ap_perms *perms,  			      struct zcrypt_track *tr,  			      struct ica_xcRB *xcrb)  { +	bool userspace = xflags & ZCRYPT_XFLAG_USERSPACE;  	struct zcrypt_card *zc, *pref_zc;  	struct zcrypt_queue *zq, *pref_zq;  	struct ap_message ap_msg;  	unsigned int wgt = 0, pref_wgt = 0; -	unsigned int func_code; +	unsigned int func_code = 0;  	unsigned short *domain, tdom; -	int cpen, qpen, qid = 0, rc = -ENODEV; +	int cpen, qpen, qid = 0, rc;  	struct module *mod;  	trace_s390_zcrypt_req(xcrb, TB_ZSECSENDCPRB);  	xcrb->status = 0; -	ap_init_message(&ap_msg); + +	rc = ap_init_apmsg(&ap_msg, xflags & ZCRYPT_XFLAG_NOMEMALLOC ? +			   AP_MSG_FLAG_MEMPOOL : 0); +	if (rc) +		goto out;  	rc = prep_cca_ap_msg(userspace, xcrb, &ap_msg, &func_code, &domain);  	if (rc) @@ -962,7 +973,7 @@ static long _zcrypt_send_cprb(bool userspace, struct ap_perms *perms,  	spin_unlock(&zcrypt_list_lock);  out: -	ap_release_message(&ap_msg); +	ap_release_apmsg(&ap_msg);  	if (tr) {  		tr->last_rc = rc;  		tr->last_qid = qid; @@ -972,7 +983,7 @@ out:  	return rc;  } -long zcrypt_send_cprb(struct ica_xcRB *xcrb) +long zcrypt_send_cprb(struct ica_xcRB *xcrb, u32 xflags)  {  	struct zcrypt_track tr;  	int rc; @@ -980,13 +991,13 @@ long zcrypt_send_cprb(struct ica_xcRB *xcrb)  	memset(&tr, 0, sizeof(tr));  	do { -		rc = _zcrypt_send_cprb(false, &ap_perms, &tr, xcrb); +		rc = _zcrypt_send_cprb(xflags, &ap_perms, &tr, xcrb);  	} while (rc == -EAGAIN && ++tr.again_counter < TRACK_AGAIN_MAX);  	/* on ENODEV failure: retry once again after a requested rescan */  	if (rc == -ENODEV && zcrypt_process_rescan())  		do { -			rc = _zcrypt_send_cprb(false, &ap_perms, &tr, xcrb); +			rc = _zcrypt_send_cprb(xflags, &ap_perms, &tr, xcrb);  		} while (rc == -EAGAIN && ++tr.again_counter < TRACK_AGAIN_MAX);  	if (rc == -EAGAIN && tr.again_counter >= TRACK_AGAIN_MAX)  		rc = -EIO; @@ -1024,50 +1035,50 @@ static bool is_desired_ep11_queue(unsigned int dev_qid,  	return false;  } -static long _zcrypt_send_ep11_cprb(bool userspace, struct ap_perms *perms, +static long _zcrypt_send_ep11_cprb(u32 xflags, struct ap_perms *perms,  				   struct zcrypt_track *tr,  				   struct ep11_urb *xcrb)  { +	bool userspace = xflags & ZCRYPT_XFLAG_USERSPACE;  	struct zcrypt_card *zc, *pref_zc;  	struct zcrypt_queue *zq, *pref_zq; -	struct ep11_target_dev *targets; +	struct ep11_target_dev *targets = NULL;  	unsigned short target_num;  	unsigned int wgt = 0, pref_wgt = 0; -	unsigned int func_code, domain; +	unsigned int func_code = 0, domain;  	struct ap_message ap_msg; -	int cpen, qpen, qid = 0, rc = -ENODEV; +	int cpen, qpen, qid = 0, rc;  	struct module *mod;  	trace_s390_zcrypt_req(xcrb, TP_ZSENDEP11CPRB); -	ap_init_message(&ap_msg); +	rc = ap_init_apmsg(&ap_msg, xflags & ZCRYPT_XFLAG_NOMEMALLOC ? +			   AP_MSG_FLAG_MEMPOOL : 0); +	if (rc) +		goto out;  	target_num = (unsigned short)xcrb->targets_num;  	/* empty list indicates autoselect (all available targets) */ -	targets = NULL; +	rc = -ENOMEM;  	if (target_num != 0) { -		struct ep11_target_dev __user *uptr; - -		targets = kcalloc(target_num, sizeof(*targets), GFP_KERNEL); -		if (!targets) { -			func_code = 0; -			rc = -ENOMEM; -			goto out; -		} - -		uptr = (struct ep11_target_dev __force __user *)xcrb->targets; -		if (z_copy_from_user(userspace, targets, uptr, -				     target_num * sizeof(*targets))) { -			func_code = 0; -			rc = -EFAULT; -			goto out_free; +		if (userspace) { +			targets = kcalloc(target_num, sizeof(*targets), GFP_KERNEL); +			if (!targets) +				goto out; +			if (copy_from_user(targets, xcrb->targets, +					   target_num * sizeof(*targets))) { +				rc = -EFAULT; +				goto out; +			} +		} else { +			targets = (struct ep11_target_dev __force __kernel *)xcrb->targets;  		}  	}  	rc = prep_ep11_ap_msg(userspace, xcrb, &ap_msg, &func_code, &domain);  	if (rc) -		goto out_free; +		goto out;  	print_hex_dump_debug("ep11req: ", DUMP_PREFIX_ADDRESS, 16, 1,  			     ap_msg.msg, ap_msg.len, false); @@ -1075,11 +1086,11 @@ static long _zcrypt_send_ep11_cprb(bool userspace, struct ap_perms *perms,  		if (ap_msg.flags & AP_MSG_FLAG_ADMIN) {  			if (!test_bit_inv(domain, perms->adm)) {  				rc = -ENODEV; -				goto out_free; +				goto out;  			}  		} else if ((ap_msg.flags & AP_MSG_FLAG_USAGE) == 0) {  			rc = -EOPNOTSUPP; -			goto out_free; +			goto out;  		}  	} @@ -1147,7 +1158,7 @@ static long _zcrypt_send_ep11_cprb(bool userspace, struct ap_perms *perms,  			pr_debug("no match for address ff.ffff => ENODEV\n");  		}  		rc = -ENODEV; -		goto out_free; +		goto out;  	}  	qid = pref_zq->queue->qid; @@ -1161,10 +1172,10 @@ static long _zcrypt_send_ep11_cprb(bool userspace, struct ap_perms *perms,  	zcrypt_drop_queue(pref_zc, pref_zq, mod, wgt);  	spin_unlock(&zcrypt_list_lock); -out_free: -	kfree(targets);  out: -	ap_release_message(&ap_msg); +	if (userspace) +		kfree(targets); +	ap_release_apmsg(&ap_msg);  	if (tr) {  		tr->last_rc = rc;  		tr->last_qid = qid; @@ -1174,7 +1185,7 @@ out:  	return rc;  } -long zcrypt_send_ep11_cprb(struct ep11_urb *xcrb) +long zcrypt_send_ep11_cprb(struct ep11_urb *xcrb, u32 xflags)  {  	struct zcrypt_track tr;  	int rc; @@ -1182,13 +1193,13 @@ long zcrypt_send_ep11_cprb(struct ep11_urb *xcrb)  	memset(&tr, 0, sizeof(tr));  	do { -		rc = _zcrypt_send_ep11_cprb(false, &ap_perms, &tr, xcrb); +		rc = _zcrypt_send_ep11_cprb(xflags, &ap_perms, &tr, xcrb);  	} while (rc == -EAGAIN && ++tr.again_counter < TRACK_AGAIN_MAX);  	/* on ENODEV failure: retry once again after a requested rescan */  	if (rc == -ENODEV && zcrypt_process_rescan())  		do { -			rc = _zcrypt_send_ep11_cprb(false, &ap_perms, &tr, xcrb); +			rc = _zcrypt_send_ep11_cprb(xflags, &ap_perms, &tr, xcrb);  		} while (rc == -EAGAIN && ++tr.again_counter < TRACK_AGAIN_MAX);  	if (rc == -EAGAIN && tr.again_counter >= TRACK_AGAIN_MAX)  		rc = -EIO; @@ -1204,7 +1215,7 @@ static long zcrypt_rng(char *buffer)  	struct zcrypt_card *zc, *pref_zc;  	struct zcrypt_queue *zq, *pref_zq;  	unsigned int wgt = 0, pref_wgt = 0; -	unsigned int func_code; +	unsigned int func_code = 0;  	struct ap_message ap_msg;  	unsigned int domain;  	int qid = 0, rc = -ENODEV; @@ -1212,7 +1223,9 @@ static long zcrypt_rng(char *buffer)  	trace_s390_zcrypt_req(buffer, TP_HWRNGCPRB); -	ap_init_message(&ap_msg); +	rc = ap_init_apmsg(&ap_msg, 0); +	if (rc) +		goto out;  	rc = prep_rng_ap_msg(&ap_msg, &func_code, &domain);  	if (rc)  		goto out; @@ -1258,7 +1271,7 @@ static long zcrypt_rng(char *buffer)  	spin_unlock(&zcrypt_list_lock);  out: -	ap_release_message(&ap_msg); +	ap_release_apmsg(&ap_msg);  	trace_s390_zcrypt_rep(buffer, func_code, rc,  			      AP_QID_CARD(qid), AP_QID_QUEUE(qid));  	return rc; @@ -1291,19 +1304,25 @@ static void zcrypt_device_status_mask(struct zcrypt_device_status *devstatus)  	spin_unlock(&zcrypt_list_lock);  } -void zcrypt_device_status_mask_ext(struct zcrypt_device_status_ext *devstatus) +void zcrypt_device_status_mask_ext(struct zcrypt_device_status_ext *devstatus, +				   int maxcard, int maxqueue)  {  	struct zcrypt_card *zc;  	struct zcrypt_queue *zq;  	struct zcrypt_device_status_ext *stat;  	int card, queue; +	maxcard = min_t(int, maxcard, MAX_ZDEV_CARDIDS_EXT); +	maxqueue = min_t(int, maxqueue, MAX_ZDEV_DOMAINS_EXT); +  	spin_lock(&zcrypt_list_lock);  	for_each_zcrypt_card(zc) {  		for_each_zcrypt_queue(zq, zc) {  			card = AP_QID_CARD(zq->queue->qid);  			queue = AP_QID_QUEUE(zq->queue->qid); -			stat = &devstatus[card * AP_DOMAINS + queue]; +			if (card >= maxcard || queue >= maxqueue) +				continue; +			stat = &devstatus[card * maxqueue + queue];  			stat->hwtype = zc->card->ap_dev.device_type;  			stat->functions = zc->card->hwinfo.fac >> 26;  			stat->qid = zq->queue->qid; @@ -1523,6 +1542,7 @@ static int zsecsendcprb_ioctl(struct ap_perms *perms, unsigned long arg)  	int rc;  	struct ica_xcRB xcrb;  	struct zcrypt_track tr; +	u32 xflags = ZCRYPT_XFLAG_USERSPACE;  	struct ica_xcRB __user *uxcrb = (void __user *)arg;  	memset(&tr, 0, sizeof(tr)); @@ -1530,13 +1550,13 @@ static int zsecsendcprb_ioctl(struct ap_perms *perms, unsigned long arg)  		return -EFAULT;  	do { -		rc = _zcrypt_send_cprb(true, perms, &tr, &xcrb); +		rc = _zcrypt_send_cprb(xflags, perms, &tr, &xcrb);  	} while (rc == -EAGAIN && ++tr.again_counter < TRACK_AGAIN_MAX);  	/* on ENODEV failure: retry once again after a requested rescan */  	if (rc == -ENODEV && zcrypt_process_rescan())  		do { -			rc = _zcrypt_send_cprb(true, perms, &tr, &xcrb); +			rc = _zcrypt_send_cprb(xflags, perms, &tr, &xcrb);  		} while (rc == -EAGAIN && ++tr.again_counter < TRACK_AGAIN_MAX);  	if (rc == -EAGAIN && tr.again_counter >= TRACK_AGAIN_MAX)  		rc = -EIO; @@ -1553,6 +1573,7 @@ static int zsendep11cprb_ioctl(struct ap_perms *perms, unsigned long arg)  	int rc;  	struct ep11_urb xcrb;  	struct zcrypt_track tr; +	u32 xflags = ZCRYPT_XFLAG_USERSPACE;  	struct ep11_urb __user *uxcrb = (void __user *)arg;  	memset(&tr, 0, sizeof(tr)); @@ -1560,13 +1581,13 @@ static int zsendep11cprb_ioctl(struct ap_perms *perms, unsigned long arg)  		return -EFAULT;  	do { -		rc = _zcrypt_send_ep11_cprb(true, perms, &tr, &xcrb); +		rc = _zcrypt_send_ep11_cprb(xflags, perms, &tr, &xcrb);  	} while (rc == -EAGAIN && ++tr.again_counter < TRACK_AGAIN_MAX);  	/* on ENODEV failure: retry once again after a requested rescan */  	if (rc == -ENODEV && zcrypt_process_rescan())  		do { -			rc = _zcrypt_send_ep11_cprb(true, perms, &tr, &xcrb); +			rc = _zcrypt_send_ep11_cprb(xflags, perms, &tr, &xcrb);  		} while (rc == -EAGAIN && ++tr.again_counter < TRACK_AGAIN_MAX);  	if (rc == -EAGAIN && tr.again_counter >= TRACK_AGAIN_MAX)  		rc = -EIO; @@ -1607,7 +1628,9 @@ static long zcrypt_unlocked_ioctl(struct file *filp, unsigned int cmd,  					 GFP_KERNEL);  		if (!device_status)  			return -ENOMEM; -		zcrypt_device_status_mask_ext(device_status); +		zcrypt_device_status_mask_ext(device_status, +					      MAX_ZDEV_CARDIDS_EXT, +					      MAX_ZDEV_DOMAINS_EXT);  		if (copy_to_user((char __user *)arg, device_status,  				 total_size))  			rc = -EFAULT; @@ -1827,6 +1850,7 @@ static long trans_xcrb32(struct ap_perms *perms, struct file *filp,  			 unsigned int cmd, unsigned long arg)  {  	struct compat_ica_xcrb __user *uxcrb32 = compat_ptr(arg); +	u32 xflags = ZCRYPT_XFLAG_USERSPACE;  	struct compat_ica_xcrb xcrb32;  	struct zcrypt_track tr;  	struct ica_xcRB xcrb64; @@ -1856,13 +1880,13 @@ static long trans_xcrb32(struct ap_perms *perms, struct file *filp,  	xcrb64.priority_window = xcrb32.priority_window;  	xcrb64.status = xcrb32.status;  	do { -		rc = _zcrypt_send_cprb(true, perms, &tr, &xcrb64); +		rc = _zcrypt_send_cprb(xflags, perms, &tr, &xcrb64);  	} while (rc == -EAGAIN && ++tr.again_counter < TRACK_AGAIN_MAX);  	/* on ENODEV failure: retry once again after a requested rescan */  	if (rc == -ENODEV && zcrypt_process_rescan())  		do { -			rc = _zcrypt_send_cprb(true, perms, &tr, &xcrb64); +			rc = _zcrypt_send_cprb(xflags, perms, &tr, &xcrb64);  		} while (rc == -EAGAIN && ++tr.again_counter < TRACK_AGAIN_MAX);  	if (rc == -EAGAIN && tr.again_counter >= TRACK_AGAIN_MAX)  		rc = -EIO; @@ -2132,13 +2156,27 @@ int __init zcrypt_api_init(void)  {  	int rc; +	/* make sure the mempool threshold is >= 1 */ +	if (zcrypt_mempool_threshold < 1) { +		rc = -EINVAL; +		goto out; +	} +  	rc = zcrypt_debug_init();  	if (rc)  		goto out;  	rc = zcdn_init();  	if (rc) -		goto out; +		goto out_zcdn_init_failed; + +	rc = zcrypt_ccamisc_init(); +	if (rc) +		goto out_ccamisc_init_failed; + +	rc = zcrypt_ep11misc_init(); +	if (rc) +		goto out_ep11misc_init_failed;  	/* Register the request sprayer. */  	rc = misc_register(&zcrypt_misc_device); @@ -2151,7 +2189,12 @@ int __init zcrypt_api_init(void)  	return 0;  out_misc_register_failed: +	zcrypt_ep11misc_exit(); +out_ep11misc_init_failed: +	zcrypt_ccamisc_exit(); +out_ccamisc_init_failed:  	zcdn_exit(); +out_zcdn_init_failed:  	zcrypt_debug_exit();  out:  	return rc;  | 
