summaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-10-23 11:14:47 +0100
committerLinus Torvalds <torvalds@linux-foundation.org>2018-10-23 11:14:47 +0100
commite2b623fbe6a34bce1332584212ae101ebc2508f5 (patch)
treeeb07421d683c90cbed7326cdcc778cea9a08d48d /drivers/s390
parent70408a9987d1ffac006e21b965f0c30dd22b0af2 (diff)
parentf822ad2c2c03af85a531c5174136b6d5b1abc566 (diff)
Merge tag 's390-4.20-1' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 updates from Martin Schwidefsky: - Improved access control for the zcrypt driver, multiple device nodes can now be created with different access control lists - Extend the pkey API to provide random protected keys, this is useful for encrypted swap device with ephemeral protected keys - Add support for virtually mapped kernel stacks - Rework the early boot code, this moves the memory detection into the boot code that runs prior to decompression. - Add KASAN support - Bug fixes and cleanups * tag 's390-4.20-1' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: (83 commits) s390/pkey: move pckmo subfunction available checks away from module init s390/kasan: support preemptible kernel build s390/pkey: Load pkey kernel module automatically s390/perf: Return error when debug_register fails s390/sthyi: Fix machine name validity indication s390/zcrypt: fix broken zcrypt_send_cprb in-kernel api function s390/vmalloc: fix VMALLOC_START calculation s390/mem_detect: add missing include s390/dumpstack: print psw mask and address again s390/crypto: Enhance paes cipher to accept variable length key material s390/pkey: Introduce new API for transforming key blobs s390/pkey: Introduce new API for random protected key verification s390/pkey: Add sysfs attributes to emit secure key blobs s390/pkey: Add sysfs attributes to emit protected key blobs s390/pkey: Define protected key blob format s390/pkey: Introduce new API for random protected key generation s390/zcrypt: add ap_adapter_mask sysfs attribute s390/zcrypt: provide apfs failure code on type 86 error reply s390/zcrypt: zcrypt device driver cleanup s390/kasan: add support for mem= kernel parameter ...
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/block/dasd.c6
-rw-r--r--drivers/s390/char/Makefile1
-rw-r--r--drivers/s390/char/monwriter.c33
-rw-r--r--drivers/s390/char/sclp.h52
-rw-r--r--drivers/s390/char/sclp_cmd.c11
-rw-r--r--drivers/s390/char/sclp_early.c123
-rw-r--r--drivers/s390/char/sclp_early_core.c116
-rw-r--r--drivers/s390/char/sclp_pci.c10
-rw-r--r--drivers/s390/char/tape_3590.c2
-rw-r--r--drivers/s390/char/vmlogrdr.c2
-rw-r--r--drivers/s390/cio/ccwgroup.c30
-rw-r--r--drivers/s390/cio/qdio_main.c15
-rw-r--r--drivers/s390/cio/qdio_setup.c1
-rw-r--r--drivers/s390/crypto/Makefile2
-rw-r--r--drivers/s390/crypto/ap_bus.c79
-rw-r--r--drivers/s390/crypto/ap_bus.h25
-rw-r--r--drivers/s390/crypto/pkey_api.c521
-rw-r--r--drivers/s390/crypto/zcrypt_api.c627
-rw-r--r--drivers/s390/crypto/zcrypt_api.h15
-rw-r--r--drivers/s390/crypto/zcrypt_card.c2
-rw-r--r--drivers/s390/crypto/zcrypt_cca_key.h2
-rw-r--r--drivers/s390/crypto/zcrypt_cex2a.c6
-rw-r--r--drivers/s390/crypto/zcrypt_cex2a.h6
-rw-r--r--drivers/s390/crypto/zcrypt_cex2c.c (renamed from drivers/s390/crypto/zcrypt_pcixcc.c)125
-rw-r--r--drivers/s390/crypto/zcrypt_cex2c.h (renamed from drivers/s390/crypto/zcrypt_pcixcc.h)14
-rw-r--r--drivers/s390/crypto/zcrypt_cex4.c20
-rw-r--r--drivers/s390/crypto/zcrypt_error.h24
-rw-r--r--drivers/s390/crypto/zcrypt_msgtype50.c24
-rw-r--r--drivers/s390/crypto/zcrypt_msgtype50.h2
-rw-r--r--drivers/s390/crypto/zcrypt_msgtype6.c74
-rw-r--r--drivers/s390/crypto/zcrypt_msgtype6.h15
-rw-r--r--drivers/s390/crypto/zcrypt_queue.c2
32 files changed, 1545 insertions, 442 deletions
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index a23e7d394a0a..5e9ebdb0594c 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -3309,10 +3309,8 @@ dasd_exit(void)
dasd_proc_exit();
#endif
dasd_eer_exit();
- if (dasd_page_cache != NULL) {
- kmem_cache_destroy(dasd_page_cache);
- dasd_page_cache = NULL;
- }
+ kmem_cache_destroy(dasd_page_cache);
+ dasd_page_cache = NULL;
dasd_gendisk_exit();
dasd_devmap_exit();
if (dasd_debug_area != NULL) {
diff --git a/drivers/s390/char/Makefile b/drivers/s390/char/Makefile
index c6ab34f94b1b..3072b89785dd 100644
--- a/drivers/s390/char/Makefile
+++ b/drivers/s390/char/Makefile
@@ -11,6 +11,7 @@ endif
GCOV_PROFILE_sclp_early_core.o := n
KCOV_INSTRUMENT_sclp_early_core.o := n
UBSAN_SANITIZE_sclp_early_core.o := n
+KASAN_SANITIZE_sclp_early_core.o := n
CFLAGS_sclp_early_core.o += -D__NO_FORTIFY
diff --git a/drivers/s390/char/monwriter.c b/drivers/s390/char/monwriter.c
index 4f1a69c9d81d..fdc0c0b7a6f5 100644
--- a/drivers/s390/char/monwriter.c
+++ b/drivers/s390/char/monwriter.c
@@ -58,22 +58,31 @@ struct mon_private {
static int monwrite_diag(struct monwrite_hdr *myhdr, char *buffer, int fcn)
{
- struct appldata_product_id id;
+ struct appldata_parameter_list *parm_list;
+ struct appldata_product_id *id;
int rc;
- memcpy(id.prod_nr, "LNXAPPL", 7);
- id.prod_fn = myhdr->applid;
- id.record_nr = myhdr->record_num;
- id.version_nr = myhdr->version;
- id.release_nr = myhdr->release;
- id.mod_lvl = myhdr->mod_level;
- rc = appldata_asm(&id, fcn, (void *) buffer, myhdr->datalen);
+ id = kmalloc(sizeof(*id), GFP_KERNEL);
+ parm_list = kmalloc(sizeof(*parm_list), GFP_KERNEL);
+ rc = -ENOMEM;
+ if (!id || !parm_list)
+ goto out;
+ memcpy(id->prod_nr, "LNXAPPL", 7);
+ id->prod_fn = myhdr->applid;
+ id->record_nr = myhdr->record_num;
+ id->version_nr = myhdr->version;
+ id->release_nr = myhdr->release;
+ id->mod_lvl = myhdr->mod_level;
+ rc = appldata_asm(parm_list, id, fcn,
+ (void *) buffer, myhdr->datalen);
if (rc <= 0)
- return rc;
+ goto out;
pr_err("Writing monitor data failed with rc=%i\n", rc);
- if (rc == 5)
- return -EPERM;
- return -EINVAL;
+ rc = (rc == 5) ? -EPERM : -EINVAL;
+out:
+ kfree(id);
+ kfree(parm_list);
+ return rc;
}
static struct mon_buf *monwrite_find_hdr(struct mon_private *monpriv,
diff --git a/drivers/s390/char/sclp.h b/drivers/s390/char/sclp.h
index 1fe4918088e7..b3fcc24b1182 100644
--- a/drivers/s390/char/sclp.h
+++ b/drivers/s390/char/sclp.h
@@ -63,6 +63,9 @@
typedef unsigned int sclp_cmdw_t;
#define SCLP_CMDW_READ_CPU_INFO 0x00010001
+#define SCLP_CMDW_READ_SCP_INFO 0x00020001
+#define SCLP_CMDW_READ_STORAGE_INFO 0x00040001
+#define SCLP_CMDW_READ_SCP_INFO_FORCED 0x00120001
#define SCLP_CMDW_READ_EVENT_DATA 0x00770005
#define SCLP_CMDW_WRITE_EVENT_DATA 0x00760005
#define SCLP_CMDW_WRITE_EVENT_MASK 0x00780005
@@ -156,6 +159,54 @@ struct read_cpu_info_sccb {
u8 reserved[4096 - 16];
} __attribute__((packed, aligned(PAGE_SIZE)));
+struct read_info_sccb {
+ struct sccb_header header; /* 0-7 */
+ u16 rnmax; /* 8-9 */
+ u8 rnsize; /* 10 */
+ u8 _pad_11[16 - 11]; /* 11-15 */
+ u16 ncpurl; /* 16-17 */
+ u16 cpuoff; /* 18-19 */
+ u8 _pad_20[24 - 20]; /* 20-23 */
+ u8 loadparm[8]; /* 24-31 */
+ u8 _pad_32[42 - 32]; /* 32-41 */
+ u8 fac42; /* 42 */
+ u8 fac43; /* 43 */
+ u8 _pad_44[48 - 44]; /* 44-47 */
+ u64 facilities; /* 48-55 */
+ u8 _pad_56[66 - 56]; /* 56-65 */
+ u8 fac66; /* 66 */
+ u8 _pad_67[76 - 67]; /* 67-83 */
+ u32 ibc; /* 76-79 */
+ u8 _pad80[84 - 80]; /* 80-83 */
+ u8 fac84; /* 84 */
+ u8 fac85; /* 85 */
+ u8 _pad_86[91 - 86]; /* 86-90 */
+ u8 fac91; /* 91 */
+ u8 _pad_92[98 - 92]; /* 92-97 */
+ u8 fac98; /* 98 */
+ u8 hamaxpow; /* 99 */
+ u32 rnsize2; /* 100-103 */
+ u64 rnmax2; /* 104-111 */
+ u32 hsa_size; /* 112-115 */
+ u8 fac116; /* 116 */
+ u8 fac117; /* 117 */
+ u8 fac118; /* 118 */
+ u8 fac119; /* 119 */
+ u16 hcpua; /* 120-121 */
+ u8 _pad_122[124 - 122]; /* 122-123 */
+ u32 hmfai; /* 124-127 */
+ u8 _pad_128[4096 - 128]; /* 128-4095 */
+} __packed __aligned(PAGE_SIZE);
+
+struct read_storage_sccb {
+ struct sccb_header header;
+ u16 max_id;
+ u16 assigned;
+ u16 standby;
+ u16 :16;
+ u32 entries[0];
+} __packed;
+
static inline void sclp_fill_core_info(struct sclp_core_info *info,
struct read_cpu_info_sccb *sccb)
{
@@ -275,6 +326,7 @@ unsigned int sclp_early_con_check_vt220(struct init_sccb *sccb);
int sclp_early_set_event_mask(struct init_sccb *sccb,
sccb_mask_t receive_mask,
sccb_mask_t send_mask);
+int sclp_early_get_info(struct read_info_sccb *info);
/* useful inlines */
diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c
index d7686a68c093..37d42de06079 100644
--- a/drivers/s390/char/sclp_cmd.c
+++ b/drivers/s390/char/sclp_cmd.c
@@ -460,15 +460,6 @@ static int sclp_mem_freeze(struct device *dev)
return -EPERM;
}
-struct read_storage_sccb {
- struct sccb_header header;
- u16 max_id;
- u16 assigned;
- u16 standby;
- u16 :16;
- u32 entries[0];
-} __packed;
-
static const struct dev_pm_ops sclp_mem_pm_ops = {
.freeze = sclp_mem_freeze,
};
@@ -498,7 +489,7 @@ static int __init sclp_detect_standby_memory(void)
for (id = 0; id <= sclp_max_storage_id; id++) {
memset(sccb, 0, PAGE_SIZE);
sccb->header.length = PAGE_SIZE;
- rc = sclp_sync_request(0x00040001 | id << 8, sccb);
+ rc = sclp_sync_request(SCLP_CMDW_READ_STORAGE_INFO | id << 8, sccb);
if (rc)
goto out;
switch (sccb->header.response_code) {
diff --git a/drivers/s390/char/sclp_early.c b/drivers/s390/char/sclp_early.c
index 9a74abb9224d..e792cee3b51c 100644
--- a/drivers/s390/char/sclp_early.c
+++ b/drivers/s390/char/sclp_early.c
@@ -15,80 +15,17 @@
#include "sclp_sdias.h"
#include "sclp.h"
-#define SCLP_CMDW_READ_SCP_INFO 0x00020001
-#define SCLP_CMDW_READ_SCP_INFO_FORCED 0x00120001
-
-struct read_info_sccb {
- struct sccb_header header; /* 0-7 */
- u16 rnmax; /* 8-9 */
- u8 rnsize; /* 10 */
- u8 _pad_11[16 - 11]; /* 11-15 */
- u16 ncpurl; /* 16-17 */
- u16 cpuoff; /* 18-19 */
- u8 _pad_20[24 - 20]; /* 20-23 */
- u8 loadparm[8]; /* 24-31 */
- u8 _pad_32[42 - 32]; /* 32-41 */
- u8 fac42; /* 42 */
- u8 fac43; /* 43 */
- u8 _pad_44[48 - 44]; /* 44-47 */
- u64 facilities; /* 48-55 */
- u8 _pad_56[66 - 56]; /* 56-65 */
- u8 fac66; /* 66 */
- u8 _pad_67[76 - 67]; /* 67-83 */
- u32 ibc; /* 76-79 */
- u8 _pad80[84 - 80]; /* 80-83 */
- u8 fac84; /* 84 */
- u8 fac85; /* 85 */
- u8 _pad_86[91 - 86]; /* 86-90 */
- u8 fac91; /* 91 */
- u8 _pad_92[98 - 92]; /* 92-97 */
- u8 fac98; /* 98 */
- u8 hamaxpow; /* 99 */
- u32 rnsize2; /* 100-103 */
- u64 rnmax2; /* 104-111 */
- u8 _pad_112[116 - 112]; /* 112-115 */
- u8 fac116; /* 116 */
- u8 fac117; /* 117 */
- u8 fac118; /* 118 */
- u8 fac119; /* 119 */
- u16 hcpua; /* 120-121 */
- u8 _pad_122[124 - 122]; /* 122-123 */
- u32 hmfai; /* 124-127 */
- u8 _pad_128[4096 - 128]; /* 128-4095 */
-} __packed __aligned(PAGE_SIZE);
-
static struct sclp_ipl_info sclp_ipl_info;
struct sclp_info sclp;
EXPORT_SYMBOL(sclp);
-static int __init sclp_early_read_info(struct read_info_sccb *sccb)
-{
- int i;
- sclp_cmdw_t commands[] = {SCLP_CMDW_READ_SCP_INFO_FORCED,
- SCLP_CMDW_READ_SCP_INFO};
-
- for (i = 0; i < ARRAY_SIZE(commands); i++) {
- memset(sccb, 0, sizeof(*sccb));
- sccb->header.length = sizeof(*sccb);
- sccb->header.function_code = 0x80;
- sccb->header.control_mask[2] = 0x80;
- if (sclp_early_cmd(commands[i], sccb))
- break;
- if (sccb->header.response_code == 0x10)
- return 0;
- if (sccb->header.response_code != 0x1f0)
- break;
- }
- return -EIO;
-}
-
static void __init sclp_early_facilities_detect(struct read_info_sccb *sccb)
{
struct sclp_core_entry *cpue;
u16 boot_cpu_address, cpu;
- if (sclp_early_read_info(sccb))
+ if (sclp_early_get_info(sccb))
return;
sclp.facilities = sccb->facilities;
@@ -147,6 +84,8 @@ static void __init sclp_early_facilities_detect(struct read_info_sccb *sccb)
sclp_ipl_info.has_dump = 1;
memcpy(&sclp_ipl_info.loadparm, &sccb->loadparm, LOADPARM_LEN);
+ if (sccb->hsa_size)
+ sclp.hsa_size = (sccb->hsa_size - 1) * PAGE_SIZE;
sclp.mtid = (sccb->fac42 & 0x80) ? (sccb->fac42 & 31) : 0;
sclp.mtid_cp = (sccb->fac42 & 0x80) ? (sccb->fac43 & 31) : 0;
sclp.mtid_prev = (sccb->fac42 & 0x80) ? (sccb->fac66 & 31) : 0;
@@ -189,61 +128,6 @@ int __init sclp_early_get_core_info(struct sclp_core_info *info)
return 0;
}
-static long __init sclp_early_hsa_size_init(struct sdias_sccb *sccb)
-{
- memset(sccb, 0, sizeof(*sccb));
- sccb->hdr.length = sizeof(*sccb);
- sccb->evbuf.hdr.length = sizeof(struct sdias_evbuf);
- sccb->evbuf.hdr.type = EVTYP_SDIAS;
- sccb->evbuf.event_qual = SDIAS_EQ_SIZE;
- sccb->evbuf.data_id = SDIAS_DI_FCP_DUMP;
- sccb->evbuf.event_id = 4712;
- sccb->evbuf.dbs = 1;
- if (sclp_early_cmd(SCLP_CMDW_WRITE_EVENT_DATA, sccb))
- return -EIO;
- if (sccb->hdr.response_code != 0x20)
- return -EIO;
- if (sccb->evbuf.blk_cnt == 0)
- return 0;
- return (sccb->evbuf.blk_cnt - 1) * PAGE_SIZE;
-}
-
-static long __init sclp_early_hsa_copy_wait(struct sdias_sccb *sccb)
-{
- memset(sccb, 0, PAGE_SIZE);
- sccb->hdr.length = PAGE_SIZE;
- if (sclp_early_cmd(SCLP_CMDW_READ_EVENT_DATA, sccb))
- return -EIO;
- if ((sccb->hdr.response_code != 0x20) && (sccb->hdr.response_code != 0x220))
- return -EIO;
- if (sccb->evbuf.blk_cnt == 0)
- return 0;
- return (sccb->evbuf.blk_cnt - 1) * PAGE_SIZE;
-}
-
-static void __init sclp_early_hsa_size_detect(void *sccb)
-{
- unsigned long flags;
- long size = -EIO;
-
- raw_local_irq_save(flags);
- if (sclp_early_set_event_mask(sccb, EVTYP_SDIAS_MASK, EVTYP_SDIAS_MASK))
- goto out;
- size = sclp_early_hsa_size_init(sccb);
- /* First check for synchronous response (LPAR) */
- if (size)
- goto out_mask;
- if (!(S390_lowcore.ext_params & 1))
- sclp_early_wait_irq();
- size = sclp_early_hsa_copy_wait(sccb);
-out_mask:
- sclp_early_set_event_mask(sccb, 0, 0);
-out:
- raw_local_irq_restore(flags);
- if (size > 0)
- sclp.hsa_size = size;
-}
-
static void __init sclp_early_console_detect(struct init_sccb *sccb)
{
if (sccb->header.response_code != 0x20)
@@ -262,7 +146,6 @@ void __init sclp_early_detect(void)
sclp_early_facilities_detect(sccb);
sclp_early_init_core_info(sccb);
- sclp_early_hsa_size_detect(sccb);
/*
* Turn off SCLP event notifications. Also save remote masks in the
diff --git a/drivers/s390/char/sclp_early_core.c b/drivers/s390/char/sclp_early_core.c
index 2f61f5579aa5..387c114ded3f 100644
--- a/drivers/s390/char/sclp_early_core.c
+++ b/drivers/s390/char/sclp_early_core.c
@@ -9,9 +9,13 @@
#include <asm/lowcore.h>
#include <asm/ebcdic.h>
#include <asm/irq.h>
+#include <asm/sections.h>
+#include <asm/mem_detect.h>
#include "sclp.h"
#include "sclp_rw.h"
+static struct read_info_sccb __bootdata(sclp_info_sccb);
+static int __bootdata(sclp_info_sccb_valid);
char sclp_early_sccb[PAGE_SIZE] __aligned(PAGE_SIZE) __section(.data);
int sclp_init_state __section(.data) = sclp_init_state_uninitialized;
/*
@@ -234,3 +238,115 @@ void sclp_early_printk_force(const char *str)
{
__sclp_early_printk(str, strlen(str), 1);
}
+
+int __init sclp_early_read_info(void)
+{
+ int i;
+ struct read_info_sccb *sccb = &sclp_info_sccb;
+ sclp_cmdw_t commands[] = {SCLP_CMDW_READ_SCP_INFO_FORCED,
+ SCLP_CMDW_READ_SCP_INFO};
+
+ for (i = 0; i < ARRAY_SIZE(commands); i++) {
+ memset(sccb, 0, sizeof(*sccb));
+ sccb->header.length = sizeof(*sccb);
+ sccb->header.function_code = 0x80;
+ sccb->header.control_mask[2] = 0x80;
+ if (sclp_early_cmd(commands[i], sccb))
+ break;
+ if (sccb->header.response_code == 0x10) {
+ sclp_info_sccb_valid = 1;
+ return 0;
+ }
+ if (sccb->header.response_code != 0x1f0)
+ break;
+ }
+ return -EIO;
+}
+
+int __init sclp_early_get_info(struct read_info_sccb *info)
+{
+ if (!sclp_info_sccb_valid)
+ return -EIO;
+
+ *info = sclp_info_sccb;
+ return 0;
+}
+
+int __init sclp_early_get_memsize(unsigned long *mem)
+{
+ unsigned long rnmax;
+ unsigned long rnsize;
+ struct read_info_sccb *sccb = &sclp_info_sccb;
+
+ if (!sclp_info_sccb_valid)
+ return -EIO;
+
+ rnmax = sccb->rnmax ? sccb->rnmax : sccb->rnmax2;
+ rnsize = sccb->rnsize ? sccb->rnsize : sccb->rnsize2;
+ rnsize <<= 20;
+ *mem = rnsize * rnmax;
+ return 0;
+}
+
+int __init sclp_early_get_hsa_size(unsigned long *hsa_size)
+{
+ if (!sclp_info_sccb_valid)
+ return -EIO;
+
+ *hsa_size = 0;
+ if (sclp_info_sccb.hsa_size)
+ *hsa_size = (sclp_info_sccb.hsa_size - 1) * PAGE_SIZE;
+ return 0;
+}
+
+#define SCLP_STORAGE_INFO_FACILITY 0x0000400000000000UL
+
+void __weak __init add_mem_detect_block(u64 start, u64 end) {}
+int __init sclp_early_read_storage_info(void)
+{
+ struct read_storage_sccb *sccb = (struct read_storage_sccb *)&sclp_early_sccb;
+ int rc, id, max_id = 0;
+ unsigned long rn, rzm;
+ sclp_cmdw_t command;
+ u16 sn;
+
+ if (!sclp_info_sccb_valid)
+ return -EIO;
+
+ if (!(sclp_info_sccb.facilities & SCLP_STORAGE_INFO_FACILITY))
+ return -EOPNOTSUPP;
+
+ rzm = sclp_info_sccb.rnsize ?: sclp_info_sccb.rnsize2;
+ rzm <<= 20;
+
+ for (id = 0; id <= max_id; id++) {
+ memset(sclp_early_sccb, 0, sizeof(sclp_early_sccb));
+ sccb->header.length = sizeof(sclp_early_sccb);
+ command = SCLP_CMDW_READ_STORAGE_INFO | (id << 8);
+ rc = sclp_early_cmd(command, sccb);
+ if (rc)
+ goto fail;
+
+ max_id = sccb->max_id;
+ switch (sccb->header.response_code) {
+ case 0x0010:
+ for (sn = 0; sn < sccb->assigned; sn++) {
+ if (!sccb->entries[sn])
+ continue;
+ rn = sccb->entries[sn] >> 16;
+ add_mem_detect_block((rn - 1) * rzm, rn * rzm);
+ }
+ break;
+ case 0x0310:
+ case 0x0410:
+ break;
+ default:
+ goto fail;
+ }
+ }
+
+ return 0;
+fail:
+ mem_detect.count = 0;
+ return -EIO;
+}
diff --git a/drivers/s390/char/sclp_pci.c b/drivers/s390/char/sclp_pci.c
index e7c84a4e5eb5..995e9196852e 100644
--- a/drivers/s390/char/sclp_pci.c
+++ b/drivers/s390/char/sclp_pci.c
@@ -24,6 +24,7 @@
#define SCLP_ATYPE_PCI 2
+#define SCLP_ERRNOTIFY_AQ_RESET 0
#define SCLP_ERRNOTIFY_AQ_REPAIR 1
#define SCLP_ERRNOTIFY_AQ_INFO_LOG 2
@@ -111,9 +112,14 @@ static int sclp_pci_check_report(struct zpci_report_error_header *report)
if (report->version != 1)
return -EINVAL;
- if (report->action != SCLP_ERRNOTIFY_AQ_REPAIR &&
- report->action != SCLP_ERRNOTIFY_AQ_INFO_LOG)
+ switch (report->action) {
+ case SCLP_ERRNOTIFY_AQ_RESET:
+ case SCLP_ERRNOTIFY_AQ_REPAIR:
+ case SCLP_ERRNOTIFY_AQ_INFO_LOG:
+ break;
+ default:
return -EINVAL;
+ }
if (report->length > (PAGE_SIZE - sizeof(struct err_notify_sccb)))
return -EINVAL;
diff --git a/drivers/s390/char/tape_3590.c b/drivers/s390/char/tape_3590.c
index cdcde18e7220..4554cdf4d6bd 100644
--- a/drivers/s390/char/tape_3590.c
+++ b/drivers/s390/char/tape_3590.c
@@ -971,7 +971,7 @@ tape_3590_print_mim_msg_f0(struct tape_device *device, struct irb *irb)
snprintf(exception, BUFSIZE, "Data degraded");
break;
case 0x03:
- snprintf(exception, BUFSIZE, "Data degraded in partion %i",
+ snprintf(exception, BUFSIZE, "Data degraded in partition %i",
sense->fmt.f70.mp);
break;
case 0x04:
diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c
index 069b9ef08206..58333cb4503f 100644
--- a/drivers/s390/char/vmlogrdr.c
+++ b/drivers/s390/char/vmlogrdr.c
@@ -153,7 +153,7 @@ static struct vmlogrdr_priv_t sys_ser[] = {
}
};
-#define MAXMINOR (sizeof(sys_ser)/sizeof(struct vmlogrdr_priv_t))
+#define MAXMINOR ARRAY_SIZE(sys_ser)
static char FENCE[] = {"EOR"};
static int vmlogrdr_major = 0;
diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c
index 93b2862bd3fa..4ebf6d4fc66c 100644
--- a/drivers/s390/cio/ccwgroup.c
+++ b/drivers/s390/cio/ccwgroup.c
@@ -608,6 +608,36 @@ void ccwgroup_driver_unregister(struct ccwgroup_driver *cdriver)
}
EXPORT_SYMBOL(ccwgroup_driver_unregister);
+static int __ccwgroupdev_check_busid(struct device *dev, void *id)
+{
+ char *bus_id = id;
+
+ return (strcmp(bus_id, dev_name(dev)) == 0);
+}
+
+/**
+ * get_ccwgroupdev_by_busid() - obtain device from a bus id
+ * @gdrv: driver the device is owned by
+ * @bus_id: bus id of the device to be searched
+ *
+ * This function searches all devices owned by @gdrv for a device with a bus
+ * id matching @bus_id.
+ * Returns:
+ * If a match is found, its reference count of the found device is increased
+ * and it is returned; else %NULL is returned.
+ */
+struct ccwgroup_device *get_ccwgroupdev_by_busid(struct ccwgroup_driver *gdrv,
+ char *bus_id)
+{
+ struct device *dev;
+
+ dev = driver_find_device(&gdrv->driver, NULL, bus_id,
+ __ccwgroupdev_check_busid);
+
+ return dev ? to_ccwgroupdev(dev) : NULL;
+}
+EXPORT_SYMBOL_GPL(get_ccwgroupdev_by_busid);
+
/**
* ccwgroup_probe_ccwdev() - probe function for slave devices
* @cdev: ccw device to be probed
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c
index 9c7d9da42ba0..9537e656e927 100644
--- a/drivers/s390/cio/qdio_main.c
+++ b/drivers/s390/cio/qdio_main.c
@@ -595,19 +595,11 @@ static inline int qdio_inbound_q_done(struct qdio_q *q)
return 0;
}
-static inline int contains_aobs(struct qdio_q *q)
-{
- return !q->is_input_q && q->u.out.use_cq;
-}
-
static inline void qdio_handle_aobs(struct qdio_q *q, int start, int count)
{
unsigned char state = 0;
int j, b = start;
- if (!contains_aobs(q))
- return;
-
for (j = 0; j < count; ++j) {
get_buf_state(q, b, &state, 0);
if (state == SLSB_P_OUTPUT_PENDING) {
@@ -618,8 +610,6 @@ static inline void qdio_handle_aobs(struct qdio_q *q, int start, int count)
q->u.out.sbal_state[b].flags |=
QDIO_OUTBUF_STATE_FLAG_PENDING;
q->u.out.aobs[b] = NULL;
- } else if (state == SLSB_P_OUTPUT_EMPTY) {
- q->u.out.sbal_state[b].aob = NULL;
}
b = next_buf(b);
}
@@ -638,7 +628,6 @@ static inline unsigned long qdio_aob_for_buffer(struct qdio_output_q *q,
q->aobs[bufnr] = aob;
}
if (q->aobs[bufnr]) {
- q->sbal_state[bufnr].aob = q->aobs[bufnr];
q->aobs[bufnr]->user1 = (u64) q->sbal_state[bufnr].user;
phys_aob = virt_to_phys(q->aobs[bufnr]);
WARN_ON_ONCE(phys_aob & 0xFF);
@@ -666,10 +655,10 @@ static void qdio_kick_handler(struct qdio_q *q)
qperf_inc(q, outbound_handler);
DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "koh: s:%02x c:%02x",
start, count);
+ if (q->u.out.use_cq)
+ qdio_handle_aobs(q, start, count);
}
- qdio_handle_aobs(q, start, count);
-
q->handler(q->irq_ptr->cdev, q->qdio_error, q->nr, start, count,
q->irq_ptr->int_parm);
diff --git a/drivers/s390/cio/qdio_setup.c b/drivers/s390/cio/qdio_setup.c
index 78f1be41b05e..e324d890a4f6 100644
--- a/drivers/s390/cio/qdio_setup.c
+++ b/drivers/s390/cio/qdio_setup.c
@@ -27,7 +27,6 @@ struct qaob *qdio_allocate_aob(void)
{
return kmem_cache_zalloc(qdio_aob_cache, GFP_ATOMIC);
}
-EXPORT_SYMBOL_GPL(qdio_allocate_aob);
void qdio_release_aob(struct qaob *aob)
{
diff --git a/drivers/s390/crypto/Makefile b/drivers/s390/crypto/Makefile
index b59af548ed1c..fd5e215c66b7 100644
--- a/drivers/s390/crypto/Makefile
+++ b/drivers/s390/crypto/Makefile
@@ -10,7 +10,7 @@ zcrypt-objs := zcrypt_api.o zcrypt_card.o zcrypt_queue.o
zcrypt-objs += zcrypt_msgtype6.o zcrypt_msgtype50.o
obj-$(CONFIG_ZCRYPT) += zcrypt.o
# adapter drivers depend on ap.o and zcrypt.o
-obj-$(CONFIG_ZCRYPT) += zcrypt_pcixcc.o zcrypt_cex2a.o zcrypt_cex4.o
+obj-$(CONFIG_ZCRYPT) += zcrypt_cex2c.o zcrypt_cex2a.o zcrypt_cex4.o
# pkey kernel module
pkey-objs := pkey_api.o
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c
index f039266b275d..048665e4f13d 100644
--- a/drivers/s390/crypto/ap_bus.c
+++ b/drivers/s390/crypto/ap_bus.c
@@ -65,12 +65,11 @@ 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);
+/* Default permissions (ioctl, card and domain masking) */
+struct ap_perms ap_perms;
+EXPORT_SYMBOL(ap_perms);
+DEFINE_MUTEX(ap_perms_mutex);
+EXPORT_SYMBOL(ap_perms_mutex);
static struct ap_config_info *ap_configuration;
static bool initialised;
@@ -944,21 +943,9 @@ static int modify_bitmap(const char *str, unsigned long *bitmap, int bits)
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 ap_parse_mask_str(const char *str,
+ unsigned long *bitmap, int bits,
+ struct mutex *lock)
{
unsigned long *newmap, size;
int rc;
@@ -989,6 +976,7 @@ static int process_mask_arg(const char *str,
kfree(newmap);
return rc;
}
+EXPORT_SYMBOL(ap_parse_mask_str);
/*
* AP bus attributes.
@@ -1049,6 +1037,21 @@ static ssize_t ap_usage_domain_mask_show(struct bus_type *bus, char *buf)
static BUS_ATTR_RO(ap_usage_domain_mask);
+static ssize_t ap_adapter_mask_show(struct bus_type *bus, char *buf)
+{
+ if (!ap_configuration) /* QCI not supported */
+ return snprintf(buf, PAGE_SIZE, "not supported\n");
+
+ return snprintf(buf, PAGE_SIZE,
+ "0x%08x%08x%08x%08x%08x%08x%08x%08x\n",
+ ap_configuration->apm[0], ap_configuration->apm[1],
+ ap_configuration->apm[2], ap_configuration->apm[3],
+ ap_configuration->apm[4], ap_configuration->apm[5],
+ ap_configuration->apm[6], ap_configuration->apm[7]);
+}
+
+static BUS_ATTR_RO(ap_adapter_mask);
+
static ssize_t ap_interrupts_show(struct bus_type *bus, char *buf)
{
return snprintf(buf, PAGE_SIZE, "%d\n",
@@ -1161,7 +1164,7 @@ static ssize_t apmask_store(struct bus_type *bus, const char *buf,
{
int rc;
- rc = process_mask_arg(buf, ap_perms.apm, AP_DEVICES, &ap_perms_mutex);
+ rc = ap_parse_mask_str(buf, ap_perms.apm, AP_DEVICES, &ap_perms_mutex);
if (rc)
return rc;
@@ -1192,7 +1195,7 @@ static ssize_t aqmask_store(struct bus_type *bus, const char *buf,
{
int rc;
- rc = process_mask_arg(buf, ap_perms.aqm, AP_DOMAINS, &ap_perms_mutex);
+ rc = ap_parse_mask_str(buf, ap_perms.aqm, AP_DOMAINS, &ap_perms