summaryrefslogtreecommitdiffstats
path: root/drivers/s390/crypto
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/crypto')
-rw-r--r--drivers/s390/crypto/ap_bus.c30
-rw-r--r--drivers/s390/crypto/ap_bus.h3
-rw-r--r--drivers/s390/crypto/ap_queue.c2
-rw-r--r--drivers/s390/crypto/pkey_api.c3
-rw-r--r--drivers/s390/crypto/zcrypt_api.c23
5 files changed, 49 insertions, 12 deletions
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c
index 1546389d71db..b9fc502c58c2 100644
--- a/drivers/s390/crypto/ap_bus.c
+++ b/drivers/s390/crypto/ap_bus.c
@@ -116,7 +116,7 @@ static int user_set_domain;
static struct bus_type ap_bus_type;
/* Adapter interrupt definitions */
-static void ap_interrupt_handler(struct airq_struct *airq);
+static void ap_interrupt_handler(struct airq_struct *airq, bool floating);
static int ap_airq_flag;
@@ -254,19 +254,37 @@ static inline int ap_test_config_card_id(unsigned int id)
}
/*
- * ap_test_config_domain(): Test, whether an AP usage domain is configured.
+ * ap_test_config_usage_domain(): Test, whether an AP usage domain
+ * is configured.
* @domain AP usage domain ID
*
* Returns 0 if the usage domain is not configured
* 1 if the usage domain is configured or
* if the configuration information is not available
*/
-static inline int ap_test_config_domain(unsigned int domain)
+int ap_test_config_usage_domain(unsigned int domain)
{
if (!ap_configuration) /* QCI not supported */
return domain < 16;
return ap_test_config(ap_configuration->aqm, domain);
}
+EXPORT_SYMBOL(ap_test_config_usage_domain);
+
+/*
+ * ap_test_config_ctrl_domain(): Test, whether an AP control domain
+ * is configured.
+ * @domain AP control domain ID
+ *
+ * Returns 1 if the control domain is configured
+ * 0 in all other cases
+ */
+int ap_test_config_ctrl_domain(unsigned int domain)
+{
+ if (!ap_configuration) /* QCI not supported */
+ return 0;
+ return ap_test_config(ap_configuration->adm, domain);
+}
+EXPORT_SYMBOL(ap_test_config_ctrl_domain);
/**
* ap_query_queue(): Check if an AP queue is available.
@@ -393,7 +411,7 @@ static enum hrtimer_restart ap_poll_timeout(struct hrtimer *unused)
* ap_interrupt_handler() - Schedule ap_tasklet on interrupt
* @airq: pointer to adapter interrupt descriptor
*/
-static void ap_interrupt_handler(struct airq_struct *airq)
+static void ap_interrupt_handler(struct airq_struct *airq, bool floating)
{
inc_irq_stat(IRQIO_APB);
if (!ap_suspend_flag)
@@ -1267,7 +1285,7 @@ static void ap_select_domain(void)
best_domain = -1;
max_count = 0;
for (i = 0; i < AP_DOMAINS; i++) {
- if (!ap_test_config_domain(i) ||
+ if (!ap_test_config_usage_domain(i) ||
!test_bit_inv(i, ap_perms.aqm))
continue;
count = 0;
@@ -1442,7 +1460,7 @@ static void _ap_scan_bus_adapter(int id)
(void *)(long) qid,
__match_queue_device_with_qid);
aq = dev ? to_ap_queue(dev) : NULL;
- if (!ap_test_config_domain(dom)) {
+ if (!ap_test_config_usage_domain(dom)) {
if (dev) {
/* Queue device exists but has been
* removed from configuration.
diff --git a/drivers/s390/crypto/ap_bus.h b/drivers/s390/crypto/ap_bus.h
index 15a98a673c5c..6f3cf37776ca 100644
--- a/drivers/s390/crypto/ap_bus.h
+++ b/drivers/s390/crypto/ap_bus.h
@@ -251,6 +251,9 @@ void ap_wait(enum ap_wait wait);
void ap_request_timeout(struct timer_list *t);
void ap_bus_force_rescan(void);
+int ap_test_config_usage_domain(unsigned int domain);
+int ap_test_config_ctrl_domain(unsigned int domain);
+
void ap_queue_init_reply(struct ap_queue *aq, struct ap_message *ap_msg);
struct ap_queue *ap_queue_create(ap_qid_t qid, int device_type);
void ap_queue_prepare_remove(struct ap_queue *aq);
diff --git a/drivers/s390/crypto/ap_queue.c b/drivers/s390/crypto/ap_queue.c
index 6a340f2c3556..5ea83dc4f1d7 100644
--- a/drivers/s390/crypto/ap_queue.c
+++ b/drivers/s390/crypto/ap_queue.c
@@ -751,8 +751,8 @@ void ap_queue_prepare_remove(struct ap_queue *aq)
__ap_flush_queue(aq);
/* set REMOVE state to prevent new messages are queued in */
aq->state = AP_STATE_REMOVE;
- del_timer_sync(&aq->timeout);
spin_unlock_bh(&aq->lock);
+ del_timer_sync(&aq->timeout);
}
void ap_queue_remove(struct ap_queue *aq)
diff --git a/drivers/s390/crypto/pkey_api.c b/drivers/s390/crypto/pkey_api.c
index 3e85d665c572..45eb0c14b880 100644
--- a/drivers/s390/crypto/pkey_api.c
+++ b/drivers/s390/crypto/pkey_api.c
@@ -51,7 +51,8 @@ static debug_info_t *debug_info;
static void __init pkey_debug_init(void)
{
- debug_info = debug_register("pkey", 1, 1, 4 * sizeof(long));
+ /* 5 arguments per dbf entry (including the format string ptr) */
+ debug_info = debug_register("pkey", 1, 1, 5 * sizeof(long));
debug_register_view(debug_info, &debug_sprintf_view);
debug_set_level(debug_info, 3);
}
diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c
index 689c2af7026a..1058b4b5cc1e 100644
--- a/drivers/s390/crypto/zcrypt_api.c
+++ b/drivers/s390/crypto/zcrypt_api.c
@@ -525,7 +525,7 @@ static int zcrypt_open(struct inode *inode, struct file *filp)
filp->private_data = (void *) perms;
atomic_inc(&zcrypt_open_count);
- return nonseekable_open(inode, filp);
+ return stream_open(inode, filp);
}
/**
@@ -659,6 +659,7 @@ static long zcrypt_rsa_modexpo(struct ap_perms *perms,
trace_s390_zcrypt_req(mex, TP_ICARSAMODEXPO);
if (mex->outputdatalength < mex->inputdatalength) {
+ func_code = 0;
rc = -EINVAL;
goto out;
}
@@ -742,6 +743,7 @@ static long zcrypt_rsa_crt(struct ap_perms *perms,
trace_s390_zcrypt_req(crt, TP_ICARSACRT);
if (crt->outputdatalength < crt->inputdatalength) {
+ func_code = 0;
rc = -EINVAL;
goto out;
}
@@ -820,7 +822,7 @@ static long _zcrypt_send_cprb(struct ap_perms *perms,
struct ap_message ap_msg;
unsigned int weight, pref_weight;
unsigned int func_code;
- unsigned short *domain;
+ unsigned short *domain, tdom;
int qid = 0, rc = -ENODEV;
struct module *mod;
@@ -832,6 +834,17 @@ static long _zcrypt_send_cprb(struct ap_perms *perms,
if (rc)
goto out;
+ /*
+ * If a valid target domain is set and this domain is NOT a usage
+ * domain but a control only domain, use the default domain as target.
+ */
+ tdom = *domain;
+ if (tdom >= 0 && tdom < AP_DOMAINS &&
+ !ap_test_config_usage_domain(tdom) &&
+ ap_test_config_ctrl_domain(tdom) &&
+ ap_domain_index >= 0)
+ tdom = ap_domain_index;
+
pref_zc = NULL;
pref_zq = NULL;
spin_lock(&zcrypt_list_lock);
@@ -854,8 +867,8 @@ static long _zcrypt_send_cprb(struct ap_perms *perms,
/* check if device is online and eligible */
if (!zq->online ||
!zq->ops->send_cprb ||
- ((*domain != (unsigned short) AUTOSELECT) &&
- (*domain != AP_QID_QUEUE(zq->queue->qid))))
+ (tdom != (unsigned short) AUTOSELECT &&
+ tdom != AP_QID_QUEUE(zq->queue->qid)))
continue;
/* check if device node has admission for this queue */
if (!zcrypt_check_queue(perms,
@@ -951,6 +964,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;
}
@@ -958,6 +972,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;
}