aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-01-28 12:02:24 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-01-28 12:02:24 -0500
commite770d73ceb93c235525cb9bbbf1374c9b61a0895 (patch)
treeac72b64d1978fece984c8b5a27442acbef7f172c
parentbe86497152220677e3e5cb326519e19d727f8674 (diff)
parent07be0382097027cde68d9268cc628741069b5762 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 patches from Martin Schwidefsky: "A new binary interface to be able to query and modify the LPAR scheduler weight and cap settings. Some improvements for the hvc terminal over iucv and a couple of bux fixes" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: s390/hypfs: add interface for diagnose 0x304 s390: wire up sys_sched_setattr/sys_sched_getattr s390/uapi: fix struct statfs64 definition s390/uaccess: remove dead extern declarations, make functions static s390/uaccess: test if current->mm is set before walking page tables s390/zfcpdump: make zfcpdump depend on 64BIT s390/32bit: fix cmpxchg64 s390/xpram: don't modify module parameters s390/zcrypt: remove zcrypt kmsg documentation again s390/hvc_iucv: Automatically assign free HVC terminal devices s390/hvc_iucv: Display connection details through device attributes s390/hvc_iucv: fix sparse warning s390/vmur: Link parent CCW device during UR device creation
-rw-r--r--Documentation/ioctl/ioctl-number.txt1
-rw-r--r--Documentation/kmsg/s390/zcrypt20
-rw-r--r--arch/s390/Kconfig2
-rw-r--r--arch/s390/hypfs/Makefile2
-rw-r--r--arch/s390/hypfs/hypfs.h7
-rw-r--r--arch/s390/hypfs/hypfs_dbfs.c16
-rw-r--r--arch/s390/hypfs/hypfs_sprp.c141
-rw-r--r--arch/s390/hypfs/inode.c15
-rw-r--r--arch/s390/include/asm/cmpxchg.h5
-rw-r--r--arch/s390/include/asm/sclp.h1
-rw-r--r--arch/s390/include/uapi/asm/hypfs.h25
-rw-r--r--arch/s390/include/uapi/asm/statfs.h10
-rw-r--r--arch/s390/include/uapi/asm/unistd.h2
-rw-r--r--arch/s390/kernel/compat_wrapper.S11
-rw-r--r--arch/s390/kernel/syscalls.S2
-rw-r--r--arch/s390/lib/uaccess.h9
-rw-r--r--arch/s390/lib/uaccess_pt.c14
-rw-r--r--drivers/s390/block/xpram.c5
-rw-r--r--drivers/s390/char/sclp_cmd.c5
-rw-r--r--drivers/s390/char/vmur.c4
-rw-r--r--drivers/tty/hvc/hvc_iucv.c103
21 files changed, 344 insertions, 56 deletions
diff --git a/Documentation/ioctl/ioctl-number.txt b/Documentation/ioctl/ioctl-number.txt
index 7cbfa3c4fc3d..d7e43fa88575 100644
--- a/Documentation/ioctl/ioctl-number.txt
+++ b/Documentation/ioctl/ioctl-number.txt
@@ -73,6 +73,7 @@ Code Seq#(hex) Include File Comments
730x09 all linux/raid/md_u.h 730x09 all linux/raid/md_u.h
740x10 00-0F drivers/char/s390/vmcp.h 740x10 00-0F drivers/char/s390/vmcp.h
750x10 10-1F arch/s390/include/uapi/sclp_ctl.h 750x10 10-1F arch/s390/include/uapi/sclp_ctl.h
760x10 20-2F arch/s390/include/uapi/asm/hypfs.h
760x12 all linux/fs.h 770x12 all linux/fs.h
77 linux/blkpg.h 78 linux/blkpg.h
780x1b all InfiniBand Subsystem <http://infiniband.sourceforge.net/> 790x1b all InfiniBand Subsystem <http://infiniband.sourceforge.net/>
diff --git a/Documentation/kmsg/s390/zcrypt b/Documentation/kmsg/s390/zcrypt
deleted file mode 100644
index 7fb2087409d6..000000000000
--- a/Documentation/kmsg/s390/zcrypt
+++ /dev/null
@@ -1,20 +0,0 @@
1/*?
2 * Text: "Cryptographic device %x failed and was set offline\n"
3 * Severity: Error
4 * Parameter:
5 * @1: device index
6 * Description:
7 * A cryptographic device failed to process a cryptographic request.
8 * The cryptographic device driver could not correct the error and
9 * set the device offline. The application that issued the
10 * request received an indication that the request has failed.
11 * User action:
12 * Use the lszcrypt command to confirm that the cryptographic
13 * hardware is still configured to your LPAR or z/VM guest virtual
14 * machine. If the device is available to your Linux instance the
15 * command output contains a line that begins with 'card<device index>',
16 * where <device index> is the two-digit decimal number in the message text.
17 * After ensuring that the device is available, use the chzcrypt command to
18 * set it online again.
19 * If the error persists, contact your support organization.
20 */
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 4f858f77d870..65a07750f4f9 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -596,7 +596,7 @@ config CRASH_DUMP
596config ZFCPDUMP 596config ZFCPDUMP
597 def_bool n 597 def_bool n
598 prompt "zfcpdump support" 598 prompt "zfcpdump support"
599 depends on SMP 599 depends on 64BIT && SMP
600 help 600 help
601 Select this option if you want to build an zfcpdump enabled kernel. 601 Select this option if you want to build an zfcpdump enabled kernel.
602 Refer to <file:Documentation/s390/zfcpdump.txt> for more details on this. 602 Refer to <file:Documentation/s390/zfcpdump.txt> for more details on this.
diff --git a/arch/s390/hypfs/Makefile b/arch/s390/hypfs/Makefile
index 2e671d5004ca..06f8d95a16cd 100644
--- a/arch/s390/hypfs/Makefile
+++ b/arch/s390/hypfs/Makefile
@@ -4,4 +4,4 @@
4 4
5obj-$(CONFIG_S390_HYPFS_FS) += s390_hypfs.o 5obj-$(CONFIG_S390_HYPFS_FS) += s390_hypfs.o
6 6
7s390_hypfs-objs := inode.o hypfs_diag.o hypfs_vm.o hypfs_dbfs.o 7s390_hypfs-objs := inode.o hypfs_diag.o hypfs_vm.o hypfs_dbfs.o hypfs_sprp.o
diff --git a/arch/s390/hypfs/hypfs.h b/arch/s390/hypfs/hypfs.h
index 79f2ac55253f..b34b5ab90a31 100644
--- a/arch/s390/hypfs/hypfs.h
+++ b/arch/s390/hypfs/hypfs.h
@@ -13,6 +13,7 @@
13#include <linux/debugfs.h> 13#include <linux/debugfs.h>
14#include <linux/workqueue.h> 14#include <linux/workqueue.h>
15#include <linux/kref.h> 15#include <linux/kref.h>
16#include <asm/hypfs.h>
16 17
17#define REG_FILE_MODE 0440 18#define REG_FILE_MODE 0440
18#define UPDATE_FILE_MODE 0220 19#define UPDATE_FILE_MODE 0220
@@ -36,6 +37,10 @@ extern int hypfs_vm_init(void);
36extern void hypfs_vm_exit(void); 37extern void hypfs_vm_exit(void);
37extern int hypfs_vm_create_files(struct dentry *root); 38extern int hypfs_vm_create_files(struct dentry *root);
38 39
40/* Set Partition-Resource Parameter */
41int hypfs_sprp_init(void);
42void hypfs_sprp_exit(void);
43
39/* debugfs interface */ 44/* debugfs interface */
40struct hypfs_dbfs_file; 45struct hypfs_dbfs_file;
41 46
@@ -52,6 +57,8 @@ struct hypfs_dbfs_file {
52 int (*data_create)(void **data, void **data_free_ptr, 57 int (*data_create)(void **data, void **data_free_ptr,
53 size_t *size); 58 size_t *size);
54 void (*data_free)(const void *buf_free_ptr); 59 void (*data_free)(const void *buf_free_ptr);
60 long (*unlocked_ioctl) (struct file *, unsigned int,
61 unsigned long);
55 62
56 /* Private data for hypfs_dbfs.c */ 63 /* Private data for hypfs_dbfs.c */
57 struct hypfs_dbfs_data *data; 64 struct hypfs_dbfs_data *data;
diff --git a/arch/s390/hypfs/hypfs_dbfs.c b/arch/s390/hypfs/hypfs_dbfs.c
index 17ab8b7b53cc..2badf2bf9cd7 100644
--- a/arch/s390/hypfs/hypfs_dbfs.c
+++ b/arch/s390/hypfs/hypfs_dbfs.c
@@ -81,9 +81,25 @@ static ssize_t dbfs_read(struct file *file, char __user *buf,
81 return rc; 81 return rc;
82} 82}
83 83
84static long dbfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
85{
86 struct hypfs_dbfs_file *df;
87 long rc;
88
89 df = file->f_path.dentry->d_inode->i_private;
90 mutex_lock(&df->lock);
91 if (df->unlocked_ioctl)
92 rc = df->unlocked_ioctl(file, cmd, arg);
93 else
94 rc = -ENOTTY;
95 mutex_unlock(&df->lock);
96 return rc;
97}
98
84static const struct file_operations dbfs_ops = { 99static const struct file_operations dbfs_ops = {
85 .read = dbfs_read, 100 .read = dbfs_read,
86 .llseek = no_llseek, 101 .llseek = no_llseek,
102 .unlocked_ioctl = dbfs_ioctl,
87}; 103};
88 104
89int hypfs_dbfs_create_file(struct hypfs_dbfs_file *df) 105int hypfs_dbfs_create_file(struct hypfs_dbfs_file *df)
diff --git a/arch/s390/hypfs/hypfs_sprp.c b/arch/s390/hypfs/hypfs_sprp.c
new file mode 100644
index 000000000000..f043c3c7e73c
--- /dev/null
+++ b/arch/s390/hypfs/hypfs_sprp.c
@@ -0,0 +1,141 @@
1/*
2 * Hypervisor filesystem for Linux on s390.
3 * Set Partition-Resource Parameter interface.
4 *
5 * Copyright IBM Corp. 2013
6 * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
7 */
8
9#include <linux/compat.h>
10#include <linux/errno.h>
11#include <linux/gfp.h>
12#include <linux/string.h>
13#include <linux/types.h>
14#include <linux/uaccess.h>
15#include <asm/compat.h>
16#include <asm/sclp.h>
17#include "hypfs.h"
18
19#define DIAG304_SET_WEIGHTS 0
20#define DIAG304_QUERY_PRP 1
21#define DIAG304_SET_CAPPING 2
22
23#define DIAG304_CMD_MAX 2
24
25static unsigned long hypfs_sprp_diag304(void *data, unsigned long cmd)
26{
27 register unsigned long _data asm("2") = (unsigned long) data;
28 register unsigned long _rc asm("3");
29 register unsigned long _cmd asm("4") = cmd;
30
31 asm volatile("diag %1,%2,0x304\n"
32 : "=d" (_rc) : "d" (_data), "d" (_cmd) : "memory");
33
34 return _rc;
35}
36
37static void hypfs_sprp_free(const void *data)
38{
39 free_page((unsigned long) data);
40}
41
42static int hypfs_sprp_create(void **data_ptr, void **free_ptr, size_t *size)
43{
44 unsigned long rc;
45 void *data;
46
47 data = (void *) get_zeroed_page(GFP_KERNEL);
48 if (!data)
49 return -ENOMEM;
50 rc = hypfs_sprp_diag304(data, DIAG304_QUERY_PRP);
51 if (rc != 1) {
52 *data_ptr = *free_ptr = NULL;
53 *size = 0;
54 free_page((unsigned long) data);
55 return -EIO;
56 }
57 *data_ptr = *free_ptr = data;
58 *size = PAGE_SIZE;
59 return 0;
60}
61
62static int __hypfs_sprp_ioctl(void __user *user_area)
63{
64 struct hypfs_diag304 diag304;
65 unsigned long cmd;
66 void __user *udata;
67 void *data;
68 int rc;
69
70 if (copy_from_user(&diag304, user_area, sizeof(diag304)))
71 return -EFAULT;
72 if ((diag304.args[0] >> 8) != 0 || diag304.args[1] > DIAG304_CMD_MAX)
73 return -EINVAL;
74
75 data = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
76 if (!data)
77 return -ENOMEM;
78
79 udata = (void __user *)(unsigned long) diag304.data;
80 if (diag304.args[1] == DIAG304_SET_WEIGHTS ||
81 diag304.args[1] == DIAG304_SET_CAPPING)
82 if (copy_from_user(data, udata, PAGE_SIZE)) {
83 rc = -EFAULT;
84 goto out;
85 }
86
87 cmd = *(unsigned long *) &diag304.args[0];
88 diag304.rc = hypfs_sprp_diag304(data, cmd);
89
90 if (diag304.args[1] == DIAG304_QUERY_PRP)
91 if (copy_to_user(udata, data, PAGE_SIZE)) {
92 rc = -EFAULT;
93 goto out;
94 }
95
96 rc = copy_to_user(user_area, &diag304, sizeof(diag304)) ? -EFAULT : 0;
97out:
98 free_page((unsigned long) data);
99 return rc;
100}
101
102static long hypfs_sprp_ioctl(struct file *file, unsigned int cmd,
103 unsigned long arg)
104{
105 void __user *argp;
106
107 if (!capable(CAP_SYS_ADMIN))
108 return -EACCES;
109 if (is_compat_task())
110 argp = compat_ptr(arg);
111 else
112 argp = (void __user *) arg;
113 switch (cmd) {
114 case HYPFS_DIAG304:
115 return __hypfs_sprp_ioctl(argp);
116 default: /* unknown ioctl number */
117 return -ENOTTY;
118 }
119 return 0;
120}
121
122static struct hypfs_dbfs_file hypfs_sprp_file = {
123 .name = "diag_304",
124 .data_create = hypfs_sprp_create,
125 .data_free = hypfs_sprp_free,
126 .unlocked_ioctl = hypfs_sprp_ioctl,
127};
128
129int hypfs_sprp_init(void)
130{
131 if (!sclp_has_sprp())
132 return 0;
133 return hypfs_dbfs_create_file(&hypfs_sprp_file);
134}
135
136void hypfs_sprp_exit(void)
137{
138 if (!sclp_has_sprp())
139 return;
140 hypfs_dbfs_remove_file(&hypfs_sprp_file);
141}
diff --git a/arch/s390/hypfs/inode.c b/arch/s390/hypfs/inode.c
index ddfe09b45134..c952b981e4f2 100644
--- a/arch/s390/hypfs/inode.c
+++ b/arch/s390/hypfs/inode.c
@@ -478,10 +478,14 @@ static int __init hypfs_init(void)
478 rc = -ENODATA; 478 rc = -ENODATA;
479 goto fail_hypfs_diag_exit; 479 goto fail_hypfs_diag_exit;
480 } 480 }
481 if (hypfs_sprp_init()) {
482 rc = -ENODATA;
483 goto fail_hypfs_vm_exit;
484 }
481 s390_kobj = kobject_create_and_add("s390", hypervisor_kobj); 485 s390_kobj = kobject_create_and_add("s390", hypervisor_kobj);
482 if (!s390_kobj) { 486 if (!s390_kobj) {
483 rc = -ENOMEM; 487 rc = -ENOMEM;
484 goto fail_hypfs_vm_exit; 488 goto fail_hypfs_sprp_exit;
485 } 489 }
486 rc = register_filesystem(&hypfs_type); 490 rc = register_filesystem(&hypfs_type);
487 if (rc) 491 if (rc)
@@ -490,6 +494,8 @@ static int __init hypfs_init(void)
490 494
491fail_filesystem: 495fail_filesystem:
492 kobject_put(s390_kobj); 496 kobject_put(s390_kobj);
497fail_hypfs_sprp_exit:
498 hypfs_sprp_exit();
493fail_hypfs_vm_exit: 499fail_hypfs_vm_exit:
494 hypfs_vm_exit(); 500 hypfs_vm_exit();
495fail_hypfs_diag_exit: 501fail_hypfs_diag_exit:
@@ -502,11 +508,12 @@ fail_dbfs_exit:
502 508
503static void __exit hypfs_exit(void) 509static void __exit hypfs_exit(void)
504{ 510{
505 hypfs_diag_exit();
506 hypfs_vm_exit();
507 hypfs_dbfs_exit();
508 unregister_filesystem(&hypfs_type); 511 unregister_filesystem(&hypfs_type);
509 kobject_put(s390_kobj); 512 kobject_put(s390_kobj);
513 hypfs_sprp_exit();
514 hypfs_vm_exit();
515 hypfs_diag_exit();
516 hypfs_dbfs_exit();
510} 517}
511 518
512module_init(hypfs_init) 519module_init(hypfs_init)
diff --git a/arch/s390/include/asm/cmpxchg.h b/arch/s390/include/asm/cmpxchg.h
index 0f636cbdf342..4236408070e5 100644
--- a/arch/s390/include/asm/cmpxchg.h
+++ b/arch/s390/include/asm/cmpxchg.h
@@ -185,11 +185,12 @@ static inline unsigned long long __cmpxchg64(void *ptr,
185{ 185{
186 register_pair rp_old = {.pair = old}; 186 register_pair rp_old = {.pair = old};
187 register_pair rp_new = {.pair = new}; 187 register_pair rp_new = {.pair = new};
188 unsigned long long *ullptr = ptr;
188 189
189 asm volatile( 190 asm volatile(
190 " cds %0,%2,%1" 191 " cds %0,%2,%1"
191 : "+&d" (rp_old), "=Q" (ptr) 192 : "+d" (rp_old), "+Q" (*ullptr)
192 : "d" (rp_new), "Q" (ptr) 193 : "d" (rp_new)
193 : "memory", "cc"); 194 : "memory", "cc");
194 return rp_old.pair; 195 return rp_old.pair;
195} 196}
diff --git a/arch/s390/include/asm/sclp.h b/arch/s390/include/asm/sclp.h
index 220e171413f8..abaca2275c7a 100644
--- a/arch/s390/include/asm/sclp.h
+++ b/arch/s390/include/asm/sclp.h
@@ -54,6 +54,7 @@ int sclp_chp_read_info(struct sclp_chp_info *info);
54void sclp_get_ipl_info(struct sclp_ipl_info *info); 54void sclp_get_ipl_info(struct sclp_ipl_info *info);
55bool __init sclp_has_linemode(void); 55bool __init sclp_has_linemode(void);
56bool __init sclp_has_vt220(void); 56bool __init sclp_has_vt220(void);
57bool sclp_has_sprp(void);
57int sclp_pci_configure(u32 fid); 58int sclp_pci_configure(u32 fid);
58int sclp_pci_deconfigure(u32 fid); 59int sclp_pci_deconfigure(u32 fid);
59int memcpy_hsa(void *dest, unsigned long src, size_t count, int mode); 60int memcpy_hsa(void *dest, unsigned long src, size_t count, int mode);
diff --git a/arch/s390/include/uapi/asm/hypfs.h b/arch/s390/include/uapi/asm/hypfs.h
new file mode 100644
index 000000000000..37998b449531
--- /dev/null
+++ b/arch/s390/include/uapi/asm/hypfs.h
@@ -0,0 +1,25 @@
1/*
2 * IOCTL interface for hypfs
3 *
4 * Copyright IBM Corp. 2013
5 *
6 * Author: Martin Schwidefsky <schwidefsky@de.ibm.com>
7 */
8
9#ifndef _ASM_HYPFS_CTL_H
10#define _ASM_HYPFS_CTL_H
11
12#include <linux/types.h>
13
14struct hypfs_diag304 {
15 __u32 args[2];
16 __u64 data;
17 __u64 rc;
18} __attribute__((packed));
19
20#define HYPFS_IOCTL_MAGIC 0x10
21
22#define HYPFS_DIAG304 \
23 _IOWR(HYPFS_IOCTL_MAGIC, 0x20, struct hypfs_diag304)
24
25#endif
diff --git a/arch/s390/include/uapi/asm/statfs.h b/arch/s390/include/uapi/asm/statfs.h
index a61d538756f2..471eb09184d4 100644
--- a/arch/s390/include/uapi/asm/statfs.h
+++ b/arch/s390/include/uapi/asm/statfs.h
@@ -35,11 +35,11 @@ struct statfs {
35struct statfs64 { 35struct statfs64 {
36 unsigned int f_type; 36 unsigned int f_type;
37 unsigned int f_bsize; 37 unsigned int f_bsize;
38 unsigned long f_blocks; 38 unsigned long long f_blocks;
39 unsigned long f_bfree; 39 unsigned long long f_bfree;
40 unsigned long f_bavail; 40 unsigned long long f_bavail;
41 unsigned long f_files; 41 unsigned long long f_files;
42 unsigned long f_ffree; 42 unsigned long long f_ffree;
43 __kernel_fsid_t f_fsid; 43 __kernel_fsid_t f_fsid;
44 unsigned int f_namelen; 44 unsigned int f_namelen;
45 unsigned int f_frsize; 45 unsigned int f_frsize;
diff --git a/arch/s390/include/uapi/asm/unistd.h b/arch/s390/include/uapi/asm/unistd.h
index 864f693c237f..5eb5c9ddb120 100644
--- a/arch/s390/include/uapi/asm/unistd.h
+++ b/arch/s390/include/uapi/asm/unistd.h
@@ -280,6 +280,8 @@
280#define __NR_s390_runtime_instr 342 280#define __NR_s390_runtime_instr 342
281#define __NR_kcmp 343 281#define __NR_kcmp 343
282#define __NR_finit_module 344 282#define __NR_finit_module 344
283#define __NR_sched_setattr 345
284#define __NR_sched_getattr 346
283#define NR_syscalls 345 285#define NR_syscalls 345
284 286
285/* 287/*
diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S
index 9cb1b975b353..59c8efce1b99 100644
--- a/arch/s390/kernel/compat_wrapper.S
+++ b/arch/s390/kernel/compat_wrapper.S
@@ -1412,3 +1412,14 @@ ENTRY(sys_finit_module_wrapper)
1412 llgtr %r3,%r3 # const char __user * 1412 llgtr %r3,%r3 # const char __user *
1413 lgfr %r4,%r4 # int 1413 lgfr %r4,%r4 # int
1414 jg sys_finit_module 1414 jg sys_finit_module
1415
1416ENTRY(sys_sched_setattr_wrapper)
1417 lgfr %r2,%r2 # pid_t
1418 llgtr %r3,%r3 # struct sched_attr __user *
1419 jg sys_sched_setattr
1420
1421ENTRY(sys_sched_getattr_wrapper)
1422 lgfr %r2,%r2 # pid_t
1423 llgtr %r3,%r3 # const char __user *
1424 llgfr %r3,%r3 # unsigned int
1425 jg sys_sched_getattr
diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S
index 913410bd74a3..143992152ec9 100644
--- a/arch/s390/kernel/syscalls.S
+++ b/arch/s390/kernel/syscalls.S
@@ -353,3 +353,5 @@ SYSCALL(sys_process_vm_writev,sys_process_vm_writev,compat_sys_process_vm_writev
353SYSCALL(sys_ni_syscall,sys_s390_runtime_instr,sys_s390_runtime_instr_wrapper) 353SYSCALL(sys_ni_syscall,sys_s390_runtime_instr,sys_s390_runtime_instr_wrapper)
354SYSCALL(sys_kcmp,sys_kcmp,sys_kcmp_wrapper) 354SYSCALL(sys_kcmp,sys_kcmp,sys_kcmp_wrapper)
355SYSCALL(sys_finit_module,sys_finit_module,sys_finit_module_wrapper) 355SYSCALL(sys_finit_module,sys_finit_module,sys_finit_module_wrapper)
356SYSCALL(sys_sched_setattr,sys_sched_setattr,sys_sched_setattr_wrapper) /* 345 */
357SYSCALL(sys_sched_getattr,sys_sched_getattr,sys_sched_getattr_wrapper)
diff --git a/arch/s390/lib/uaccess.h b/arch/s390/lib/uaccess.h
index 315dbe09983e..b1a22173d027 100644
--- a/arch/s390/lib/uaccess.h
+++ b/arch/s390/lib/uaccess.h
@@ -6,15 +6,6 @@
6#ifndef __ARCH_S390_LIB_UACCESS_H 6#ifndef __ARCH_S390_LIB_UACCESS_H
7#define __ARCH_S390_LIB_UACCESS_H 7#define __ARCH_S390_LIB_UACCESS_H
8 8
9extern size_t copy_from_user_std(size_t, const void __user *, void *);
10extern size_t copy_to_user_std(size_t, void __user *, const void *);
11extern size_t strnlen_user_std(size_t, const char __user *);
12extern size_t strncpy_from_user_std(size_t, const char __user *, char *);
13extern int futex_atomic_cmpxchg_std(u32 *, u32 __user *, u32, u32);
14extern int futex_atomic_op_std(int, u32 __user *, int, int *);
15
16extern size_t copy_from_user_pt(size_t, const void __user *, void *);
17extern size_t copy_to_user_pt(size_t, void __user *, const void *);
18extern int futex_atomic_op_pt(int, u32 __user *, int, int *); 9extern int futex_atomic_op_pt(int, u32 __user *, int, int *);
19extern int futex_atomic_cmpxchg_pt(u32 *, u32 __user *, u32, u32); 10extern int futex_atomic_cmpxchg_pt(u32 *, u32 __user *, u32, u32);
20 11
diff --git a/arch/s390/lib/uaccess_pt.c b/arch/s390/lib/uaccess_pt.c
index 0632dc50da78..61ebcc9ccb34 100644
--- a/arch/s390/lib/uaccess_pt.c
+++ b/arch/s390/lib/uaccess_pt.c
@@ -153,6 +153,8 @@ static __always_inline size_t __user_copy_pt(unsigned long uaddr, void *kptr,
153 unsigned long offset, done, size, kaddr; 153 unsigned long offset, done, size, kaddr;
154 void *from, *to; 154 void *from, *to;
155 155
156 if (!mm)
157 return n;
156 done = 0; 158 done = 0;
157retry: 159retry:
158 spin_lock(&mm->page_table_lock); 160 spin_lock(&mm->page_table_lock);
@@ -209,7 +211,7 @@ fault:
209 return 0; 211 return 0;
210} 212}
211 213
212size_t copy_from_user_pt(size_t n, const void __user *from, void *to) 214static size_t copy_from_user_pt(size_t n, const void __user *from, void *to)
213{ 215{
214 size_t rc; 216 size_t rc;
215 217
@@ -221,7 +223,7 @@ size_t copy_from_user_pt(size_t n, const void __user *from, void *to)
221 return rc; 223 return rc;
222} 224}
223 225
224size_t copy_to_user_pt(size_t n, void __user *to, const void *from) 226static size_t copy_to_user_pt(size_t n, void __user *to, const void *from)
225{ 227{
226 if (segment_eq(get_fs(), KERNEL_DS)) 228 if (segment_eq(get_fs(), KERNEL_DS))
227 return copy_in_kernel(n, to, (void __user *) from); 229 return copy_in_kernel(n, to, (void __user *) from);
@@ -262,6 +264,8 @@ static size_t strnlen_user_pt(size_t count, const char __user *src)
262 return 0; 264 return 0;
263 if (segment_eq(get_fs(), KERNEL_DS)) 265 if (segment_eq(get_fs(), KERNEL_DS))
264 return strnlen_kernel(count, src); 266 return strnlen_kernel(count, src);
267 if (!mm)
268 return 0;
265 done = 0; 269 done = 0;
266retry: 270retry:
267 spin_lock(&mm->page_table_lock); 271 spin_lock(&mm->page_table_lock);
@@ -323,6 +327,8 @@ static size_t copy_in_user_pt(size_t n, void __user *to,
323 327
324 if (segment_eq(get_fs(), KERNEL_DS)) 328 if (segment_eq(get_fs(), KERNEL_DS))
325 return copy_in_kernel(n, to, from); 329 return copy_in_kernel(n, to, from);
330 if (!mm)
331 return n;
326 done = 0; 332 done = 0;
327retry: 333retry:
328 spin_lock(&mm->page_table_lock); 334 spin_lock(&mm->page_table_lock);
@@ -411,6 +417,8 @@ int futex_atomic_op_pt(int op, u32 __user *uaddr, int oparg, int *old)
411 417
412 if (segment_eq(get_fs(), KERNEL_DS)) 418 if (segment_eq(get_fs(), KERNEL_DS))
413 return __futex_atomic_op_pt(op, uaddr, oparg, old); 419 return __futex_atomic_op_pt(op, uaddr, oparg, old);
420 if (unlikely(!current->mm))
421 return -EFAULT;
414 spin_lock(&current->mm->page_table_lock); 422 spin_lock(&current->mm->page_table_lock);
415 uaddr = (u32 __force __user *) 423 uaddr = (u32 __force __user *)
416 __dat_user_addr((__force unsigned long) uaddr, 1); 424 __dat_user_addr((__force unsigned long) uaddr, 1);
@@ -448,6 +456,8 @@ int futex_atomic_cmpxchg_pt(u32 *uval, u32 __user *uaddr,
448 456
449 if (segment_eq(get_fs(), KERNEL_DS)) 457 if (segment_eq(get_fs(), KERNEL_DS))
450 return __futex_atomic_cmpxchg_pt(uval, uaddr, oldval, newval); 458 return __futex_atomic_cmpxchg_pt(uval, uaddr, oldval, newval);
459 if (unlikely(!current->mm))
460 return -EFAULT;
451 spin_lock(&current->mm->page_table_lock); 461 spin_lock(&current->mm->page_table_lock);
452 uaddr = (u32 __force __user *) 462 uaddr = (u32 __force __user *)
453 __dat_user_addr((__force unsigned long) uaddr, 1); 463 __dat_user_addr((__force unsigned long) uaddr, 1);
diff --git a/drivers/s390/block/xpram.c b/drivers/s390/block/xpram.c
index 464dd29d06c0..58141f0651f2 100644
--- a/drivers/s390/block/xpram.c
+++ b/drivers/s390/block/xpram.c
@@ -257,6 +257,7 @@ static int __init xpram_setup_sizes(unsigned long pages)
257 unsigned long mem_needed; 257 unsigned long mem_needed;
258 unsigned long mem_auto; 258 unsigned long mem_auto;
259 unsigned long long size; 259 unsigned long long size;
260 char *sizes_end;
260 int mem_auto_no; 261 int mem_auto_no;
261 int i; 262 int i;
262 263
@@ -275,8 +276,8 @@ static int __init xpram_setup_sizes(unsigned long pages)
275 mem_auto_no = 0; 276 mem_auto_no = 0;
276 for (i = 0; i < xpram_devs; i++) { 277 for (i = 0; i < xpram_devs; i++) {
277 if (sizes[i]) { 278 if (sizes[i]) {
278 size = simple_strtoull(sizes[i], &sizes[i], 0); 279 size = simple_strtoull(sizes[i], &sizes_end, 0);
279 switch (sizes[i][0]) { 280 switch (*sizes_end) {
280 case 'g': 281 case 'g':
281 case 'G': 282 case 'G':
282 size <<= 20; 283 size <<= 20;
diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c
index cb3c4e05a385..49af8eeb90ea 100644
--- a/drivers/s390/char/sclp_cmd.c
+++ b/drivers/s390/char/sclp_cmd.c
@@ -700,3 +700,8 @@ out:
700 free_page((unsigned long) sccb); 700 free_page((unsigned long) sccb);
701 return rc; 701 return rc;
702} 702}
703
704bool sclp_has_sprp(void)
705{
706 return !!(sclp_fac84 & 0x2);
707}
diff --git a/drivers/s390/char/vmur.c b/drivers/s390/char/vmur.c
index 64c467998a90..0efb27f6f199 100644
--- a/drivers/s390/char/vmur.c
+++ b/drivers/s390/char/vmur.c
@@ -922,8 +922,8 @@ static int ur_set_online(struct ccw_device *cdev)
922 goto fail_free_cdev; 922 goto fail_free_cdev;
923 } 923 }
924 924
925 urd->device = device_create(vmur_class, NULL, urd->char_device->dev, 925 urd->device = device_create(vmur_class, &cdev->dev,
926 NULL, "%s", node_id); 926 urd->char_device->dev, NULL, "%s", node_id);
927 if (IS_ERR(urd->device)) { 927 if (IS_ERR(urd->device)) {
928 rc = PTR_ERR(urd->device); 928 rc = PTR_ERR(urd->device);
929 TRACE("ur_set_online: device_create rc=%d\n", rc); 929 TRACE("ur_set_online: device_create rc=%d\n", rc);
diff --git a/drivers/tty/hvc/hvc_iucv.c b/drivers/tty/hvc/hvc_iucv.c
index db19a38c8c69..ea74460f3638 100644
--- a/drivers/tty/hvc/hvc_iucv.c
+++ b/drivers/tty/hvc/hvc_iucv.c
@@ -77,6 +77,7 @@ struct hvc_iucv_private {
77 struct list_head tty_outqueue; /* outgoing IUCV messages */ 77 struct list_head tty_outqueue; /* outgoing IUCV messages */
78 struct list_head tty_inqueue; /* incoming IUCV messages */ 78 struct list_head tty_inqueue; /* incoming IUCV messages */
79 struct device *dev; /* device structure */ 79 struct device *dev; /* device structure */
80 u8 info_path[16]; /* IUCV path info (dev attr) */
80}; 81};
81 82
82struct iucv_tty_buffer { 83struct iucv_tty_buffer {
@@ -126,7 +127,7 @@ static struct iucv_handler hvc_iucv_handler = {
126 * This function returns the struct hvc_iucv_private instance that corresponds 127 * This function returns the struct hvc_iucv_private instance that corresponds
127 * to the HVC virtual terminal number specified as parameter @num. 128 * to the HVC virtual terminal number specified as parameter @num.
128 */ 129 */
129struct hvc_iucv_private *hvc_iucv_get_private(uint32_t num) 130static struct hvc_iucv_private *hvc_iucv_get_private(uint32_t num)
130{ 131{
131 if ((num < HVC_IUCV_MAGIC) || (num - HVC_IUCV_MAGIC > hvc_iucv_devices)) 132 if ((num < HVC_IUCV_MAGIC) || (num - HVC_IUCV_MAGIC > hvc_iucv_devices))
132 return NULL; 133 return NULL;
@@ -772,18 +773,37 @@ static int hvc_iucv_filter_connreq(u8 ipvmid[8])
772static int hvc_iucv_path_pending(struct iucv_path *path, 773static int hvc_iucv_path_pending(struct iucv_path *path,
773 u8 ipvmid[8], u8 ipuser[16]) 774 u8 ipvmid[8], u8 ipuser[16])
774{ 775{
775 struct hvc_iucv_private *priv; 776 struct hvc_iucv_private *priv, *tmp;
777 u8 wildcard[9] = "lnxhvc ";
778 int i, rc, find_unused;
776 u8 nuser_data[16]; 779 u8 nuser_data[16];
777 u8 vm_user_id[9]; 780 u8 vm_user_id[9];
778 int i, rc;
779 781
782 ASCEBC(wildcard, sizeof(wildcard));
783 find_unused = !memcmp(wildcard, ipuser, 8);
784
785 /* First, check if the pending path request is managed by this
786 * IUCV handler:
787 * - find a disconnected device if ipuser contains the wildcard
788 * - find the device that matches the terminal ID in ipuser
789 */
780 priv = NULL; 790 priv = NULL;
781 for (i = 0; i < hvc_iucv_devices; i++) 791 for (i = 0; i < hvc_iucv_devices; i++) {
782 if (hvc_iucv_table[i] && 792 tmp = hvc_iucv_table[i];
783 (0 == memcmp(hvc_iucv_table[i]->srv_name, ipuser, 8))) { 793 if (!tmp)
784 priv = hvc_iucv_table[i]; 794 continue;
795
796 if (find_unused) {
797 spin_lock(&tmp->lock);
798 if (tmp->iucv_state == IUCV_DISCONN)
799 priv = tmp;
800 spin_unlock(&tmp->lock);
801
802 } else if (!memcmp(tmp->srv_name, ipuser, 8))
803 priv = tmp;
804 if (priv)
785 break; 805 break;
786 } 806 }
787 if (!priv) 807 if (!priv)
788 return -ENODEV; 808 return -ENODEV;
789 809
@@ -826,6 +846,10 @@ static int hvc_iucv_path_pending(struct iucv_path *path,
826 priv->path = path; 846 priv->path = path;
827 priv->iucv_state = IUCV_CONNECTED; 847 priv->iucv_state = IUCV_CONNECTED;
828 848
849 /* store path information */
850 memcpy(priv->info_path, ipvmid, 8);
851 memcpy(priv->info_path + 8, ipuser + 8, 8);
852
829 /* flush buffered output data... */ 853 /* flush buffered output data... */
830 schedule_delayed_work(&priv->sndbuf_work, 5); 854 schedule_delayed_work(&priv->sndbuf_work, 5);
831 855
@@ -960,6 +984,49 @@ static int hvc_iucv_pm_restore_thaw(struct device *dev)
960 return 0; 984 return 0;
961} 985}
962 986
987static ssize_t hvc_iucv_dev_termid_show(struct device *dev,
988 struct device_attribute *attr,
989 char *buf)
990{
991 struct hvc_iucv_private *priv = dev_get_drvdata(dev);
992 size_t len;
993
994 len = sizeof(priv->srv_name);
995 memcpy(buf, priv->srv_name, len);
996 EBCASC(buf, len);
997 buf[len++] = '\n';
998 return len;
999}
1000
1001static ssize_t hvc_iucv_dev_state_show(struct device *dev,
1002 struct device_attribute *attr,
1003 char *buf)
1004{
1005 struct hvc_iucv_private *priv = dev_get_drvdata(dev);
1006 return sprintf(buf, "%u:%u\n", priv->iucv_state, priv->tty_state);
1007}
1008
1009static ssize_t hvc_iucv_dev_peer_show(struct device *dev,
1010 struct device_attribute *attr,
1011 char *buf)
1012{
1013 struct hvc_iucv_private *priv = dev_get_drvdata(dev);
1014 char vmid[9], ipuser[9];
1015
1016 memset(vmid, 0, sizeof(vmid));
1017 memset(ipuser, 0, sizeof(ipuser));
1018
1019 spin_lock_bh(&priv->lock);
1020 if (priv->iucv_state == IUCV_CONNECTED) {
1021 memcpy(vmid, priv->info_path, 8);
1022 memcpy(ipuser, priv->info_path + 8, 8);
1023 }
1024 spin_unlock_bh(&priv->lock);
1025 EBCASC(ipuser, 8);
1026
1027 return sprintf(buf, "%s:%s\n", vmid, ipuser);
1028}
1029
963 1030
964/* HVC operations */ 1031/* HVC operations */
965static const struct hv_ops hvc_iucv_ops = { 1032static const struct hv_ops hvc_iucv_ops = {
@@ -985,6 +1052,25 @@ static struct device_driver hvc_iucv_driver = {
985 .pm = &hvc_iucv_pm_ops, 1052 .pm = &hvc_iucv_pm_ops,
986}; 1053};
987 1054
1055/* IUCV HVC device attributes */
1056static DEVICE_ATTR(termid, 0640, hvc_iucv_dev_termid_show, NULL);
1057static DEVICE_ATTR(state, 0640, hvc_iucv_dev_state_show, NULL);
1058static DEVICE_ATTR(peer, 0640, hvc_iucv_dev_peer_show, NULL);
1059static struct attribute *hvc_iucv_dev_attrs[] = {
1060 &dev_attr_termid.attr,
1061 &dev_attr_state.attr,
1062 &dev_attr_peer.attr,
1063 NULL,
1064};
1065static struct attribute_group hvc_iucv_dev_attr_group = {
1066 .attrs = hvc_iucv_dev_attrs,
1067};
1068static const struct attribute_group *hvc_iucv_dev_attr_groups[] = {
1069 &hvc_iucv_dev_attr_group,
1070 NULL,
1071};
1072
1073
988/** 1074/**
989 * hvc_iucv_alloc() - Allocates a new struct hvc_iucv_private instance 1075 * hvc_iucv_alloc() - Allocates a new struct hvc_iucv_private instance
990 * @id: hvc_iucv_table index 1076 * @id: hvc_iucv_table index
@@ -1046,6 +1132,7 @@ static int __init hvc_iucv_alloc(int id, unsigned int is_console)
1046 priv->dev->bus = &iucv_bus; 1132 priv->dev->bus = &iucv_bus;
1047 priv->dev->parent = iucv_root; 1133 priv->dev->parent = iucv_root;
1048 priv->dev->driver = &hvc_iucv_driver; 1134 priv->dev->driver = &hvc_iucv_driver;
1135 priv->dev->groups = hvc_iucv_dev_attr_groups;
1049 priv->dev->release = (void (*)(struct device *)) kfree; 1136 priv->dev->release = (void (*)(struct device *)) kfree;
1050 rc = device_register(priv->dev); 1137 rc = device_register(priv->dev);
1051 if (rc) { 1138 if (rc) {