aboutsummaryrefslogtreecommitdiff
path: root/drivers/s390/crypto
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/crypto')
-rw-r--r--drivers/s390/crypto/ap_bus.c63
-rw-r--r--drivers/s390/crypto/ap_bus.h2
-rw-r--r--drivers/s390/crypto/zcrypt_api.c24
-rw-r--r--drivers/s390/crypto/zcrypt_api.h28
-rw-r--r--drivers/s390/crypto/zcrypt_cex2a.c4
-rw-r--r--drivers/s390/crypto/zcrypt_error.h6
-rw-r--r--drivers/s390/crypto/zcrypt_pcica.c3
-rw-r--r--drivers/s390/crypto/zcrypt_pcicc.c15
-rw-r--r--drivers/s390/crypto/zcrypt_pcixcc.c69
9 files changed, 74 insertions, 140 deletions
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c
index a1ab3e3efd1..62b6b55230d 100644
--- a/drivers/s390/crypto/ap_bus.c
+++ b/drivers/s390/crypto/ap_bus.c
@@ -34,13 +34,15 @@
#include <linux/mutex.h>
#include <asm/s390_rdev.h>
#include <asm/reset.h>
+#include <linux/hrtimer.h>
+#include <linux/ktime.h>
#include "ap_bus.h"
/* Some prototypes. */
static void ap_scan_bus(struct work_struct *);
static void ap_poll_all(unsigned long);
-static void ap_poll_timeout(unsigned long);
+static enum hrtimer_restart ap_poll_timeout(struct hrtimer *);
static int ap_poll_thread_start(void);
static void ap_poll_thread_stop(void);
static void ap_request_timeout(unsigned long);
@@ -80,12 +82,15 @@ static DECLARE_WORK(ap_config_work, ap_scan_bus);
/*
* Tasklet & timer for AP request polling.
*/
-static struct timer_list ap_poll_timer = TIMER_INITIALIZER(ap_poll_timeout,0,0);
static DECLARE_TASKLET(ap_tasklet, ap_poll_all, 0);
static atomic_t ap_poll_requests = ATOMIC_INIT(0);
static DECLARE_WAIT_QUEUE_HEAD(ap_poll_wait);
static struct task_struct *ap_poll_kthread = NULL;
static DEFINE_MUTEX(ap_poll_thread_mutex);
+static struct hrtimer ap_poll_timer;
+/* In LPAR poll with 4kHz frequency. Poll every 250000 nanoseconds.
+ * If z/VM change to 1500000 nanoseconds to adjust to z/VM polling.*/
+static unsigned long long poll_timeout = 250000;
/**
* ap_intructions_available() - Test if AP instructions are available.
@@ -636,11 +641,39 @@ static ssize_t ap_poll_thread_store(struct bus_type *bus,
static BUS_ATTR(poll_thread, 0644, ap_poll_thread_show, ap_poll_thread_store);
+static ssize_t poll_timeout_show(struct bus_type *bus, char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "%llu\n", poll_timeout);
+}
+
+static ssize_t poll_timeout_store(struct bus_type *bus, const char *buf,
+ size_t count)
+{
+ unsigned long long time;
+ ktime_t hr_time;
+
+ /* 120 seconds = maximum poll interval */
+ if (sscanf(buf, "%llu\n", &time) != 1 || time < 1 || time > 120000000000)
+ return -EINVAL;
+ poll_timeout = time;
+ hr_time = ktime_set(0, poll_timeout);
+
+ if (!hrtimer_is_queued(&ap_poll_timer) ||
+ !hrtimer_forward(&ap_poll_timer, ap_poll_timer.expires, hr_time)) {
+ ap_poll_timer.expires = hr_time;
+ hrtimer_start(&ap_poll_timer, hr_time, HRTIMER_MODE_ABS);
+ }
+ return count;
+}
+
+static BUS_ATTR(poll_timeout, 0644, poll_timeout_show, poll_timeout_store);
+
static struct bus_attribute *const ap_bus_attrs[] = {
&bus_attr_ap_domain,
&bus_attr_config_time,
&bus_attr_poll_thread,
- NULL
+ &bus_attr_poll_timeout,
+ NULL,
};
/**
@@ -895,9 +928,10 @@ ap_config_timeout(unsigned long ptr)
*/
static inline void ap_schedule_poll_timer(void)
{
- if (timer_pending(&ap_poll_timer))
+ if (hrtimer_is_queued(&ap_poll_timer))
return;
- mod_timer(&ap_poll_timer, jiffies + AP_POLL_TIME);
+ hrtimer_start(&ap_poll_timer, ktime_set(0, poll_timeout),
+ HRTIMER_MODE_ABS);
}
/**
@@ -1115,13 +1149,14 @@ EXPORT_SYMBOL(ap_cancel_message);
/**
* ap_poll_timeout(): AP receive polling for finished AP requests.
- * @unused: Unused variable.
+ * @unused: Unused pointer.
*
- * Schedules the AP tasklet.
+ * Schedules the AP tasklet using a high resolution timer.
*/
-static void ap_poll_timeout(unsigned long unused)
+static enum hrtimer_restart ap_poll_timeout(struct hrtimer *unused)
{
tasklet_schedule(&ap_tasklet);
+ return HRTIMER_NORESTART;
}
/**
@@ -1344,6 +1379,14 @@ int __init ap_module_init(void)
ap_config_timer.expires = jiffies + ap_config_time * HZ;
add_timer(&ap_config_timer);
+ /* Setup the high resultion poll timer.
+ * If we are running under z/VM adjust polling to z/VM polling rate.
+ */
+ if (MACHINE_IS_VM)
+ poll_timeout = 1500000;
+ hrtimer_init(&ap_poll_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
+ ap_poll_timer.function = ap_poll_timeout;
+
/* Start the low priority AP bus poll thread. */
if (ap_thread_flag) {
rc = ap_poll_thread_start();
@@ -1355,7 +1398,7 @@ int __init ap_module_init(void)
out_work:
del_timer_sync(&ap_config_timer);
- del_timer_sync(&ap_poll_timer);
+ hrtimer_cancel(&ap_poll_timer);
destroy_workqueue(ap_work_queue);
out_root:
s390_root_dev_unregister(ap_root_device);
@@ -1386,7 +1429,7 @@ void ap_module_exit(void)
ap_reset_domain();
ap_poll_thread_stop();
del_timer_sync(&ap_config_timer);
- del_timer_sync(&ap_poll_timer);
+ hrtimer_cancel(&ap_poll_timer);
destroy_workqueue(ap_work_queue);
tasklet_kill(&ap_tasklet);
s390_root_dev_unregister(ap_root_device);
diff --git a/drivers/s390/crypto/ap_bus.h b/drivers/s390/crypto/ap_bus.h
index c1e1200c43f..446378b308f 100644
--- a/drivers/s390/crypto/ap_bus.h
+++ b/drivers/s390/crypto/ap_bus.h
@@ -92,6 +92,8 @@ struct ap_queue_status {
#define AP_DEVICE_TYPE_PCIXCC 5
#define AP_DEVICE_TYPE_CEX2A 6
#define AP_DEVICE_TYPE_CEX2C 7
+#define AP_DEVICE_TYPE_CEX2A2 8
+#define AP_DEVICE_TYPE_CEX2C2 9
/*
* AP reset flag states
diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c
index 4d36e805a23..8a4964f3584 100644
--- a/drivers/s390/crypto/zcrypt_api.c
+++ b/drivers/s390/crypto/zcrypt_api.c
@@ -1068,10 +1068,8 @@ static int zcrypt_status_write(struct file *file, const char __user *buffer,
#define LBUFSIZE 1200UL
lbuf = kmalloc(LBUFSIZE, GFP_KERNEL);
- if (!lbuf) {
- PRINTK("kmalloc failed!\n");
+ if (!lbuf)
return 0;
- }
local_count = min(LBUFSIZE - 1, count);
if (copy_from_user(lbuf, buffer, local_count) != 0) {
@@ -1081,23 +1079,15 @@ static int zcrypt_status_write(struct file *file, const char __user *buffer,
lbuf[local_count] = '\0';
ptr = strstr(lbuf, "Online devices");
- if (!ptr) {
- PRINTK("Unable to parse data (missing \"Online devices\")\n");
+ if (!ptr)
goto out;
- }
ptr = strstr(ptr, "\n");
- if (!ptr) {
- PRINTK("Unable to parse data (missing newline "
- "after \"Online devices\")\n");
+ if (!ptr)
goto out;
- }
ptr++;
- if (strstr(ptr, "Waiting work element counts") == NULL) {
- PRINTK("Unable to parse data (missing "
- "\"Waiting work element counts\")\n");
+ if (strstr(ptr, "Waiting work element counts") == NULL)
goto out;
- }
for (j = 0; j < 64 && *ptr; ptr++) {
/*
@@ -1197,16 +1187,12 @@ int __init zcrypt_api_init(void)
/* Register the request sprayer. */
rc = misc_register(&zcrypt_misc_device);
- if (rc < 0) {
- PRINTKW(KERN_ERR "misc_register (minor %d) failed with %d\n",
- zcrypt_misc_device.minor, rc);
+ if (rc < 0)
goto out;
- }
/* Set up the proc file system */
zcrypt_entry = create_proc_entry("driver/z90crypt", 0644, NULL);
if (!zcrypt_entry) {
- PRINTK("Couldn't create z90crypt proc entry\n");
rc = -ENOMEM;
goto out_misc;
}
diff --git a/drivers/s390/crypto/zcrypt_api.h b/drivers/s390/crypto/zcrypt_api.h
index 5c6e222b2ac..1d1ec74dadb 100644
--- a/drivers/s390/crypto/zcrypt_api.h
+++ b/drivers/s390/crypto/zcrypt_api.h
@@ -30,34 +30,6 @@
#ifndef _ZCRYPT_API_H_
#define _ZCRYPT_API_H_
-/**
- * Macro definitions
- *
- * PDEBUG debugs in the form "zcrypt: function_name -> message"
- *
- * PRINTK is like PDEBUG, except that it is always enabled
- * PRINTKN is like PRINTK, except that it does not include the function name
- * PRINTKW is like PRINTK, except that it uses KERN_WARNING
- * PRINTKC is like PRINTK, except that it uses KERN_CRIT
- */
-#define DEV_NAME "zcrypt"
-
-#define PRINTK(fmt, args...) \
- printk(KERN_DEBUG DEV_NAME ": %s -> " fmt, __func__ , ## args)
-#define PRINTKN(fmt, args...) \
- printk(KERN_DEBUG DEV_NAME ": " fmt, ## args)
-#define PRINTKW(fmt, args...) \
- printk(KERN_WARNING DEV_NAME ": %s -> " fmt, __func__ , ## args)
-#define PRINTKC(fmt, args...) \
- printk(KERN_CRIT DEV_NAME ": %s -> " fmt, __func__ , ## args)
-
-#ifdef ZCRYPT_DEBUG
-#define PDEBUG(fmt, args...) \
- printk(KERN_DEBUG DEV_NAME ": %s -> " fmt, __func__ , ## args)
-#else
-#define PDEBUG(fmt, args...) do {} while (0)
-#endif
-
#include "ap_bus.h"
#include <asm/zcrypt.h>
diff --git a/drivers/s390/crypto/zcrypt_cex2a.c b/drivers/s390/crypto/zcrypt_cex2a.c
index 08657f604b8..54f4cbc3be9 100644
--- a/drivers/s390/crypto/zcrypt_cex2a.c
+++ b/drivers/s390/crypto/zcrypt_cex2a.c
@@ -49,6 +49,7 @@
static struct ap_device_id zcrypt_cex2a_ids[] = {
{ AP_DEVICE(AP_DEVICE_TYPE_CEX2A) },
+ { AP_DEVICE(AP_DEVICE_TYPE_CEX2A2) },
{ /* end of list */ },
};
@@ -242,9 +243,6 @@ static int convert_response(struct zcrypt_device *zdev,
return convert_type80(zdev, reply,
outputdata, outputdatalength);
default: /* Unknown response type, this should NEVER EVER happen */
- PRINTK("Unrecognized Message Header: %08x%08x\n",
- *(unsigned int *) reply->message,
- *(unsigned int *) (reply->message+4));
zdev->online = 0;
return -EAGAIN; /* repeat the request on a different device. */
}
diff --git a/drivers/s390/crypto/zcrypt_error.h b/drivers/s390/crypto/zcrypt_error.h
index 3e27fe77d20..03ba27f05f9 100644
--- a/drivers/s390/crypto/zcrypt_error.h
+++ b/drivers/s390/crypto/zcrypt_error.h
@@ -92,10 +92,6 @@ static inline int convert_error(struct zcrypt_device *zdev,
{
struct error_hdr *ehdr = reply->message;
- PRINTK("Hardware error : Type %02x Message Header: %08x%08x\n",
- ehdr->type, *(unsigned int *) reply->message,
- *(unsigned int *) (reply->message + 4));
-
switch (ehdr->reply_code) {
case REP82_ERROR_OPERAND_INVALID:
case REP82_ERROR_OPERAND_SIZE:
@@ -123,8 +119,6 @@ static inline int convert_error(struct zcrypt_device *zdev,
zdev->online = 0;
return -EAGAIN;
default:
- PRINTKW("unknown type %02x reply code = %d\n",
- ehdr->type, ehdr->reply_code);
zdev->online = 0;
return -EAGAIN; /* repeat the request on a different device. */
}
diff --git a/drivers/s390/crypto/zcrypt_pcica.c b/drivers/s390/crypto/zcrypt_pcica.c
index 6e93b475178..12da4815ba8 100644
--- a/drivers/s390/crypto/zcrypt_pcica.c
+++ b/drivers/s390/crypto/zcrypt_pcica.c
@@ -226,9 +226,6 @@ static int convert_response(struct zcrypt_device *zdev,
return convert_type84(zdev, reply,
outputdata, outputdatalength);
default: /* Unknown response type, this should NEVER EVER happen */
- PRINTK("Unrecognized Message Header: %08x%08x\n",
- *(unsigned int *) reply->message,
- *(unsigned int *) (reply->message+4));
zdev->online = 0;
return -EAGAIN; /* repeat the request on a different device. */
}
diff --git a/drivers/s390/crypto/zcrypt_pcicc.c b/drivers/s390/crypto/zcrypt_pcicc.c
index 17ea56ce1c1..779952cb19f 100644
--- a/drivers/s390/crypto/zcrypt_pcicc.c
+++ b/drivers/s390/crypto/zcrypt_pcicc.c
@@ -361,26 +361,18 @@ static int convert_type86(struct zcrypt_device *zdev,
service_rc = le16_to_cpu(msg->cprb.ccp_rtcode);
if (unlikely(service_rc != 0)) {
service_rs = le16_to_cpu(msg->cprb.ccp_rscode);
- if (service_rc == 8 && service_rs == 66) {
- PDEBUG("Bad block format on PCICC\n");
+ if (service_rc == 8 && service_rs == 66)
return -EINVAL;
- }
- if (service_rc == 8 && service_rs == 65) {
- PDEBUG("Probably an even modulus on PCICC\n");
+ if (service_rc == 8 && service_rs == 65)
return -EINVAL;
- }
if (service_rc == 8 && service_rs == 770) {
- PDEBUG("Invalid key length on PCICC\n");
zdev->max_mod_size = PCICC_MAX_MOD_SIZE_OLD;
return -EAGAIN;
}
if (service_rc == 8 && service_rs == 783) {
- PDEBUG("Extended bitlengths not enabled on PCICC\n");
zdev->max_mod_size = PCICC_MAX_MOD_SIZE_OLD;
return -EAGAIN;
}
- PRINTK("Unknown service rc/rs (PCICC): %d/%d\n",
- service_rc, service_rs);
zdev->online = 0;
return -EAGAIN; /* repeat the request on a different device. */
}
@@ -434,9 +426,6 @@ static int convert_response(struct zcrypt_device *zdev,
outputdata, outputdatalength);
/* no break, incorrect cprb version is an unknown response */
default: /* Unknown response type, this should NEVER EVER happen */
- PRINTK("Unrecognized Message Header: %08x%08x\n",
- *(unsigned int *) reply->message,
- *(unsigned int *) (reply->message+4));
zdev->online = 0;
return -EAGAIN; /* repeat the request on a different device. */
}
diff --git a/drivers/s390/crypto/zcrypt_pcixcc.c b/drivers/s390/crypto/zcrypt_pcixcc.c
index 0bc9b3188e6..d8ad36f8154 100644
--- a/drivers/s390/crypto/zcrypt_pcixcc.c
+++ b/drivers/s390/crypto/zcrypt_pcixcc.c
@@ -72,6 +72,7 @@ struct response_type {
static struct ap_device_id zcrypt_pcixcc_ids[] = {
{ AP_DEVICE(AP_DEVICE_TYPE_PCIXCC) },
{ AP_DEVICE(AP_DEVICE_TYPE_CEX2C) },
+ { AP_DEVICE(AP_DEVICE_TYPE_CEX2C2) },
{ /* end of list */ },
};
@@ -289,38 +290,19 @@ static int XCRB_msg_to_type6CPRB_msgX(struct zcrypt_device *zdev,
ap_msg->length = sizeof(struct type6_hdr) +
CEIL4(xcRB->request_control_blk_length) +
xcRB->request_data_length;
- if (ap_msg->length > PCIXCC_MAX_XCRB_MESSAGE_SIZE) {
- PRINTK("Combined message is too large (%ld/%d/%d).\n",
- sizeof(struct type6_hdr),
- xcRB->request_control_blk_length,
- xcRB->request_data_length);
+ if (ap_msg->length > PCIXCC_MAX_XCRB_MESSAGE_SIZE)
return -EFAULT;
- }
- if (CEIL4(xcRB->reply_control_blk_length) >
- PCIXCC_MAX_XCRB_REPLY_SIZE) {
- PDEBUG("Reply CPRB length is too large (%d).\n",
- xcRB->request_control_blk_length);
+ if (CEIL4(xcRB->reply_control_blk_length) > PCIXCC_MAX_XCRB_REPLY_SIZE)
return -EFAULT;
- }
- if (CEIL4(xcRB->reply_data_length) > PCIXCC_MAX_XCRB_DATA_SIZE) {
- PDEBUG("Reply data block length is too large (%d).\n",
- xcRB->reply_data_length);
+ if (CEIL4(xcRB->reply_data_length) > PCIXCC_MAX_XCRB_DATA_SIZE)
return -EFAULT;
- }
replylen = CEIL4(xcRB->reply_control_blk_length) +
CEIL4(xcRB->reply_data_length) +
sizeof(struct type86_fmt2_msg);
if (replylen > PCIXCC_MAX_XCRB_RESPONSE_SIZE) {
- PDEBUG("Reply CPRB + data block > PCIXCC_MAX_XCRB_RESPONSE_SIZE"
- " (%d/%d/%d).\n",
- sizeof(struct type86_fmt2_msg),
- xcRB->reply_control_blk_length,
- xcRB->reply_data_length);
xcRB->reply_control_blk_length = PCIXCC_MAX_XCRB_RESPONSE_SIZE -
(sizeof(struct type86_fmt2_msg) +
CEIL4(xcRB->reply_data_length));
- PDEBUG("Capping Reply CPRB length at %d\n",
- xcRB->reply_control_blk_length);
}
/* prepare type6 header */
@@ -339,11 +321,8 @@ static int XCRB_msg_to_type6CPRB_msgX(struct zcrypt_device *zdev,
xcRB->request_control_blk_length))
return -EFAULT;
if (msg->cprbx.cprb_len + sizeof(msg->hdr.function_code) >
- xcRB->request_control_blk_length) {
- PDEBUG("cprb_len too large (%d/%d)\n", msg->cprbx.cprb_len,
- xcRB->request_control_blk_length);
+ xcRB->request_control_blk_length)
return -EFAULT;
- }
function_code = ((unsigned char *)&msg->cprbx) + msg->cprbx.cprb_len;
memcpy(msg->hdr.function_code, function_code, sizeof(msg->hdr.function_code));
@@ -471,29 +450,18 @@ static int convert_type86_ica(struct zcrypt_device *zdev,
service_rc = msg->cprbx.ccp_rtcode;
if (unlikely(service_rc != 0)) {
service_rs = msg->cprbx.ccp_rscode;
- if (service_rc == 8 && service_rs == 66) {
- PDEBUG("Bad block format on PCIXCC/CEX2C\n");
+ if (service_rc == 8 && service_rs == 66)
return -EINVAL;
- }
- if (service_rc == 8 && service_rs == 65) {
- PDEBUG("Probably an even modulus on PCIXCC/CEX2C\n");
+ if (service_rc == 8 && service_rs == 65)
return -EINVAL;
- }
- if (service_rc == 8 && service_rs == 770) {
- PDEBUG("Invalid key length on PCIXCC/CEX2C\n");
+ if (service_rc == 8 && service_rs == 770)
return -EINVAL;
- }
if (service_rc == 8 && service_rs == 783) {
- PDEBUG("Extended bitlengths not enabled on PCIXCC/CEX2C\n");
zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE_OLD;
return -EAGAIN;
}
- if (service_rc == 12 && service_rs == 769) {
- PDEBUG("Invalid key on PCIXCC/CEX2C\n");
+ if (service_rc == 12 && service_rs == 769)
return -EINVAL;
- }
- PRINTK("Unknown service rc/rs (PCIXCC/CEX2C): %d/%d\n",
- service_rc, service_rs);
zdev->online = 0;
return -EAGAIN; /* repeat the request on a different device. */
}
@@ -569,11 +537,8 @@ static int convert_type86_rng(struct zcrypt_device *zdev,
} __attribute__((packed)) *msg = reply->message;
char *data = reply->message;
- if (msg->cprbx.ccp_rtcode != 0 || msg->cprbx.ccp_rscode != 0) {
- PDEBUG("RNG response error on PCIXCC/CEX2C rc=%hu/rs=%hu\n",
- rc, rs);
+ if (msg->cprbx.ccp_rtcode != 0 || msg->cprbx.ccp_rscode != 0)
return -EINVAL;
- }
memcpy(buffer, data + msg->fmt2.offset2, msg->fmt2.count2);
return msg->fmt2.count2;
}
@@ -598,9 +563,6 @@ static int convert_response_ica(struct zcrypt_device *zdev,
outputdata, outputdatalength);
/* no break, incorrect cprb version is an unknown response */
default: /* Unknown response type, this should NEVER EVER happen */
- PRINTK("Unrecognized Message Header: %08x%08x\n",
- *(unsigned int *) reply->message,
- *(unsigned int *) (reply->message+4));
zdev->online = 0;
return -EAGAIN; /* repeat the request on a different device. */
}
@@ -627,9 +589,6 @@ static int convert_response_xcrb(struct zcrypt_device *zdev,
return convert_type86_xcrb(zdev, reply, xcRB);
/* no break, incorrect cprb version is an unknown response */
default: /* Unknown response type, this should NEVER EVER happen */
- PRINTK("Unrecognized Message Header: %08x%08x\n",
- *(unsigned int *) reply->message,
- *(unsigned int *) (reply->message+4));
xcRB->status = 0x0008044DL; /* HDD_InvalidParm */
zdev->online = 0;
return -EAGAIN; /* repeat the request on a different device. */
@@ -653,9 +612,6 @@ static int convert_response_rng(struct zcrypt_device *zdev,
return convert_type86_rng(zdev, reply, data);
/* no break, incorrect cprb version is an unknown response */
default: /* Unknown response type, this should NEVER EVER happen */
- PRINTK("Unrecognized Message Header: %08x%08x\n",
- *(unsigned int *) reply->message,
- *(unsigned int *) (reply->message+4));
zdev->online = 0;
return -EAGAIN; /* repeat the request on a different device. */
}
@@ -700,10 +656,7 @@ static void zcrypt_pcixcc_receive(struct ap_device *ap_dev,
memcpy(msg->message, reply->message, length);
break;
default:
- PRINTK("Invalid internal response type: %i\n",
- resp_type->type);
- memcpy(msg->message, &error_reply,
- sizeof error_reply);
+ memcpy(msg->message, &error_reply, sizeof error_reply);
}
} else
memcpy(msg->message, reply->message, sizeof error_reply);