summaryrefslogtreecommitdiffstats
path: root/drivers/s390/crypto
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/crypto')
-rw-r--r--drivers/s390/crypto/ap_asm.h236
-rw-r--r--drivers/s390/crypto/ap_bus.c457
-rw-r--r--drivers/s390/crypto/ap_bus.h37
-rw-r--r--drivers/s390/crypto/ap_card.c51
-rw-r--r--drivers/s390/crypto/ap_queue.c58
-rw-r--r--drivers/s390/crypto/pkey_api.c93
-rw-r--r--drivers/s390/crypto/zcrypt_api.c30
-rw-r--r--drivers/s390/crypto/zcrypt_api.h2
-rw-r--r--drivers/s390/crypto/zcrypt_card.c33
-rw-r--r--drivers/s390/crypto/zcrypt_cca_key.h32
-rw-r--r--drivers/s390/crypto/zcrypt_cex2a.c2
-rw-r--r--drivers/s390/crypto/zcrypt_cex2a.h18
-rw-r--r--drivers/s390/crypto/zcrypt_cex4.c2
-rw-r--r--drivers/s390/crypto/zcrypt_error.h2
-rw-r--r--drivers/s390/crypto/zcrypt_msgtype50.c17
-rw-r--r--drivers/s390/crypto/zcrypt_msgtype50.h8
-rw-r--r--drivers/s390/crypto/zcrypt_msgtype6.c54
-rw-r--r--drivers/s390/crypto/zcrypt_msgtype6.h2
-rw-r--r--drivers/s390/crypto/zcrypt_pcixcc.c6
-rw-r--r--drivers/s390/crypto/zcrypt_pcixcc.h2
-rw-r--r--drivers/s390/crypto/zcrypt_queue.c27
21 files changed, 684 insertions, 485 deletions
diff --git a/drivers/s390/crypto/ap_asm.h b/drivers/s390/crypto/ap_asm.h
deleted file mode 100644
index 16b59ce5e01d..000000000000
--- a/drivers/s390/crypto/ap_asm.h
+++ /dev/null
@@ -1,236 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright IBM Corp. 2016
- * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
- *
- * Adjunct processor bus inline assemblies.
- */
-
-#ifndef _AP_ASM_H_
-#define _AP_ASM_H_
-
-#include <asm/isc.h>
-
-/**
- * ap_intructions_available() - Test if AP instructions are available.
- *
- * Returns 0 if the AP instructions are installed.
- */
-static inline int ap_instructions_available(void)
-{
- register unsigned long reg0 asm ("0") = AP_MKQID(0, 0);
- register unsigned long reg1 asm ("1") = -ENODEV;
- register unsigned long reg2 asm ("2") = 0UL;
-
- asm volatile(
- " .long 0xb2af0000\n" /* PQAP(TAPQ) */
- "0: la %1,0\n"
- "1:\n"
- EX_TABLE(0b, 1b)
- : "+d" (reg0), "+d" (reg1), "+d" (reg2) : : "cc");
- return reg1;
-}
-
-/**
- * ap_tapq(): Test adjunct processor queue.
- * @qid: The AP queue number
- * @info: Pointer to queue descriptor
- *
- * Returns AP queue status structure.
- */
-static inline struct ap_queue_status ap_tapq(ap_qid_t qid, unsigned long *info)
-{
- register unsigned long reg0 asm ("0") = qid;
- register struct ap_queue_status reg1 asm ("1");
- register unsigned long reg2 asm ("2") = 0UL;
-
- asm volatile(".long 0xb2af0000" /* PQAP(TAPQ) */
- : "+d" (reg0), "=d" (reg1), "+d" (reg2) : : "cc");
- if (info)
- *info = reg2;
- return reg1;
-}
-
-/**
- * ap_pqap_rapq(): Reset adjunct processor queue.
- * @qid: The AP queue number
- *
- * Returns AP queue status structure.
- */
-static inline struct ap_queue_status ap_rapq(ap_qid_t qid)
-{
- register unsigned long reg0 asm ("0") = qid | 0x01000000UL;
- register struct ap_queue_status reg1 asm ("1");
- register unsigned long reg2 asm ("2") = 0UL;
-
- asm volatile(
- ".long 0xb2af0000" /* PQAP(RAPQ) */
- : "+d" (reg0), "=d" (reg1), "+d" (reg2) : : "cc");
- return reg1;
-}
-
-/**
- * ap_aqic(): Control interruption for a specific AP.
- * @qid: The AP queue number
- * @qirqctrl: struct ap_qirq_ctrl (64 bit value)
- * @ind: The notification indicator byte
- *
- * Returns AP queue status.
- */
-static inline struct ap_queue_status ap_aqic(ap_qid_t qid,
- struct ap_qirq_ctrl qirqctrl,
- void *ind)
-{
- register unsigned long reg0 asm ("0") = qid | (3UL << 24);
- register struct ap_qirq_ctrl reg1_in asm ("1") = qirqctrl;
- register struct ap_queue_status reg1_out asm ("1");
- register void *reg2 asm ("2") = ind;
-
- asm volatile(
- ".long 0xb2af0000" /* PQAP(AQIC) */
- : "+d" (reg0), "+d" (reg1_in), "=d" (reg1_out), "+d" (reg2)
- :
- : "cc");
- return reg1_out;
-}
-
-/**
- * ap_qci(): Get AP configuration data
- *
- * Returns 0 on success, or -EOPNOTSUPP.
- */
-static inline int ap_qci(void *config)
-{
- register unsigned long reg0 asm ("0") = 0x04000000UL;
- register unsigned long reg1 asm ("1") = -EINVAL;
- register void *reg2 asm ("2") = (void *) config;
-
- asm volatile(
- ".long 0xb2af0000\n" /* PQAP(QCI) */
- "0: la %1,0\n"
- "1:\n"
- EX_TABLE(0b, 1b)
- : "+d" (reg0), "+d" (reg1), "+d" (reg2)
- :
- : "cc", "memory");
-
- return reg1;
-}
-
-/*
- * union ap_qact_ap_info - used together with the
- * ap_aqic() function to provide a convenient way
- * to handle the ap info needed by the qact function.
- */
-union ap_qact_ap_info {
- unsigned long val;
- struct {
- unsigned int : 3;
- unsigned int mode : 3;
- unsigned int : 26;
- unsigned int cat : 8;
- unsigned int : 8;
- unsigned char ver[2];
- };
-};
-
-/**
- * ap_qact(): Query AP combatibility type.
- * @qid: The AP queue number
- * @apinfo: On input the info about the AP queue. On output the
- * alternate AP queue info provided by the qact function
- * in GR2 is stored in.
- *
- * Returns AP queue status. Check response_code field for failures.
- */
-static inline struct ap_queue_status ap_qact(ap_qid_t qid, int ifbit,
- union ap_qact_ap_info *apinfo)
-{
- register unsigned long reg0 asm ("0") = qid | (5UL << 24)
- | ((ifbit & 0x01) << 22);
- register unsigned long reg1_in asm ("1") = apinfo->val;
- register struct ap_queue_status reg1_out asm ("1");
- register unsigned long reg2 asm ("2") = 0;
-
- asm volatile(
- ".long 0xb2af0000" /* PQAP(QACT) */
- : "+d" (reg0), "+d" (reg1_in), "=d" (reg1_out), "+d" (reg2)
- : : "cc");
- apinfo->val = reg2;
- return reg1_out;
-}
-
-/**
- * ap_nqap(): Send message to adjunct processor queue.
- * @qid: The AP queue number
- * @psmid: The program supplied message identifier
- * @msg: The message text
- * @length: The message length
- *
- * Returns AP queue status structure.
- * Condition code 1 on NQAP can't happen because the L bit is 1.
- * Condition code 2 on NQAP also means the send is incomplete,
- * because a segment boundary was reached. The NQAP is repeated.
- */
-static inline struct ap_queue_status ap_nqap(ap_qid_t qid,
- unsigned long long psmid,
- void *msg, size_t length)
-{
- register unsigned long reg0 asm ("0") = qid | 0x40000000UL;
- register struct ap_queue_status reg1 asm ("1");
- register unsigned long reg2 asm ("2") = (unsigned long) msg;
- register unsigned long reg3 asm ("3") = (unsigned long) length;
- register unsigned long reg4 asm ("4") = (unsigned int) (psmid >> 32);
- register unsigned long reg5 asm ("5") = psmid & 0xffffffff;
-
- asm volatile (
- "0: .long 0xb2ad0042\n" /* NQAP */
- " brc 2,0b"
- : "+d" (reg0), "=d" (reg1), "+d" (reg2), "+d" (reg3)
- : "d" (reg4), "d" (reg5)
- : "cc", "memory");
- return reg1;
-}
-
-/**
- * ap_dqap(): Receive message from adjunct processor queue.
- * @qid: The AP queue number
- * @psmid: Pointer to program supplied message identifier
- * @msg: The message text
- * @length: The message length
- *
- * Returns AP queue status structure.
- * Condition code 1 on DQAP means the receive has taken place
- * but only partially. The response is incomplete, hence the
- * DQAP is repeated.
- * Condition code 2 on DQAP also means the receive is incomplete,
- * this time because a segment boundary was reached. Again, the
- * DQAP is repeated.
- * Note that gpr2 is used by the DQAP instruction to keep track of
- * any 'residual' length, in case the instruction gets interrupted.
- * Hence it gets zeroed before the instruction.
- */
-static inline struct ap_queue_status ap_dqap(ap_qid_t qid,
- unsigned long long *psmid,
- void *msg, size_t length)
-{
- register unsigned long reg0 asm("0") = qid | 0x80000000UL;
- register struct ap_queue_status reg1 asm ("1");
- register unsigned long reg2 asm("2") = 0UL;
- register unsigned long reg4 asm("4") = (unsigned long) msg;
- register unsigned long reg5 asm("5") = (unsigned long) length;
- register unsigned long reg6 asm("6") = 0UL;
- register unsigned long reg7 asm("7") = 0UL;
-
-
- asm volatile(
- "0: .long 0xb2ae0064\n" /* DQAP */
- " brc 6,0b\n"
- : "+d" (reg0), "=d" (reg1), "+d" (reg2),
- "+d" (reg4), "+d" (reg5), "+d" (reg6), "+d" (reg7)
- : : "cc", "memory");
- *psmid = (((unsigned long long) reg6) << 32) + reg7;
- return reg1;
-}
-
-#endif /* _AP_ASM_H_ */
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c
index 35a0c2b52f82..ec891bc7d10a 100644
--- a/drivers/s390/crypto/ap_bus.c
+++ b/drivers/s390/crypto/ap_bus.c
@@ -34,9 +34,9 @@
#include <linux/crypto.h>
#include <linux/mod_devicetable.h>
#include <linux/debugfs.h>
+#include <linux/ctype.h>
#include "ap_bus.h"
-#include "ap_asm.h"
#include "ap_debug.h"
/*
@@ -44,19 +44,34 @@
*/
int ap_domain_index = -1; /* Adjunct Processor Domain Index */
static DEFINE_SPINLOCK(ap_domain_lock);
-module_param_named(domain, ap_domain_index, int, S_IRUSR|S_IRGRP);
+module_param_named(domain, ap_domain_index, int, 0440);
MODULE_PARM_DESC(domain, "domain index for ap devices");
EXPORT_SYMBOL(ap_domain_index);
-static int ap_thread_flag = 0;
-module_param_named(poll_thread, ap_thread_flag, int, S_IRUSR|S_IRGRP);
+static int ap_thread_flag;
+module_param_named(poll_thread, ap_thread_flag, int, 0440);
MODULE_PARM_DESC(poll_thread, "Turn on/off poll thread, default is 0 (off).");
+static char *apm_str;
+module_param_named(apmask, apm_str, charp, 0440);
+MODULE_PARM_DESC(apmask, "AP bus adapter mask.");
+
+static char *aqm_str;
+module_param_named(aqmask, aqm_str, charp, 0440);
+MODULE_PARM_DESC(aqmask, "AP bus domain mask.");
+
static struct device *ap_root_device;
DEFINE_SPINLOCK(ap_list_lock);
LIST_HEAD(ap_card_list);
+/* Default permissions (card and domain masking) */
+static struct ap_perms {
+ DECLARE_BITMAP(apm, AP_DEVICES);
+ DECLARE_BITMAP(aqm, AP_DOMAINS);
+} ap_perms;
+static DEFINE_MUTEX(ap_perms_mutex);
+
static struct ap_config_info *ap_configuration;
static bool initialised;
@@ -79,22 +94,26 @@ static DECLARE_WORK(ap_scan_work, ap_scan_bus);
static void ap_tasklet_fn(unsigned long);
static DECLARE_TASKLET(ap_tasklet, ap_tasklet_fn, 0);
static DECLARE_WAIT_QUEUE_HEAD(ap_poll_wait);
-static struct task_struct *ap_poll_kthread = NULL;
+static struct task_struct *ap_poll_kthread;
static DEFINE_MUTEX(ap_poll_thread_mutex);
static DEFINE_SPINLOCK(ap_poll_timer_lock);
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.*/
+/*
+ * 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;
/* Suspend flag */
static int ap_suspend_flag;
/* Maximum domain id */
static int ap_max_domain_id;
-/* Flag to check if domain was set through module parameter domain=. This is
+/*
+ * Flag to check if domain was set through module parameter domain=. This is
* important when supsend and resume is done in a z/VM environment where the
- * domain might change. */
-static int user_set_domain = 0;
+ * domain might change.
+ */
+static int user_set_domain;
static struct bus_type ap_bus_type;
/* Adapter interrupt definitions */
@@ -174,24 +193,6 @@ static inline int ap_qact_available(void)
return 0;
}
-/**
- * ap_test_queue(): Test adjunct processor queue.
- * @qid: The AP queue number
- * @tbit: Test facilities bit
- * @info: Pointer to queue descriptor
- *
- * Returns AP queue status structure.
- */
-struct ap_queue_status ap_test_queue(ap_qid_t qid,
- int tbit,
- unsigned long *info)
-{
- if (tbit)
- qid |= 1UL << 23; /* set T bit*/
- return ap_tapq(qid, info);
-}
-EXPORT_SYMBOL(ap_test_queue);
-
/*
* ap_query_configuration(): Fetch cryptographic config info
*
@@ -200,7 +201,7 @@ EXPORT_SYMBOL(ap_test_queue);
* is returned, e.g. if the PQAP(QCI) instruction is not
* available, the return value will be -EOPNOTSUPP.
*/
-int ap_query_configuration(struct ap_config_info *info)
+static inline int ap_query_configuration(struct ap_config_info *info)
{
if (!ap_configuration_available())
return -EOPNOTSUPP;
@@ -493,7 +494,7 @@ static int ap_poll_thread_start(void)
return 0;
mutex_lock(&ap_poll_thread_mutex);
ap_poll_kthread = kthread_run(ap_poll_thread, NULL, "appoll");
- rc = PTR_RET(ap_poll_kthread);
+ rc = PTR_ERR_OR_ZERO(ap_poll_kthread);
if (rc)
ap_poll_kthread = NULL;
mutex_unlock(&ap_poll_thread_mutex);
@@ -550,7 +551,7 @@ static int ap_bus_match(struct device *dev, struct device_driver *drv)
* It sets up a single environment variable DEV_TYPE which contains the
* hardware device type.
*/
-static int ap_uevent (struct device *dev, struct kobj_uevent_env *env)
+static int ap_uevent(struct device *dev, struct kobj_uevent_env *env)
{
struct ap_device *ap_dev = to_ap_dev(dev);
int retval = 0;
@@ -589,7 +590,7 @@ static int ap_dev_resume(struct device *dev)
static void ap_bus_suspend(void)
{
- AP_DBF(DBF_DEBUG, "ap_bus_suspend running\n");
+ AP_DBF(DBF_DEBUG, "%s running\n", __func__);
ap_suspend_flag = 1;
/*
@@ -626,7 +627,7 @@ static void ap_bus_resume(void)
{
int rc;
- AP_DBF(DBF_DEBUG, "ap_bus_resume running\n");
+ AP_DBF(DBF_DEBUG, "%s running\n", __func__);
/* remove all queue devices */
bus_for_each_dev(&ap_bus_type, NULL, NULL,
@@ -685,11 +686,97 @@ static struct bus_type ap_bus_type = {
.pm = &ap_bus_pm_ops,
};
+static int __ap_revise_reserved(struct device *dev, void *dummy)
+{
+ int rc, card, queue, devres, drvres;
+
+ if (is_queue_dev(dev)) {
+ card = AP_QID_CARD(to_ap_queue(dev)->qid);
+ queue = AP_QID_QUEUE(to_ap_queue(dev)->qid);
+ mutex_lock(&ap_perms_mutex);
+ devres = test_bit_inv(card, ap_perms.apm)
+ && test_bit_inv(queue, ap_perms.aqm);
+ mutex_unlock(&ap_perms_mutex);
+ drvres = to_ap_drv(dev->driver)->flags
+ & AP_DRIVER_FLAG_DEFAULT;
+ if (!!devres != !!drvres) {
+ AP_DBF(DBF_DEBUG, "reprobing queue=%02x.%04x\n",
+ card, queue);
+ rc = device_reprobe(dev);
+ }
+ }
+
+ return 0;
+}
+
+static void ap_bus_revise_bindings(void)
+{
+ bus_for_each_dev(&ap_bus_type, NULL, NULL, __ap_revise_reserved);
+}
+
+int ap_owned_by_def_drv(int card, int queue)
+{
+ int rc = 0;
+
+ if (card < 0 || card >= AP_DEVICES || queue < 0 || queue >= AP_DOMAINS)
+ return -EINVAL;
+
+ mutex_lock(&ap_perms_mutex);
+
+ if (test_bit_inv(card, ap_perms.apm)
+ && test_bit_inv(queue, ap_perms.aqm))
+ rc = 1;
+
+ mutex_unlock(&ap_perms_mutex);
+
+ return rc;
+}
+EXPORT_SYMBOL(ap_owned_by_def_drv);
+
+int ap_apqn_in_matrix_owned_by_def_drv(unsigned long *apm,
+ unsigned long *aqm)
+{
+ int card, queue, rc = 0;
+
+ mutex_lock(&ap_perms_mutex);
+
+ for (card = 0; !rc && card < AP_DEVICES; card++)
+ if (test_bit_inv(card, apm) &&
+ test_bit_inv(card, ap_perms.apm))
+ for (queue = 0; !rc && queue < AP_DOMAINS; queue++)
+ if (test_bit_inv(queue, aqm) &&
+ test_bit_inv(queue, ap_perms.aqm))
+ rc = 1;
+
+ mutex_unlock(&ap_perms_mutex);
+
+ return rc;
+}
+EXPORT_SYMBOL(ap_apqn_in_matrix_owned_by_def_drv);
+
static int ap_device_probe(struct device *dev)
{
struct ap_device *ap_dev = to_ap_dev(dev);
struct ap_driver *ap_drv = to_ap_drv(dev->driver);
- int rc;
+ int card, queue, devres, drvres, rc;
+
+ if (is_queue_dev(dev)) {
+ /*
+ * If the apqn is marked as reserved/used by ap bus and
+ * default drivers, only probe with drivers with the default
+ * flag set. If it is not marked, only probe with drivers
+ * with the default flag not set.
+ */
+ card = AP_QID_CARD(to_ap_queue(dev)->qid);
+ queue = AP_QID_QUEUE(to_ap_queue(dev)->qid);
+ mutex_lock(&ap_perms_mutex);
+ devres = test_bit_inv(card, ap_perms.apm)
+ && test_bit_inv(queue, ap_perms.aqm);
+ mutex_unlock(&ap_perms_mutex);
+ drvres = ap_drv->flags & AP_DRIVER_FLAG_DEFAULT;
+ if (!!devres != !!drvres)
+ return -ENODEV;
+ }
/* Add queue/card to list of active queues/cards */
spin_lock_bh(&ap_list_lock);
@@ -770,8 +857,163 @@ void ap_bus_force_rescan(void)
EXPORT_SYMBOL(ap_bus_force_rescan);
/*
+ * hex2bitmap() - parse hex mask string and set bitmap.
+ * Valid strings are "0x012345678" with at least one valid hex number.
+ * Rest of the bitmap to the right is padded with 0. No spaces allowed
+ * within the string, the leading 0x may be omitted.
+ * Returns the bitmask with exactly the bits set as given by the hex
+ * string (both in big endian order).
+ */
+static int hex2bitmap(const char *str, unsigned long *bitmap, int bits)
+{
+ int i, n, b;
+
+ /* bits needs to be a multiple of 8 */
+ if (bits & 0x07)
+ return -EINVAL;
+
+ memset(bitmap, 0, bits / 8);
+
+ if (str[0] == '0' && str[1] == 'x')
+ str++;
+ if (*str == 'x')
+ str++;
+
+ for (i = 0; isxdigit(*str) && i < bits; str++) {
+ b = hex_to_bin(*str);
+ for (n = 0; n < 4; n++)
+ if (b & (0x08 >> n))
+ set_bit_inv(i + n, bitmap);
+ i += 4;
+ }
+
+ if (*str == '\n')
+ str++;
+ if (*str)
+ return -EINVAL;
+ return 0;
+}
+
+/*
+ * str2clrsetmasks() - parse bitmask argument and set the clear and
+ * the set bitmap mask. A concatenation (done with ',') of these terms
+ * is recognized:
+ * +<bitnr>[-<bitnr>] or -<bitnr>[-<bitnr>]
+ * <bitnr> may be any valid number (hex, decimal or octal) in the range
+ * 0...bits-1; the leading + or - is required. Here are some examples:
+ * +0-15,+32,-128,-0xFF
+ * -0-255,+1-16,+0x128
+ * +1,+2,+3,+4,-5,-7-10
+ * Returns a clear and a set bitmask. Every positive value in the string
+ * results in a bit set in the set mask and every negative value in the
+ * string results in a bit SET in the clear mask. As a bit may be touched
+ * more than once, the last 'operation' wins: +0-255,-128 = all but bit
+ * 128 set in the set mask, only bit 128 set in the clear mask.
+ */
+static int str2clrsetmasks(const char *str,
+ unsigned long *clrmap,
+ unsigned long *setmap,
+ int bits)
+{
+ int a, i, z;
+ char *np, sign;
+
+ /* bits needs to be a multiple of 8 */
+ if (bits & 0x07)
+ return -EINVAL;
+
+ memset(clrmap, 0, bits / 8);
+ memset(setmap, 0, bits / 8);
+
+ while (*str) {
+ sign = *str++;
+ if (sign != '+' && sign != '-')
+ return -EINVAL;
+ a = z = simple_strtoul(str, &np, 0);
+ if (str == np || a >= bits)
+ return -EINVAL;
+ str = np;
+ if (*str == '-') {
+ z = simple_strtoul(++str, &np, 0);
+ if (str == np || a > z || z >= bits)
+ return -EINVAL;
+ str = np;
+ }
+ for (i = a; i <= z; i++)
+ if (sign == '+') {
+ set_bit_inv(i, setmap);
+ clear_bit_inv(i, clrmap);
+ } else {
+ clear_bit_inv(i, setmap);
+ set_bit_inv(i, clrmap);
+ }
+ while (*str == ',' || *str == '\n')
+ str++;
+ }
+
+ return 0;
+}
+
+/*
+ * process_mask_arg() - parse a bitmap string and clear/set the
+ * bits in the bitmap accordingly. The string may be given as
+ * absolute value, a hex string like 0x1F2E3D4C5B6A" simple over-
+ * writing the current content of the bitmap. Or as relative string
+ * like "+1-16,-32,-0x40,+128" where only single bits or ranges of
+ * bits are cleared or set. Distinction is done based on the very
+ * first character which may be '+' or '-' for the relative string
+ * and othewise assume to be an absolute value string. If parsing fails
+ * a negative errno value is returned. All arguments and bitmaps are
+ * big endian order.
+ */
+static int process_mask_arg(const char *str,
+ unsigned long *bitmap, int bits,
+ struct mutex *lock)
+{
+ int i;
+
+ /* bits needs to be a multiple of 8 */
+ if (bits & 0x07)
+ return -EINVAL;
+
+ if (*str == '+' || *str == '-') {
+ DECLARE_BITMAP(clrm, bits);
+ DECLARE_BITMAP(setm, bits);
+
+ i = str2clrsetmasks(str, clrm, setm, bits);
+ if (i)
+ return i;
+ if (mutex_lock_interruptible(lock))
+ return -ERESTARTSYS;
+ for (i = 0; i < bits; i++) {
+ if (test_bit_inv(i, clrm))
+ clear_bit_inv(i, bitmap);
+ if (test_bit_inv(i, setm))
+ set_bit_inv(i, bitmap);
+ }
+ } else {
+ DECLARE_BITMAP(setm, bits);
+
+ i = hex2bitmap(str, setm, bits);
+ if (i)
+ return i;
+ if (mutex_lock_interruptible(lock))
+ return -ERESTARTSYS;
+ for (i = 0; i < bits; i++)
+ if (test_bit_inv(i, setm))
+ set_bit_inv(i, bitmap);
+ else
+ clear_bit_inv(i, bitmap);
+ }
+ mutex_unlock(lock);
+
+ return 0;
+}
+
+/*
* AP bus attributes.
*/
+
static ssize_t ap_domain_show(struct bus_type *bus, char *buf)
{
return snprintf(buf, PAGE_SIZE, "%d\n", ap_domain_index);
@@ -783,7 +1025,8 @@ static ssize_t ap_domain_store(struct bus_type *bus,
int domain;
if (sscanf(buf, "%i\n", &domain) != 1 ||
- domain < 0 || domain > ap_max_domain_id)
+ domain < 0 || domain > ap_max_domain_id ||
+ !test_bit_inv(domain, ap_perms.aqm))
return -EINVAL;
spin_lock_bh(&ap_domain_lock);
ap_domain_index = domain;
@@ -794,7 +1037,7 @@ static ssize_t ap_domain_store(struct bus_type *bus,
return count;
}
-static BUS_ATTR(ap_domain, 0644, ap_domain_show, ap_domain_store);
+static BUS_ATTR_RW(ap_domain);
static ssize_t ap_control_domain_mask_show(struct bus_type *bus, char *buf)
{
@@ -809,8 +1052,7 @@ static ssize_t ap_control_domain_mask_show(struct bus_type *bus, char *buf)
ap_configuration->adm[6], ap_configuration->adm[7]);
}
-static BUS_ATTR(ap_control_domain_mask, 0444,
- ap_control_domain_mask_show, NULL);
+static BUS_ATTR_RO(ap_control_domain_mask);
static ssize_t ap_usage_domain_mask_show(struct bus_type *bus, char *buf)
{
@@ -825,13 +1067,7 @@ static ssize_t ap_usage_domain_mask_show(struct bus_type *bus, char *buf)
ap_configuration->aqm[6], ap_configuration->aqm[7]);
}
-static BUS_ATTR(ap_usage_domain_mask, 0444,
- ap_usage_domain_mask_show, NULL);
-
-static ssize_t ap_config_time_show(struct bus_type *bus, char *buf)
-{
- return snprintf(buf, PAGE_SIZE, "%d\n", ap_config_time);
-}
+static BUS_ATTR_RO(ap_usage_domain_mask);
static ssize_t ap_interrupts_show(struct bus_type *bus, char *buf)
{
@@ -839,10 +1075,15 @@ static ssize_t ap_interrupts_show(struct bus_type *bus, char *buf)
ap_using_interrupts() ? 1 : 0);
}
-static BUS_ATTR(ap_interrupts, 0444, ap_interrupts_show, NULL);
+static BUS_ATTR_RO(ap_interrupts);
-static ssize_t ap_config_time_store(struct bus_type *bus,
- const char *buf, size_t count)
+static ssize_t config_time_show(struct bus_type *bus, char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "%d\n", ap_config_time);
+}
+
+static ssize_t config_time_store(struct bus_type *bus,
+ const char *buf, size_t count)
{
int time;
@@ -853,15 +1094,15 @@ static ssize_t ap_config_time_store(struct bus_type *bus,
return count;
}
-static BUS_ATTR(config_time, 0644, ap_config_time_show, ap_config_time_store);
+static BUS_ATTR_RW(config_time);
-static ssize_t ap_poll_thread_show(struct bus_type *bus, char *buf)
+static ssize_t poll_thread_show(struct bus_type *bus, char *buf)
{
return snprintf(buf, PAGE_SIZE, "%d\n", ap_poll_kthread ? 1 : 0);
}
-static ssize_t ap_poll_thread_store(struct bus_type *bus,
- const char *buf, size_t count)
+static ssize_t poll_thread_store(struct bus_type *bus,
+ const char *buf, size_t count)
{
int flag, rc;
@@ -876,7 +1117,7 @@ static ssize_t ap_poll_thread_store(struct bus_type *bus,
return count;
}
-static BUS_ATTR(poll_thread, 0644, ap_poll_thread_show, ap_poll_thread_store);
+static BUS_ATTR_RW(poll_thread);
static ssize_t poll_timeout_show(struct bus_type *bus, char *buf)
{
@@ -905,7 +1146,7 @@ static ssize_t poll_timeout_store(struct bus_type *bus, const char *buf,
return count;
}
-static BUS_ATTR(poll_timeout, 0644, poll_timeout_show, poll_timeout_store);
+static BUS_ATTR_RW(poll_timeout);
static ssize_t ap_max_domain_id_show(struct bus_type *bus, char *buf)
{
@@ -918,7 +1159,69 @@ static ssize_t ap_max_domain_id_show(struct bus_type *bus, char *buf)
return snprintf(buf, PAGE_SIZE, "%d\n", max_domain_id);
}
-static BUS_ATTR(ap_max_domain_id, 0444, ap_max_domain_id_show, NULL);
+static BUS_ATTR_RO(ap_max_domain_id);
+
+static ssize_t apmask_show(struct bus_type *bus, char *buf)
+{
+ int rc;
+
+ if (mutex_lock_interruptible(&ap_perms_mutex))
+ return -ERESTARTSYS;
+ rc = snprintf(buf, PAGE_SIZE,
+ "0x%016lx%016lx%016lx%016lx\n",
+ ap_perms.apm[0], ap_perms.apm[1],
+ ap_perms.apm[2], ap_perms.apm[3]);
+ mutex_unlock(&ap_perms_mutex);
+
+ return rc;
+}
+
+static ssize_t apmask_store(struct bus_type *bus, const char *buf,
+ size_t count)
+{
+ int rc;
+
+ rc = process_mask_arg(buf, ap_perms.apm, AP_DEVICES, &ap_perms_mutex);
+ if (rc)
+ return rc;
+
+ ap_bus_revise_bindings();
+
+ return count;
+}
+
+static BUS_ATTR_RW(apmask);
+
+static ssize_t aqmask_show(struct bus_type *bus, char *buf)
+{
+ int rc;
+
+ if (mutex_lock_interruptible(&ap_perms_mutex))
+ return -ERESTARTSYS;
+ rc = snprintf(buf, PAGE_SIZE,
+ "0x%016lx%016lx%016lx%016lx\n",
+ ap_perms.aqm[0], ap_perms.aqm[1],
+ ap_perms.aqm[2], ap_perms.aqm[3]);
+ mutex_unlock(&ap_perms_mutex);
+
+ return rc;
+}
+
+static ssize_t aqmask_store(struct bus_type *bus, const char *buf,
+ size_t count)
+{
+ int rc;
+
+ rc = process_mask_arg(buf, ap_perms.aqm, AP_DOMAINS, &ap_perms_mutex);
+ if (rc)
+ return rc;
+
+ ap_bus_revise_bindings();
+
+ return count;
+}
+
+static BUS_ATTR_RW(aqmask);
static struct bus_attribute *const ap_bus_attrs[] = {
&bus_attr_ap_domain,
@@ -929,6 +1232,8 @@ static struct bus_attribute *const ap_bus_attrs[] = {
&bus_attr_ap_interrupts,
&bus_attr_poll_timeout,
&bus_attr_ap_max_domain_id,
+ &bus_attr_apmask,
+ &bus_attr_aqmask,
NULL,
};
@@ -957,7 +1262,8 @@ static int 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_domain(i) ||
+ !test_bit_inv(i, ap_perms.aqm))
continue;
count = 0;
for (j = 0; j < AP_DEVICES; j++) {
@@ -975,7 +1281,7 @@ static int ap_select_domain(void)
best_domain = i;
}
}
- if (best_domain >= 0){
+ if (best_domain >= 0) {
ap_domain_index = best_domain;
AP_DBF(DBF_DEBUG, "new ap_domain_index=%d\n", ap_domain_index);
spin_unlock_bh(&ap_domain_lock);
@@ -1057,7 +1363,7 @@ static void ap_scan_bus(struct work_struct *unused)
unsigned int func = 0;
int rc, id, dom, borked, domains, defdomdevs = 0;
- AP_DBF(DBF_DEBUG, "ap_scan_bus running\n");
+ AP_DBF(DBF_DEBUG, "%s running\n", __func__);
ap_query_configuration(ap_configuration);
if (ap_select_domain() != 0)
@@ -1182,7 +1488,8 @@ static void ap_scan_bus(struct work_struct *unused)
} /* end device loop */
if (defdomdevs < 1)
- AP_DBF(DBF_INFO, "no queue device with default domain %d available\n",
+ AP_DBF(DBF_INFO,
+ "no queue device with default domain %d available\n",
ap_domain_index);
out:
@@ -1206,6 +1513,27 @@ static int __init ap_debug_init(void)
return 0;
}
+static void __init ap_perms_init(void)
+{
+ /* all resources useable if no kernel parameter string given */
+ memset(&ap_perms.apm, 0xFF, sizeof(ap_perms.apm));
+ memset(&ap_perms.aqm, 0xFF, sizeof(ap_perms.aqm));
+
+ /* apm kernel parameter string */
+ if (apm_str) {
+ memset(&ap_perms.apm, 0, sizeof(ap_perms.apm));
+ process_mask_arg(apm_str, ap_perms.apm, AP_DEVICES,
+ &ap_perms_mutex);
+ }
+
+ /* aqm kernel parameter string */
+ if (aqm_str) {
+ memset(&ap_perms.aqm, 0, sizeof(ap_perms.aqm));
+ process_mask_arg(aqm_str, ap_perms.aqm, AP_DOMAINS,
+ &ap_perms_mutex);
+ }
+}
+
/**
* ap_module_init(): The module initialization code.
*
@@ -1220,11 +1548,14 @@ static int __init ap_module_init(void)
if (rc)
return rc;
- if (ap_instructions_available() != 0) {
+ if (!ap_instructions_available()) {
pr_warn("The hardware system does not support AP instructions\n");
return -ENODEV;
}
+ /* set up the AP permissions (ap and aq masks) */
+ ap_perms_init();
+
/* Get AP configuration data if available */
ap_init_configuration();
@@ -1233,7 +1564,9 @@ static int __init ap_module_init(void)
ap_max_domain_id ? ap_max_domain_id : AP_DOMAINS - 1;
else
max_domain_id = 15;
- if (ap_domain_index < -1 || ap_domain_index > max_domain_id) {
+ if (ap_domain_index < -1 || ap_domain_index > max_domain_id ||
+ (ap_domain_index >= 0 &&
+ !test_bit_inv(ap_domain_index, ap_perms.aqm))) {
pr_warn("%d is not a valid cryptographic domain\n",
ap_domain_index);
ap_domain_index = -1;
@@ -1261,7 +1594,7 @@ static int __init ap_module_init(void)
/* Create /sys/devices/ap. */
ap_root_device = root_device_register("ap");
- rc = PTR_RET(ap_root_device);
+ rc = PTR_ERR_OR_ZERO(ap_root_device);
if (rc)
goto out_bus;
diff --git a/drivers/s390/crypto/ap_bus.h b/drivers/s390/crypto/ap_bus.h
index 6a273c5ebca5..5246cd8c16a6 100644
--- a/drivers/s390/crypto/ap_bus.h
+++ b/drivers/s390/crypto/ap_bus.h
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0+
+/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright IBM Corp. 2006, 2012
* Author(s): Cornelia Huck <cornelia.huck@de.ibm.com>
@@ -15,6 +15,7 @@
#include <linux/device.h>
#include <linux/types.h>
+#include <asm/isc.h>
#include <asm/ap.h>
#define AP_DEVICES 256 /* Number of AP devices. */
@@ -116,9 +117,18 @@ enum ap_wait {
struct ap_device;
struct ap_message;
+/*
+ * The ap driver struct includes a flags field which holds some info for
+ * the ap bus about the driver. Currently only one flag is supported and
+ * used: The DEFAULT flag marks an ap driver as a default driver which is
+ * used together with the apmask and aqmask whitelisting of the ap bus.
+ */
+#define AP_DRIVER_FLAG_DEFAULT 0x0001
+
struct ap_driver {
struct device_driver driver;
struct ap_device_id *ids;
+ unsigned int flags;
int (*probe)(struct ap_device *);
void (*remove)(struct ap_device *);
@@ -166,7 +176,7 @@ struct ap_queue {
int pendingq_count; /* # requests on pendingq list. */
int requestq_count; /* # requests on requestq list. */
int total_request_count; /* # requests ever for this AP device.*/
- int request_timeout; /* Request timout in jiffies. */
+ int request_timeout; /* Request timeout in jiffies. */
struct timer_list timeout; /* Timer for request timeouts. */
struct list_head pendingq; /* List of message sent to AP queue. */
struct list_head requestq; /* List of message yet to be sent. */
@@ -247,4 +257,27 @@ void ap_queue_resume(struct ap_device *ap_dev);
struct ap_card *ap_card_create(int id, int queue_depth, int raw_device_type,
int comp_device_type, unsigned int functions);
+/*
+ * check APQN for owned/reserved by ap bus and default driver(s).
+ * Checks if this APQN is or will be in use by the ap bus
+ * and the default set of drivers.
+ * If yes, returns 1, if not returns 0. On error a negative
+ * errno value is returned.
+ */
+int ap_owned_by_def_drv(int card, int queue);
+
+/*
+ * check 'matrix' of APQNs for owned/reserved by ap bus and
+ * default driver(s).
+ * Checks if there is at least one APQN in the given 'matrix'
+ * marked as owned/reserved by the ap bus and default driver(s).
+ * If such an APQN is found the return value is 1, otherwise
+ * 0 is returned. On error a negative errno value is returned.
+ * The parameter apm is a bitmask which should be declared
+ * as DECLARE_BITMAP(apm, AP_DEVICES), the aqm parameter is
+ * similar, should be declared as DECLARE_BITMAP(aqm, AP_DOMAINS).
+ */
+int ap_apqn_in_matrix_owned_by_def_drv(unsigned long *apm,
+ unsigned long *aqm);
+
#endif /* _AP_BUS_H_ */
diff --git a/drivers/s390/crypto/ap_card.c b/drivers/s390/crypto/ap_card.c
index 2c726df210f6..63b4cc6cd7e5 100644
--- a/drivers/s390/crypto/ap_card.c
+++ b/drivers/s390/crypto/ap_card.c
@@ -14,40 +14,39 @@
#include <asm/facility.h>
#include "ap_bus.h"
-#include "ap_asm.h"
/*
* AP card related attributes.
*/
-static ssize_t ap_hwtype_show(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t hwtype_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct ap_card *ac = to_ap_card(dev);
return snprintf(buf, PAGE_SIZE, "%d\n", ac->ap_dev.device_type);
}
-static DEVICE_ATTR(hwtype, 0444, ap_hwtype_show, NULL);
+static DEVICE_ATTR_RO(hwtype);
-static ssize_t ap_raw_hwtype_show(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t raw_hwtype_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct ap_card *ac = to_ap_card(dev);
return snprintf(buf, PAGE_SIZE, "%d\n", ac->raw_hwtype);
}
-static DEVICE_ATTR(raw_hwtype, 0444, ap_raw_hwtype_show, NULL);
+static DEVICE_ATTR_RO(raw_hwtype);
-static ssize_t ap_depth_show(struct device *dev, struct device_attribute *attr,
- char *buf)
+static ssize_t depth_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
struct ap_card *ac = to_ap_card(dev);
return snprintf(buf, PAGE_SIZE, "%d\n", ac->queue_depth);
}
-static DEVICE_ATTR(depth, 0444, ap_depth_show, NULL);
+static DEVICE_ATTR_RO(depth);
static ssize_t ap_functions_show(struct device *dev,
struct device_attribute *attr, char *buf)
@@ -59,9 +58,9 @@ static ssize_t ap_functions_show(struct device *dev,
static DEVICE_ATTR_RO(ap_functions);
-static ssize_t ap_req_count_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
+static ssize_t request_count_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
{
struct ap_card *ac = to_ap_card(dev);
unsigned int req_cnt;
@@ -73,9 +72,9 @@ static ssize_t ap_req_count_show(struct device *dev,
return snprintf(buf, PAGE_SIZE, "%d\n", req_cnt);
}
-static ssize_t ap_req_count_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
+static ssize_t request_count_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
{
struct ap_card *ac = to_ap_card(dev);
struct ap_queue *aq;
@@ -89,10 +88,10 @@ static ssize_t ap_req_count_store(struct device *dev,
return count;
}
-static DEVICE_ATTR(request_count, 0644, ap_req_count_show, ap_req_count_store);
+static DEVICE_ATTR_RW(request_count);
-static ssize_t ap_requestq_count_show(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t requestq_count_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct ap_card *ac = to_ap_card(dev);
struct ap_queue *aq;
@@ -106,10 +105,10 @@ static ssize_t ap_requestq_count_show(struct device *dev,
return snprintf(buf, PAGE_SIZE, "%d\n", reqq_cnt);
}
-static DEVICE_ATTR(requestq_count, 0444, ap_requestq_count_show, NULL);
+static DEVICE_ATTR_RO(requestq_count);
-static ssize_t ap_pendingq_count_show(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t pendingq_count_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct ap_card *ac = to_ap_card(dev);
struct ap_queue *aq;
@@ -123,15 +122,15 @@ static ssize_t ap_pendingq_count_show(struct device *dev,
return snprintf(buf, PAGE_SIZE, "%d\n", penq_cnt);
}
-static DEVICE_ATTR(pendingq_count, 0444, ap_pendingq_count_show, NULL);
+static DEVICE_ATTR_RO(pendingq_count);
-static ssize_t ap_modalias_show(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t modalias_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
return sprintf(buf, "ap:t%02X\n", to_ap_dev(dev)->device_type);
}
-static DEVICE_ATTR(modalias, 0444, ap_modalias_show, NULL);
+static DEVICE_ATTR_RO(modalias);
static struct attribute *ap_card_dev_attrs[] = {
&dev_attr_hwtype.attr,
diff --git a/drivers/s390/crypto/ap_queue.c b/drivers/s390/crypto/ap_queue.c
index ba3a2e13b0eb..66f7334bcb03 100644
--- a/drivers/s390/crypto/ap_queue.c
+++ b/drivers/s390/crypto/ap_queue.c
@@ -14,26 +14,6 @@
#include <asm/facility.h>
#include "ap_bus.h"
-#include "ap_asm.h"
-
-/**
- * ap_queue_irq_ctrl(): Control interruption on a AP queue.
- * @qirqctrl: struct ap_qirq_ctrl (64 bit value)
- * @ind: The notification indicator byte
- *
- * Returns AP queue status.
- *
- * Control interruption on the given AP queue.
- * Just a simple wrapper function for the low level PQAP(AQIC)
- * instruction available for other kernel modules.
- */
-struct ap_queue_status ap_queue_irq_ctrl(ap_qid_t qid,
- struct ap_qirq_ctrl qirqctrl,
- void *ind)
-{
- return ap_aqic(qid, qirqctrl, ind);
-}
-EXPORT_SYMBOL(ap_queue_irq_ctrl);
/**
* ap_queue_enable_interruption(): Enable interruption on an AP queue.
@@ -482,9 +462,9 @@ EXPORT_SYMBOL(ap_queue_resume);
/*
* AP queue related attributes.
*/
-static ssize_t ap_req_count_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
+static ssize_t request_count_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
{
struct ap_queue *aq = to_ap_queue(dev);
unsigned int req_cnt;
@@ -495,9 +475,9 @@ static ssize_t ap_req_count_show(struct device *dev,
return snprintf(buf, PAGE_SIZE, "%d\n", req_cnt);
}
-static ssize_t ap_req_count_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
+static ssize_t request_count_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
{
struct ap_queue *aq = to_ap_queue(dev);
@@ -508,10 +488,10 @@ static ssize_t ap_req_count_store(struct device *dev,
return count;
}
-static DEVICE_ATTR(request_count, 0644, ap_req_count_show, ap_req_count_store);
+static DEVICE_ATTR_RW(request_count);
-static ssize_t ap_requestq_count_show(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t requestq_count_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct ap_queue *aq = to_ap_queue(dev);
unsigned int reqq_cnt = 0;
@@ -522,10 +502,10 @@ static ssize_t ap_requestq_count_show(struct device *dev,
return snprintf(buf, PAGE_SIZE, "%d\n", reqq_cnt);
}
-static DEVICE_ATTR(requestq_count, 0444, ap_requestq_count_show, NULL);
+static DEVICE_ATTR_RO(requestq_count);
-static ssize_t ap_pendingq_count_show(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t pendingq_count_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct ap_queue *aq = to_ap_queue(dev);
unsigned int penq_cnt = 0;
@@ -536,10 +516,10 @@ static ssize_t ap_pendingq_count_show(struct device *dev,
return snprintf(buf, PAGE_SIZE, "%d\n", penq_cnt);
}
-static DEVICE_ATTR(pendingq_count, 0444, ap_pendingq_count_show, NULL);
+static DEVICE_ATTR_RO(pendingq_count);
-static ssize_t ap_reset_show(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t reset_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct ap_queue *aq = to_ap_queue(dev);
int rc = 0;
@@ -561,10 +541,10 @@ static ssize_t ap_reset_show(struct device *dev,
return rc;
}
-static DEVICE_ATTR(reset, 0444, ap_reset_show, NULL);
+static DEVICE_ATTR_RO(reset);
-static ssize_t ap_interrupt_show(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t interrupt_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct ap_queue *aq = to_ap_queue(dev);
int rc = 0;
@@ -580,7 +560,7 @@ static ssize_t ap_interrupt_show(struct device *dev,
return rc;
}
-static DEVICE_ATTR(interrupt, 0444, ap_interrupt_show, NULL);
+static DEVICE_ATTR_RO(interrupt);
static struct attribute *ap_queue_dev_attrs[] = {
&dev_attr_request_count.attr,
diff --git a/drivers/s390/crypto/pkey_api.c b/drivers/s390/crypto/pkey_api.c
index 3929c8be8098..1b4001e0285f 100644
--- a/drivers/s390/crypto/pkey_api.c
+++ b/drivers/s390/crypto/pkey_api.c
@@ -82,20 +82,20 @@ static int check_secaeskeytoken(const u8 *token, int keybitsize)
if (t->type != 0x01) {
DEBUG_ERR(
- "check_secaeskeytoken secure token check failed, type mismatch 0x%02x != 0x01\n",
- (int) t->type);
+ "%s secure token check failed, type mismatch 0x%02x != 0x01\n",
+ __func__, (int) t->type);
return -EINVAL;
}
if (t->version != 0x04) {
DEBUG_ERR(
- "check_secaeskeytoken secure token check failed, version mismatch 0x%02x != 0x04\n",
- (int) t->version);
+ "%s secure token check failed, version mismatch 0x%02x != 0x04\n",
+ __func__, (int) t->version);
return -EINVAL;
}
if (keybitsize > 0 && t->bitsize != keybitsize) {
DEBUG_ERR(
- "check_secaeskeytoken secure token check failed, bitsize mismatch %d != %d\n",
- (int) t->bitsize, keybitsize);
+ "%s secure token check failed, bitsize mismatch %d != %d\n",
+ __func__, (int) t->bitsize, keybitsize);
return -EINVAL;
}
@@ -270,8 +270,8 @@ int pkey_genseckey(u16 cardnr, u16 domain,
break;
default:
DEBUG_ERR(
- "pkey_genseckey unknown/unsupported keytype %d\n",
- keytype);
+ "%s unknown/unsupported keytype %d\n",
+ __func__, keytype);
rc = -EINVAL;
goto out;
}
@@ -290,15 +290,16 @@ int pkey_genseckey(u16 cardnr, u16 domain,
rc = _zcrypt_send_cprb(&xcrb);
if (rc) {
DEBUG_ERR(
- "pkey_genseckey zcrypt_send_cprb (cardnr=%d domain=%d) failed with errno %d\n",
- (int) cardnr, (int) domain, rc);
+ "%s zcrypt_send_cprb (cardnr=%d domain=%d) failed with errno %d\n",
+ __func__, (int) cardnr, (int) domain, rc);
goto out;
}
/* check response returncode and reasoncode */
if (prepcblk->ccp_rtcode != 0) {
DEBUG_ERR(
- "pkey_genseckey secure key generate failure, card response %d/%d\n",
+ "%s secure key generate failure, card response %d/%d\n",
+ __func__,
(int) prepcblk->ccp_rtcode,
(int) prepcblk->ccp_rscode);
rc = -EIO;
@@ -315,8 +316,8 @@ int pkey_genseckey(u16 cardnr, u16 domain,
- sizeof(prepparm->lv3.keyblock.tokattr);
if (seckeysize != SECKEYBLOBSIZE) {
DEBUG_ERR(
- "pkey_genseckey secure token size mismatch %d != %d bytes\n",
- seckeysize, SECKEYBLOBSIZE);
+ "%s secure token size mismatch %d != %d bytes\n",
+ __func__, seckeysize, SECKEYBLOBSIZE);
rc = -EIO;
goto out;
}
@@ -407,8 +408,8 @@ int pkey_clr2seckey(u16 cardnr, u16 domain, u32 keytype,
break;
default:
DEBUG_ERR(
- "pkey_clr2seckey unknown/unsupported keytype %d\n",
- keytype);
+ "%s unknown/unsupported keytype %d\n",
+ __func__, keytype);
rc = -EINVAL;
goto out;
}
@@ -427,15 +428,16 @@ int pkey_clr2seckey(u16 cardnr, u16 domain, u32 keytype,
rc = _zcrypt_send_cprb(&xcrb);
if (rc) {
DEBUG_ERR(
- "pkey_clr2seckey zcrypt_send_cprb (cardnr=%d domain=%d) failed with errno %d\n",
- (int) cardnr, (int) domain, rc);
+ "%s zcrypt_send_cprb (cardnr=%d domain=%d) failed with errno %d\n",
+ __func__, (int) cardnr, (int) domain, rc);
goto out;
}
/* check response returncode and reasoncode */
if (prepcblk->ccp_rtcode != 0) {
DEBUG_ERR(
- "pkey_clr2seckey clear key import failure, card response %d/%d\n",
+ "%s clear key import failure, card response %d/%d\n",
+ __func__,
(int) prepcblk->ccp_rtcode,
(int) prepcblk->ccp_rscode);
rc = -EIO;
@@ -452,8 +454,8 @@ int pkey_clr2seckey(u16 cardnr, u16 domain, u32 keytype,
- sizeof(prepparm->lv3.keyblock.tokattr);
if (seckeysize != SECKEYBLOBSIZE) {
DEBUG_ERR(
- "pkey_clr2seckey secure token size mismatch %d != %d bytes\n",
- seckeysize, SECKEYBLOBSIZE);
+ "%s secure token size mismatch %d != %d bytes\n",
+ __func__, seckeysize, SECKEYBLOBSIZE);
rc = -EIO;
goto out;
}
@@ -553,15 +555,16 @@ int pkey_sec2protkey(u16 cardnr, u16 domain,
rc = _zcrypt_send_cprb(&xcrb);
if (rc) {
DEBUG_ERR(
- "pkey_sec2protkey zcrypt_send_cprb (cardnr=%d domain=%d) failed with errno %d\n",
- (int) cardnr, (int) domain, rc);
+ "%s zcrypt_send_cprb (cardnr=%d domain=%d) failed with errno %d\n",
+ __func__, (int) cardnr, (int) domain, rc);
goto out;
}
/* check response returncode and reasoncode */
if (prepcblk->ccp_rtcode != 0) {
DEBUG_ERR(
- "pkey_sec2protkey unwrap secure key failure, card response %d/%d\n",
+ "%s unwrap secure key failure, card response %d/%d\n",
+ __func__,
(int) prepcblk->ccp_rtcode,
(int) prepcblk->ccp_rscode);
rc = -EIO;
@@ -569,7 +572,8 @@ int pkey_sec2protkey(u16 cardnr, u16 domain,
}
if (prepcblk->ccp_rscode != 0) {
DEBUG_WARN(
- "pkey_sec2protkey unwrap secure key warning, card response %d/%d\n",
+ "%s unwrap secure key warning, card response %d/%d\n",
+ __func__,
(int) prepcblk->ccp_rtcode,
(int) prepcblk->ccp_rscode);
}
@@ -581,8 +585,8 @@ int pkey_sec2protkey(u16 cardnr, u16 domain,
/* check the returned keyblock */
if (prepparm->lv3.keyblock.version != 0x01) {
DEBUG_ERR(
- "pkey_sec2protkey reply param keyblock version mismatch 0x%02x != 0x01\n",
- (int) prepparm->lv3.keyblock.version);
+ "%s reply param keyblock version mismatch 0x%02x != 0x01\n",
+ __func__, (int) prepparm->lv3.keyblock.version);
rc = -EIO;
goto out;
}
@@ -599,8 +603,8 @@ int pkey_sec2protkey(u16 cardnr, u16 domain,
protkey->type = PKEY_KEYTYPE_AES_256;
break;
default:
- DEBUG_ERR("pkey_sec2protkey unknown/unsupported keytype %d\n",
- prepparm->lv3.keyblock.keylen);
+ DEBUG_ERR("%s unknown/unsupported keytype %d\n",
+ __func__, prepparm->lv3.keyblock.keylen);
rc = -EIO;
goto out;
}
@@ -638,8 +642,8 @@ int pkey_clr2protkey(u32 keytype,
fc = CPACF_PCKMO_ENC_AES_256_KEY;
break;
default:
- DEBUG_ERR("pkey_clr2protkey unknown/unsupported keytype %d\n",
- keytype);
+ DEBUG_ERR("%s unknown/unsupported keytype %d\n",
+ __func__, keytype);
return -EINVAL;
}
@@ -699,7 +703,7 @@ static int query_crypto_facility(u16 cardnr, u16 domain,
/* fill request cprb param block with FQ request */
preqparm = (struct fqreqparm *) preqcblk->req_parmb;
memcpy(preqparm->subfunc_code, "FQ", 2);
- strncpy(preqparm->rule_array, keyword, sizeof(preqparm->rule_array));
+ memcpy(preqparm->rule_array, keyword, sizeof(preqparm->rule_array));
preqparm->rule_array_len =
sizeof(preqparm->rule_array_len) + sizeof(preqparm->rule_array);
preqparm->lv1.len = sizeof(preqparm->lv1);
@@ -713,15 +717,16 @@ static int query_crypto_facility(u16 cardnr, u16 domain,
rc = _zcrypt_send_cprb(&xcrb);
if (rc) {
DEBUG_ERR(
- "query_crypto_facility zcrypt_send_cprb (cardnr=%d domain=%d) failed with errno %d\n",
- (int) cardnr, (int) domain, rc);
+ "%s zcrypt_send_cprb (cardnr=%d domain=%d) failed with errno %d\n",
+ __func__, (int) cardnr, (int) domain, rc);
goto out;
}
/* check response returncode and reasoncode */
if (prepcblk->ccp_rtcode != 0) {
DEBUG_ERR(
- "query_crypto_facility unwrap secure key failure, card response %d/%d\n",
+ "%s unwrap secure key failure, card response %d/%d\n",
+ __func__,
(int) prepcblk->ccp_rtcode,
(int) prepcblk->ccp_rscode);
rc = -EIO;
@@ -993,7 +998,7 @@ int pkey_skey2pkey(const struct pkey_seckey *seckey,
}
if (rc)
- DEBUG_DBG("pkey_skey2pkey failed rc=%d\n", rc);
+ DEBUG_DBG("%s failed rc=%d\n", __func__, rc);
return rc;
}
@@ -1030,7 +1035,7 @@ int pkey_verifykey(const struct pkey_seckey *seckey,
if (rc)
goto out;
if (t->mkvp == mkvp[1]) {
- DEBUG_DBG("pkey_verifykey secure key has old mkvp\n");
+ DEBUG_DBG("%s secure key has old mkvp\n", __func__);
if (pattributes)
*pattributes |= PKEY_VERIFY_ATTR_OLD_MKVP;
}
@@ -1041,7 +1046,7 @@ int pkey_verifykey(const struct pkey_seckey *seckey,
*pdomain = domain;
out:
- DEBUG_DBG("pkey_verifykey rc=%d\n", rc);
+ DEBUG_DBG("%s rc=%d\n", __func__, rc);
return rc;
}
EXPORT_SYMBOL(pkey_verifykey);
@@ -1064,7 +1069,7 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
return -EFAULT;
rc = pkey_genseckey(kgs.cardnr, kgs.domain,
kgs.keytype, &kgs.seckey);
- DEBUG_DBG("pkey_ioctl pkey_genseckey()=%d\n", rc);
+ DEBUG_DBG("%s pkey_genseckey()=%d\n", __func__, rc);
if (rc)
break;
if (copy_to_user(ugs, &kgs, sizeof(kgs)))
@@ -1079,7 +1084,7 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
return -EFAULT;
rc = pkey_clr2seckey(kcs.cardnr, kcs.domain, kcs.keytype,
&kcs.clrkey, &kcs.seckey);
- DEBUG_DBG("pkey_ioctl pkey_clr2seckey()=%d\n", rc);
+ DEBUG_DBG("%s pkey_clr2seckey()=%d\n", __func__, rc);
if (rc)
break;
if (copy_to_user(ucs, &kcs, sizeof(kcs)))
@@ -1095,7 +1100,7 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
return -EFAULT;
rc = pkey_sec2protkey(ksp.cardnr, ksp.domain,
&ksp.seckey, &ksp.protkey);
- DEBUG_DBG("pkey_ioctl pkey_sec2protkey()=%d\n", rc);
+ DEBUG_DBG("%s pkey_sec2protkey()=%d\n", __func__, rc);
if (rc)
break;
if (copy_to_user(usp, &ksp, sizeof(ksp)))
@@ -1110,7 +1115,7 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
return -EFAULT;
rc = pkey_clr2protkey(kcp.keytype,
&kcp.clrkey, &kcp.protkey);
- DEBUG_DBG("pkey_ioctl pkey_clr2protkey()=%d\n", rc);
+ DEBUG_DBG("%s pkey_clr2protkey()=%d\n", __func__, rc);
if (rc)
break;
if (copy_to_user(ucp, &kcp, sizeof(kcp)))
@@ -1126,7 +1131,7 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
return -EFAULT;
rc = pkey_findcard(&kfc.seckey,
&kfc.cardnr, &kfc.domain, 1);
- DEBUG_DBG("pkey_ioctl pkey_findcard()=%d\n", rc);
+ DEBUG_DBG("%s pkey_findcard()=%d\n", __func__, rc);
if (rc)
break;
if (copy_to_user(ufc, &kfc, sizeof(kfc)))
@@ -1140,7 +1145,7 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
if (copy_from_user(&ksp, usp, sizeof(ksp)))
return -EFAULT;
rc = pkey_skey2pkey(&ksp.seckey, &ksp.protkey);
- DEBUG_DBG("pkey_ioctl pkey_skey2pkey()=%d\n", rc);
+ DEBUG_DBG("%s pkey_skey2pkey()=%d\n", __func__, rc);
if (rc)
break;
if (copy_to_user(usp, &ksp, sizeof(ksp)))
@@ -1155,7 +1160,7 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
return -EFAULT;
rc = pkey_verifykey(&kvk.seckey, &kvk.cardnr, &kvk.domain,
&kvk.keysize, &kvk.attributes);
- DEBUG_DBG("pkey_ioctl pkey_verifykey()=%d\n", rc);
+ DEBUG_DBG("%s pkey_verifykey()=%d\n", __func__, rc);
if (rc)
break;
if (copy_to_user(uvk, &kvk, sizeof(kvk)))
diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c
index febcdb5135bf..e6854127b434 100644
--- a/drivers/s390/crypto/zcrypt_api.c
+++ b/drivers/s390/crypto/zcrypt_api.c
@@ -50,7 +50,7 @@ EXPORT_TRACEPOINT_SYMBOL(s390_zcrypt_req);
EXPORT_TRACEPOINT_SYMBOL(s390_zcrypt_rep);
static int zcrypt_hwrng_seed = 1;
-module_param_named(hwrng_seed, zcrypt_hwrng_seed, int, S_IRUSR|S_IRGRP);
+module_param_named(hwrng_seed, zcrypt_hwrng_seed, int, 0440);
MODULE_PARM_DESC(hwrng_seed, "Turn on/off hwrng auto seed, default is 1 (on).");
DEFINE_SPINLOCK(zcrypt_list_lock);
@@ -182,7 +182,8 @@ static inline void zcrypt_drop_queue(struct zcrypt_card *zc,
static inline bool zcrypt_card_compare(struct zcrypt_card *zc,
struct zcrypt_card *pref_zc,
- unsigned weight, unsigned pref_weight)
+ unsigned int weight,
+ unsigned int pref_weight)
{
if (!pref_zc)
return false;
@@ -196,7 +197,8 @@ static inline bool zcrypt_card_compare(struct zcrypt_card *zc,
static inline bool zcrypt_queue_compare(struct zcrypt_queue *zq,
struct zcrypt_queue *pref_zq,
- unsigned weight, unsigned pref_weight)
+ unsigned int weight,
+ unsigned int pref_weight)
{
if (!pref_zq)
return false;
@@ -792,6 +794,7 @@ static long zcrypt_unlocked_ioctl(struct file *filp, unsigned int cmd,
case ICARSAMODEXPO: {
struct ica_rsa_modexpo __user *umex = (void __user *) arg;
struct ica_rsa_modexpo mex;
+
if (copy_from_user(&mex, umex, sizeof(mex)))
return -EFAULT;
do {
@@ -811,6 +814,7 @@ static long zcrypt_unlocked_ioctl(struct file *filp, unsigned int cmd,
case ICARSACRT: {
struct ica_rsa_modexpo_crt __user *ucrt = (void __user *) arg;
struct ica_rsa_modexpo_crt crt;
+
if (copy_from_user(&crt, ucrt, sizeof(crt)))
return -EFAULT;
do {
@@ -830,6 +834,7 @@ static long zcrypt_unlocked_ioctl(struct file *filp, unsigned int cmd,
case ZSECSENDCPRB: {
struct ica_xcRB __user *uxcRB = (void __user *) arg;
struct ica_xcRB xcRB;
+
if (copy_from_user(&xcRB, uxcRB, sizeof(xcRB)))
return -EFAULT;
do {
@@ -849,6 +854,7 @@ static long zcrypt_unlocked_ioctl(struct file *filp, unsigned int cmd,
case ZSENDEP11CPRB: {
struct ep11_urb __user *uxcrb = (void __user *)arg;
struct ep11_urb xcrb;
+
if (copy_from_user(&xcrb, uxcrb, sizeof(xcrb)))
return -EFAULT;
do {
@@ -1037,7 +1043,7 @@ static long trans_modexpo_crt32(struct file *filp, unsigned int cmd,
return -EFAULT;
crt64.inputdata = compat_ptr(crt32.inputdata);
crt64.inputdatalength = crt32.inputdatalength;
- crt64.outputdata= compat_ptr(crt32.outputdata);
+ crt64.outputdata = compat_ptr(crt32.outputdata);
crt64.outputdatalength = crt32.outputdatalength;
crt64.bp_key = compat_ptr(crt32.bp_key);
crt64.bq_key = compat_ptr(crt32.bq_key);
@@ -1063,20 +1069,20 @@ struct compat_ica_xcRB {
unsigned int user_defined;
unsigned short request_ID;
unsigned int request_control_blk_length;
- unsigned char padding1[16 - sizeof (compat_uptr_t)];
+ unsigned char padding1[16 - sizeof(compat_uptr_t)];
compat_uptr_t request_control_blk_addr;
unsigned int request_data_length;
- char padding2[16 - sizeof (compat_uptr_t)];
+ char padding2[16 - sizeof(compat_uptr_t)];
compat_uptr_t request_data_address;
unsigned int reply_control_blk_length;
- char padding3[16 - sizeof (compat_uptr_t)];
+ char padding3[16 - sizeof(compat_uptr_t)];
compat_uptr_t reply_control_blk_addr;
unsigned int reply_data_length;
- char padding4[16 - sizeof (compat_uptr_t)];
+ char padding4[16 - sizeof(compat_uptr_t)];
compat_uptr_t reply_data_addr;
unsigned short priority_window;
unsigned int status;
-} __attribute__((packed));
+} __packed;
static long trans_xcRB32(struct file *filp, unsigned int cmd,
unsigned long arg)
@@ -1120,7 +1126,7 @@ static long trans_xcRB32(struct file *filp, unsigned int cmd,
xcRB32.reply_data_length = xcRB64.reply_data_length;
xcRB32.status = xcRB64.status;
if (copy_to_user(uxcRB32, &xcRB32, sizeof(xcRB32)))
- return -EFAULT;
+ return -EFAULT;
return rc;
}
@@ -1182,10 +1188,10 @@ static int zcrypt_rng_data_read(struct hwrng *rng, u32 *data)
rc = zcrypt_rng((char *) zcrypt_rng_buffer);
if (rc < 0)
return -EIO;
- zcrypt_rng_buffer_index = rc / sizeof *data;
+ zcrypt_rng_buffer_index = rc / sizeof(*data);
}
*data = zcrypt_rng_buffer[--zcrypt_rng_buffer_index];
- return sizeof *data;
+ return sizeof(*data);
}
static struct hwrng zcrypt_rng_dev = {
diff --git a/drivers/s390/crypto/zcrypt_api.h b/drivers/s390/crypto/zcrypt_api.h
index f149a8fee60d..a848625c1a5a 100644
--- a/drivers/s390/crypto/zcrypt_api.h
+++ b/drivers/s390/crypto/zcrypt_api.h
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0+
+/* SPDX-License-Identifier: GPL-2.0+ */
/*
* zcrypt 2.1.0
*
diff --git a/drivers/s390/crypto/zcrypt_card.c b/drivers/s390/crypto/zcrypt_card.c
index 233e1e695208..40cd4c1c2de8 100644
--- a/drivers/s390/crypto/zcrypt_card.c
+++ b/drivers/s390/crypto/zcrypt_card.c
@@ -38,28 +38,28 @@
* Device attributes common for all crypto card devices.
*/
-static ssize_t zcrypt_card_type_show(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t type_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct zcrypt_card *zc = to_ap_card(dev)->private;
return snprintf(buf, PAGE_SIZE, "%s\n", zc->type_string);
}
-static DEVICE_ATTR(type, 0444, zcrypt_card_type_show, NULL);
+static DEVICE_ATTR_RO(type);
-static ssize_t zcrypt_card_online_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
+static ssize_t online_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
{
struct zcrypt_card *zc = to_ap_card(dev)->private;
return snprintf(buf, PAGE_SIZE, "%d\n", zc->online);
}
-static ssize_t zcrypt_card_online_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
+static ssize_t online_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
{
struct zcrypt_card *zc = to_ap_card(dev)->private;
struct zcrypt_queue *zq;
@@ -80,12 +80,23 @@ static ssize_t zcrypt_card_online_store(struct device *dev,
return count;
}
-static DEVICE_ATTR(online, 0644, zcrypt_card_online_show,
- zcrypt_card_online_store);
+static DEVICE_ATTR_RW(online);
+
+static ssize_t load_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct zcrypt_card *zc = to_ap_card(dev)->private;
+
+ return snprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&zc->load));
+}
+
+static DEVICE_ATTR_RO(load);
static struct attribute *zcrypt_card_attrs[] = {
&dev_attr_type.attr,
&dev_attr_online.attr,
+ &dev_attr_load.attr,
NULL,
};
diff --git a/drivers/s390/crypto/zcrypt_cca_key.h b/drivers/s390/crypto/zcrypt_cca_key.h
index 011d61d8a4ae..e5b5c02c9d67 100644
--- a/drivers/s390/crypto/zcrypt_cca_key.h
+++ b/drivers/s390/crypto/zcrypt_cca_key.h
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0+
+/* SPDX-License-Identifier: GPL-2.0+ */
/*
* zcrypt 2.1.0
*
@@ -31,7 +31,7 @@ struct cca_token_hdr {
unsigned char version;
unsigned short token_length;
unsigned char reserved[4];
-} __attribute__((packed));
+} __packed;
#define CCA_TKN_HDR_ID_EXT 0x1E
@@ -51,7 +51,7 @@ struct cca_public_sec {
unsigned short exponent_len;
unsigned short modulus_bit_len;
unsigned short modulus_byte_len; /* In a private key, this is 0 */
-} __attribute__((packed));
+} __packed;
/**
* mapping for the cca private CRT key 'token'
@@ -85,7 +85,7 @@ struct cca_pvt_ext_CRT_sec {
unsigned short pad_len;
unsigned char reserved4[52];
unsigned char confounder[8];
-} __attribute__((packed));
+} __packed;
#define CCA_PVT_EXT_CRT_SEC_ID_PVT 0x08
#define CCA_PVT_EXT_CRT_SEC_FMT_CL 0x40
@@ -99,7 +99,7 @@ struct cca_pvt_ext_CRT_sec {
* @mex: pointer to user input data
* @p: pointer to memory area for the key
*
- * Returns the size of the key area or -EFAULT
+ * Returns the size of the key area or negative errno value.
*/
static inline int zcrypt_type6_mex_key_en(struct ica_rsa_modexpo *mex, void *p)
{
@@ -114,10 +114,19 @@ static inline int zcrypt_type6_mex_key_en(struct ica_rsa_modexpo *mex, void *p)
struct cca_token_hdr pubHdr;
struct cca_public_sec pubSec;
char exponent[0];
- } __attribute__((packed)) *key = p;
+ } __packed *key = p;
unsigned char *temp;
int i;
+ /*
+ * The inputdatalength was a selection criteria in the dispatching
+ * function zcrypt_rsa_modexpo(). However, do a plausibility check
+ * here to make sure the following copy_from_user() can't be utilized
+ * to compromise the system.
+ */
+ if (WARN_ON_ONCE(mex->inputdatalength > 512))
+ return -EINVAL;
+
memset(key, 0, sizeof(*key));
key->pubHdr = static_pub_hdr;
@@ -174,10 +183,19 @@ static inline int zcrypt_type6_crt_key(struct ica_rsa_modexpo_crt *crt, void *p)
struct cca_token_hdr token;
struct cca_pvt_ext_CRT_sec pvt;
char key_parts[0];
- } __attribute__((packed)) *key = p;
+ } __packed *key = p;
struct cca_public_sec *pub;
int short_len, long_len, pad_len, key_len, size;
+ /*
+ * The inputdatalength was a selection criteria in the dispatching
+ * function zcrypt_rsa_crt(). However, do a plausibility check
+ * here to make sure the following copy_from_user() can't be utilized
+ * to compromise the system.
+ */
+ if (WARN_ON_ONCE(crt->inputdatalength > 512))
+ return -EINVAL;
+
memset(key, 0, sizeof(*key));
short_len = (crt->inputdatalength + 1) / 2;
diff --git a/drivers/s390/crypto/zcrypt_cex2a.c b/drivers/s390/crypto/zcrypt_cex2a.c
index e701194d3611..f4ae5fa30ec9 100644
--- a/drivers/s390/crypto/zcrypt_cex2a.c
+++ b/drivers/s390/crypto/zcrypt_cex2a.c
@@ -145,6 +145,7 @@ static struct ap_driver zcrypt_cex2a_card_driver = {
.probe = zcrypt_cex2a_card_probe,
.remove = zcrypt_cex2a_card_remove,
.ids = zcrypt_cex2a_card_ids,
+ .flags = AP_DRIVER_FLAG_DEFAULT,
};
/**
@@ -208,6 +209,7 @@ static struct ap_driver zcrypt_cex2a_queue_driver = {
.suspend = ap_queue_suspend,
.resume = ap_queue_resume,
.ids = zcrypt_cex2a_queue_ids,
+ .flags = AP_DRIVER_FLAG_DEFAULT,
};
int __init zcrypt_cex2a_init(void)
diff --git a/drivers/s390/crypto/zcrypt_cex2a.h b/drivers/s390/crypto/zcrypt_cex2a.h
index c3c116777c93..66d58bc87c66 100644
--- a/drivers/s390/crypto/zcrypt_cex2a.h
+++ b/drivers/s390/crypto/zcrypt_cex2a.h
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0+
+/* SPDX-License-Identifier: GPL-2.0+ */
/*
* zcrypt 2.1.0
*
@@ -30,7 +30,7 @@ struct type50_hdr {
unsigned char reserved2;
unsigned char ignored;
unsigned short reserved3;
-} __attribute__((packed));
+} __packed;
#define TYPE50_TYPE_CODE 0x50
@@ -49,7 +49,7 @@ struct type50_meb1_msg {
unsigned char exponent[128];
unsigned char modulus[128];
unsigned char message[128];
-} __attribute__((packed));
+} __packed;
/* Mod-Exp, with a large modulus */
struct type50_meb2_msg {
@@ -59,7 +59,7 @@ struct type50_meb2_msg {
unsigned char exponent[256];
unsigned char modulus[256];
unsigned char message[256];
-} __attribute__((packed));
+} __packed;
/* Mod-Exp, with a larger modulus */
struct type50_meb3_msg {
@@ -69,7 +69,7 @@ struct type50_meb3_msg {
unsigned char exponent[512];
unsigned char modulus[512];
unsigned char message[512];
-} __attribute__((packed));
+} __packed;
/* CRT, with a small modulus */
struct type50_crb1_msg {
@@ -82,7 +82,7 @@ struct type50_crb1_msg {
unsigned char dq[64];
unsigned char u[64];
unsigned char message[128];
-} __attribute__((packed));
+} __packed;
/* CRT, with a large modulus */
struct type50_crb2_msg {
@@ -95,7 +95,7 @@ struct type50_crb2_msg {
unsigned char dq[128];
unsigned char u[128];
unsigned char message[256];
-} __attribute__((packed));
+} __packed;
/* CRT, with a larger modulus */
struct type50_crb3_msg {
@@ -108,7 +108,7 @@ struct type50_crb3_msg {
unsigned char dq[256];
unsigned char u[256];
unsigned char message[512];
-} __attribute__((packed));
+} __packed;
/**
* The type 80 response family is associated with a CEX2A card.
@@ -128,7 +128,7 @@ struct type80_hdr {
unsigned char code; /* 0x00 */
unsigned char reserved2[3];
unsigned char reserved3[8];
-} __attribute__((packed));
+} __packed;
int zcrypt_cex2a_init(void);
void zcrypt_cex2a_exit(void);
diff --git a/drivers/s390/crypto/zcrypt_cex4.c b/drivers/s390/crypto/zcrypt_cex4.c
index f305538334ad..35d58dbbc4da 100644
--- a/drivers/s390/crypto/zcrypt_cex4.c
+++ b/drivers/s390/crypto/zcrypt_cex4.c
@@ -214,6 +214,7 @@ static struct ap_driver zcrypt_cex4_card_driver = {
.probe = zcrypt_cex4_card_probe,
.remove = zcrypt_cex4_card_remove,
.ids = zcrypt_cex4_card_ids,
+ .flags = AP_DRIVER_FLAG_DEFAULT,
};
/**
@@ -283,6 +284,7 @@ static struct ap_driver zcrypt_cex4_queue_driver = {
.suspend = ap_queue_suspend,
.resume = ap_queue_resume,
.ids = zcrypt_cex4_queue_ids,
+ .flags = AP_DRIVER_FLAG_DEFAULT,
};
int __init zcrypt_cex4_init(void)
diff --git a/drivers/s390/crypto/zcrypt_error.h b/drivers/s390/crypto/zcrypt_error.h
index 01598d83c60a..6f7ebc1dbe10 100644
--- a/drivers/s390/crypto/zcrypt_error.h
+++ b/drivers/s390/crypto/zcrypt_error.h
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0+
+/* SPDX-License-Identifier: GPL-2.0+ */
/*
* zcrypt 2.1.0
*
diff --git a/drivers/s390/crypto/zcrypt_msgtype50.c b/drivers/s390/crypto/zcrypt_msgtype50.c
index afe1b2bcd7ec..f159662c907b 100644
--- a/drivers/s390/crypto/zcrypt_msgtype50.c
+++ b/drivers/s390/crypto/zcrypt_msgtype50.c
@@ -27,13 +27,14 @@
#include "zcrypt_error.h"
#include "zcrypt_msgtype50.h"
-#define CEX3A_MAX_MOD_SIZE 512 /* 4096 bits */
+/* 4096 bits */
+#define CEX3A_MAX_MOD_SIZE 512
-#define CEX2A_MAX_RESPONSE_SIZE 0x110 /* max outputdatalength + type80_hdr */
+/* max outputdatalength + type80_hdr */
+#define CEX2A_MAX_RESPONSE_SIZE 0x110
-#define CEX3A_MAX_RESPONSE_SIZE 0x210 /* 512 bit modulus
- * (max outputdatalength) +
- * type80_hdr*/
+/* 512 bit modulus, (max outputdatalength) + type80_hdr */
+#define CEX3A_MAX_RESPONSE_SIZE 0x210
MODULE_AUTHOR("IBM Corporation");
MODULE_DESCRIPTION("Cryptographic Accelerator (message type 50), " \
@@ -209,6 +210,7 @@ static int ICAMEX_msg_to_type50MEX_msg(struct zcrypt_queue *zq,
if (mod_len <= 128) {
struct type50_meb1_msg *meb1 = ap_msg->message;
+
memset(meb1, 0, sizeof(*meb1));
ap_msg->length = sizeof(*meb1);
meb1->header.msg_type_code = TYPE50_TYPE_CODE;
@@ -219,6 +221,7 @@ static int ICAMEX_msg_to_type50MEX_msg(struct zcrypt_queue *zq,
inp = meb1->message + sizeof(meb1->message) - mod_len;
} else if (mod_len <= 256) {
struct type50_meb2_msg *meb2 = ap_msg->message;
+
memset(meb2, 0, sizeof(*meb2));
ap_msg->length = sizeof(*meb2);
meb2->header.msg_type_code = TYPE50_TYPE_CODE;
@@ -229,6 +232,7 @@ static int ICAMEX_msg_to_type50MEX_msg(struct zcrypt_queue *zq,
inp = meb2->message + sizeof(meb2->message) - mod_len;
} else if (mod_len <= 512) {
struct type50_meb3_msg *meb3 = ap_msg->message;
+
memset(meb3, 0, sizeof(*meb3));
ap_msg->length = sizeof(*meb3);
meb3->header.msg_type_code = TYPE50_TYPE_CODE;
@@ -274,6 +278,7 @@ static int ICACRT_msg_to_type50CRT_msg(struct zcrypt_queue *zq,
*/
if (mod_len <= 128) { /* up to 1024 bit key size */
struct type50_crb1_msg *crb1 = ap_msg->message;
+
memset(crb1, 0, sizeof(*crb1));
ap_msg->length = sizeof(*crb1);
crb1->header.msg_type_code = TYPE50_TYPE_CODE;
@@ -287,6 +292,7 @@ static int ICACRT_msg_to_type50CRT_msg(struct zcrypt_queue *zq,
inp = crb1->message + sizeof(crb1->message) - mod_len;
} else if (mod_len <= 256) { /* up to 2048 bit key size */
struct type50_crb2_msg *crb2 = ap_msg->message;
+
memset(crb2, 0, sizeof(*crb2));
ap_msg->length = sizeof(*crb2);
crb2->header.msg_type_code = TYPE50_TYPE_CODE;
@@ -301,6 +307,7 @@ static int ICACRT_msg_to_type50CRT_msg(struct zcrypt_queue *zq,
} else if ((mod_len <= 512) && /* up to 4096 bit key size */
(zq->zcard->max_mod_size == CEX3A_MAX_MOD_SIZE)) {
struct type50_crb3_msg *crb3 = ap_msg->message;
+
memset(crb3, 0, sizeof(*crb3));
ap_msg->length = sizeof(*crb3);
crb3->header.msg_type_code = TYPE50_TYPE_CODE;
diff --git a/drivers/s390/crypto/zcrypt_msgtype50.h b/drivers/s390/crypto/zcrypt_msgtype50.h
index 0a36545cfb8e..8530f652ea4f 100644
--- a/drivers/s390/crypto/zcrypt_msgtype50.h
+++ b/drivers/s390/crypto/zcrypt_msgtype50.h
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0+
+/* SPDX-License-Identifier: GPL-2.0+ */
/*
* zcrypt 2.1.0
*
@@ -17,10 +17,10 @@
#define MSGTYPE50_NAME "zcrypt_msgtype50"
#define MSGTYPE50_VARIANT_DEFAULT 0
-#define MSGTYPE50_CRB2_MAX_MSG_SIZE 0x390 /*sizeof(struct type50_crb2_msg)*/
-#define MSGTYPE50_CRB3_MAX_MSG_SIZE 0x710 /*sizeof(struct type50_crb3_msg)*/
+#define MSGTYPE50_CRB2_MAX_MSG_SIZE 0x390 /* sizeof(struct type50_crb2_msg) */
+#define MSGTYPE50_CRB3_MAX_MSG_SIZE 0x710 /* sizeof(struct type50_crb3_msg) */
-#define MSGTYPE_ADJUSTMENT 0x08 /*type04 extension (not needed in type50)*/
+#define MSGTYPE_ADJUSTMENT 0x08 /* type04 extension (not needed in type50) */
unsigned int get_rsa_modex_fc(struct ica_rsa_modexpo *, int *);
unsigned int get_rsa_crt_fc(struct ica_rsa_modexpo_crt *, int *);
diff --git a/drivers/s390/crypto/zcrypt_msgtype6.c b/drivers/s390/crypto/zcrypt_msgtype6.c
index 97d4bacbc442..2101776a8148 100644
--- a/drivers/s390/crypto/zcrypt_msgtype6.c
+++ b/drivers/s390/crypto/zcrypt_msgtype6.c
@@ -246,7 +246,7 @@ int speed_idx_ep11(int req_type)
* @ap_msg: pointer to AP message
* @mex: pointer to user input data
*
- * Returns 0 on success or -EFAULT.
+ * Returns 0 on success or negative errno value.
*/
static int ICAMEX_msg_to_type6MEX_msgX(struct zcrypt_queue *zq,
struct ap_message *ap_msg,
@@ -272,6 +272,14 @@ static int ICAMEX_msg_to_type6MEX_msgX(struct zcrypt_queue *zq,
} __packed * msg = ap_msg->message;
int size;
+ /*
+ * The inputdatalength was a selection criteria in the dispatching
+ * function zcrypt_rsa_modexpo(). However, make sure the following
+ * copy_from_user() never exceeds the allocated buffer space.
+ */
+ if (WARN_ON_ONCE(mex->inputdatalength > PAGE_SIZE))
+ return -EINVAL;
+
/* VUD.ciphertext */
msg->length = mex->inputdatalength + 2;
if (copy_from_user(msg->text, mex->inputdata, mex->inputdatalength))
@@ -307,7 +315,7 @@ static int ICAMEX_msg_to_type6MEX_msgX(struct zcrypt_queue *zq,
* @ap_msg: pointer to AP message
* @crt: pointer to user input data
*
- * Returns 0 on success or -EFAULT.
+ * Returns 0 on success or negative errno value.
*/
static int ICACRT_msg_to_type6CRT_msgX(struct zcrypt_queue *zq,
struct ap_message *ap_msg,
@@ -334,6 +342,14 @@ static int ICACRT_msg_to_type6CRT_msgX(struct zcrypt_queue *zq,
} __packed * msg = ap_msg->message;
int size;
+ /*
+ * The inputdatalength was a selection criteria in the dispatching
+ * function zcrypt_rsa_crt(). However, make sure the following
+ * copy_from_user() never exceeds the allocated buffer space.
+ */
+ if (WARN_ON_ONCE(crt->inputdatalength > PAGE_SIZE))
+ return -EINVAL;
+
/* VUD.ciphertext */
msg->length = crt->inputdatalength + 2;
if (copy_from_user(msg->text, crt->inputdata, crt->inputdatalength))
@@ -405,8 +421,10 @@ static int XCRB_msg_to_type6CPRB_msgX(struct ap_message *ap_msg,
if (ap_msg->length > MSGTYPE06_MAX_MSG_SIZE)
return -EINVAL;
- /* Overflow check
- sum must be greater (or equal) than the largest operand */
+ /*
+ * Overflow check
+ * sum must be greater (or equal) than the largest operand
+ */
req_sumlen = CEIL4(xcRB->request_control_blk_length) +
xcRB->request_data_length;
if ((CEIL4(xcRB->request_control_blk_length) <=
@@ -426,8 +444,10 @@ static int XCRB_msg_to_type6CPRB_msgX(struct ap_message *ap_msg,
if (replylen > MSGTYPE06_MAX_MSG_SIZE)
return -EINVAL;
- /* Overflow check
- sum must be greater (or equal) than the largest operand */
+ /*
+ * Overflow check
+ * sum must be greater (or equal) than the largest operand
+ */
resp_sumlen = CEIL4(xcRB->reply_control_blk_length) +
xcRB->reply_data_length;
if ((CEIL4(xcRB->reply_control_blk_length) <= xcRB->reply_data_length) ?
@@ -438,7 +458,7 @@ static int XCRB_msg_to_type6CPRB_msgX(struct ap_message *ap_msg,
/* prepare type6 header */
msg->hdr = static_type6_hdrX;
- memcpy(msg->hdr.agent_id , &(xcRB->agent_ID), sizeof(xcRB->agent_ID));
+ memcpy(msg->hdr.agent_id, &(xcRB->agent_ID), sizeof(xcRB->agent_ID));
msg->hdr.ToCardLen1 = xcRB->request_control_blk_length;
if (xcRB->request_data_length) {
msg->hdr.offset2 = msg->hdr.offset1 + rcblen;
@@ -790,8 +810,10 @@ static int convert_response_ica(struct zcrypt_queue *zq,
if (msg->cprbx.cprb_ver_id == 0x02)
return convert_type86_ica(zq, reply,
outputdata, outputdatalength);
- /* Fall through, no break, incorrect cprb version is an unknown
- * response */
+ /*
+ * Fall through, no break, incorrect cprb version is an unknown
+ * response
+ */
default: /* Unknown response type, this should NEVER EVER happen */
zq->online = 0;
pr_err("Cryptographic device %02x.%04x failed and was set offline\n",
@@ -824,8 +846,10 @@ static int convert_response_xcrb(struct zcrypt_queue *zq,
}
if (msg->cprbx.cprb_ver_id == 0x02)
return convert_type86_xcrb(zq, reply, xcRB);
- /* Fall through, no break, incorrect cprb version is an unknown
- * response */
+ /*
+ * Fall through, no break, incorrect cprb version is an unknown
+ * response
+ */
default: /* Unknown response type, this should NEVER EVER happen */
xcRB->status = 0x0008044DL; /* HDD_InvalidParm */
zq->online = 0;
@@ -885,8 +909,10 @@ static int convert_response_rng(struct zcrypt_queue *zq,
return -EINVAL;
if (msg->cprbx.cprb_ver_id == 0x02)
return convert_type86_rng(zq, reply, data);
- /* Fall through, no break, incorrect cprb version is an unknown
- * response */
+ /*
+ * Fall through, no break, incorrect cprb version is an unknown
+ * response
+ */
default: /* Unknown response type, this should NEVER EVER happen */
zq->online = 0;
pr_err("Cryptographic device %02x.%04x failed and was set offline\n",
@@ -988,7 +1014,7 @@ static void zcrypt_msgtype6_receive_ep11(struct ap_queue *aq,
}
} else {
memcpy(msg->message, reply->message, sizeof(error_reply));
- }
+ }
out:
complete(&(resp_type->work));
}
diff --git a/drivers/s390/crypto/zcrypt_msgtype6.h b/drivers/s390/crypto/zcrypt_msgtype6.h
index d314f4525518..e4c2f37d7ad9 100644
--- a/drivers/s390/crypto/zcrypt_msgtype6.h
+++ b/drivers/s390/crypto/zcrypt_msgtype6.h
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0+
+/* SPDX-License-Identifier: GPL-2.0+ */
/*
* zcrypt 2.1.0
*
diff --git a/drivers/s390/crypto/zcrypt_pcixcc.c b/drivers/s390/crypto/zcrypt_pcixcc.c
index 159b0a0dd211..94d9f7224aea 100644
--- a/drivers/s390/crypto/zcrypt_pcixcc.c
+++ b/drivers/s390/crypto/zcrypt_pcixcc.c
@@ -95,7 +95,7 @@ static int zcrypt_pcixcc_rng_supported(struct ap_queue *aq)
struct type86_hdr hdr;
struct type86_fmt2_ext fmt2;
struct CPRBX cprbx;
- } __attribute__((packed)) *reply;
+ } __packed *reply;
struct {
struct type6_hdr hdr;
struct CPRBX cprbx;
@@ -104,7 +104,7 @@ static int zcrypt_pcixcc_rng_supported(struct ap_queue *aq)
char rule[8];
short int verb_length;
short int key_length;
- } __packed * msg;
+ } __packed *msg;
int rc, i;
ap_init_message(&ap_msg);
@@ -223,6 +223,7 @@ static struct ap_driver zcrypt_pcixcc_card_driver = {
.probe = zcrypt_pcixcc_card_probe,
.remove = zcrypt_pcixcc_card_remove,
.ids = zcrypt_pcixcc_card_ids,
+ .flags = AP_DRIVER_FLAG_DEFAULT,
};
/**
@@ -286,6 +287,7 @@ static struct ap_driver zcrypt_pcixcc_queue_driver = {
.suspend = ap_queue_suspend,
.resume = ap_queue_resume,
.ids = zcrypt_pcixcc_queue_ids,
+ .flags = AP_DRIVER_FLAG_DEFAULT,
};
int __init zcrypt_pcixcc_init(void)
diff --git a/drivers/s390/crypto/zcrypt_pcixcc.h b/drivers/s390/crypto/zcrypt_pcixcc.h
index d678a3af83a7..cf73a0f91e9c 100644
--- a/drivers/s390/crypto/zcrypt_pcixcc.h
+++ b/drivers/s390/crypto/zcrypt_pcixcc.h
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0+
+/* SPDX-License-Identifier: GPL-2.0+ */
/*
* zcrypt 2.1.0
*
diff --git a/drivers/s390/crypto/zcrypt_queue.c b/drivers/s390/crypto/zcrypt_queue.c
index 720434e18007..8df82c6ef66e 100644
--- a/drivers/s390/crypto/zcrypt_queue.c
+++ b/drivers/s390/crypto/zcrypt_queue.c
@@ -38,18 +38,18 @@
* Device attributes common for all crypto queue devices.
*/
-static ssize_t zcrypt_queue_online_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
+static ssize_t online_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
{
struct zcrypt_queue *zq = to_ap_queue(dev)->private;
return snprintf(buf, PAGE_SIZE, "%d\n", zq->online);
}
-static ssize_t zcrypt_queue_online_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
+static ssize_t online_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
{
struct zcrypt_queue *zq = to_ap_queue(dev)->private;
struct zcrypt_card *zc = zq->zcard;
@@ -72,11 +72,22 @@ static ssize_t zcrypt_queue_online_store(struct device *dev,
return count;
}
-static DEVICE_ATTR(online, 0644, zcrypt_queue_online_show,
- zcrypt_queue_online_store);
+static DEVICE_ATTR_RW(online);
+
+static ssize_t load_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct zcrypt_queue *zq = to_ap_queue(dev)->private;
+
+ return snprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&zq->load));
+}
+
+static DEVICE_ATTR_RO(load);
static struct attribute *zcrypt_queue_attrs[] = {
&dev_attr_online.attr,
+ &dev_attr_load.attr,
NULL,
};
OpenPOWER on IntegriCloud