aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390
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 /arch/s390
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
Diffstat (limited to 'arch/s390')
-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
15 files changed, 238 insertions, 24 deletions
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);