diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-16 14:28:25 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-16 14:28:25 -0400 |
commit | 0f689a33ad17845363acdc6d52783befd6ad116c (patch) | |
tree | 88d1c183fc6f223de431ae8bdc86137481721f2c | |
parent | 7d38cc02909b85f6f4d3f082c471f0151fc5be3e (diff) | |
parent | 5896f8fe491891f551bdc6574bbc4a07c054c30b (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 patches from Martin Schwidefsky:
"An update to the oops output with additional information about the
crash. The renameat2 system call is enabled. Two patches in regard
to the PTR_ERR_OR_ZERO cleanup. And a bunch of bug fixes"
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux:
s390/sclp_cmd: replace PTR_RET with PTR_ERR_OR_ZERO
s390/sclp: replace PTR_RET with PTR_ERR_OR_ZERO
s390/sclp_vt220: Fix kernel panic due to early terminal input
s390/compat: fix typo
s390/uaccess: fix possible register corruption in strnlen_user_srst()
s390: add 31 bit warning message
s390: wire up sys_renameat2
s390: show_registers() should not map user space addresses to kernel symbols
s390/mm: print control registers and page table walk on crash
s390/smp: fix smp_stop_cpu() for !CONFIG_SMP
s390: fix control register update
-rw-r--r-- | arch/s390/include/asm/sigp.h | 19 | ||||
-rw-r--r-- | arch/s390/include/asm/smp.h | 13 | ||||
-rw-r--r-- | arch/s390/include/uapi/asm/unistd.h | 3 | ||||
-rw-r--r-- | arch/s390/kernel/compat_wrapper.c | 3 | ||||
-rw-r--r-- | arch/s390/kernel/dumpstack.c | 8 | ||||
-rw-r--r-- | arch/s390/kernel/ptrace.c | 2 | ||||
-rw-r--r-- | arch/s390/kernel/setup.c | 32 | ||||
-rw-r--r-- | arch/s390/kernel/smp.c | 15 | ||||
-rw-r--r-- | arch/s390/kernel/syscalls.S | 1 | ||||
-rw-r--r-- | arch/s390/lib/uaccess.c | 5 | ||||
-rw-r--r-- | arch/s390/mm/fault.c | 140 | ||||
-rw-r--r-- | drivers/s390/char/sclp.c | 2 | ||||
-rw-r--r-- | drivers/s390/char/sclp_cmd.c | 2 | ||||
-rw-r--r-- | drivers/s390/char/sclp_vt220.c | 14 |
14 files changed, 223 insertions, 36 deletions
diff --git a/arch/s390/include/asm/sigp.h b/arch/s390/include/asm/sigp.h index d091aa1aaf11..bf9c823d4020 100644 --- a/arch/s390/include/asm/sigp.h +++ b/arch/s390/include/asm/sigp.h | |||
@@ -31,4 +31,23 @@ | |||
31 | #define SIGP_STATUS_INCORRECT_STATE 0x00000200UL | 31 | #define SIGP_STATUS_INCORRECT_STATE 0x00000200UL |
32 | #define SIGP_STATUS_NOT_RUNNING 0x00000400UL | 32 | #define SIGP_STATUS_NOT_RUNNING 0x00000400UL |
33 | 33 | ||
34 | #ifndef __ASSEMBLY__ | ||
35 | |||
36 | static inline int __pcpu_sigp(u16 addr, u8 order, u32 parm, u32 *status) | ||
37 | { | ||
38 | register unsigned int reg1 asm ("1") = parm; | ||
39 | int cc; | ||
40 | |||
41 | asm volatile( | ||
42 | " sigp %1,%2,0(%3)\n" | ||
43 | " ipm %0\n" | ||
44 | " srl %0,28\n" | ||
45 | : "=d" (cc), "+d" (reg1) : "d" (addr), "a" (order) : "cc"); | ||
46 | if (status && cc == 1) | ||
47 | *status = reg1; | ||
48 | return cc; | ||
49 | } | ||
50 | |||
51 | #endif /* __ASSEMBLY__ */ | ||
52 | |||
34 | #endif /* __S390_ASM_SIGP_H */ | 53 | #endif /* __S390_ASM_SIGP_H */ |
diff --git a/arch/s390/include/asm/smp.h b/arch/s390/include/asm/smp.h index 160779394096..21703f85b48d 100644 --- a/arch/s390/include/asm/smp.h +++ b/arch/s390/include/asm/smp.h | |||
@@ -7,6 +7,8 @@ | |||
7 | #ifndef __ASM_SMP_H | 7 | #ifndef __ASM_SMP_H |
8 | #define __ASM_SMP_H | 8 | #define __ASM_SMP_H |
9 | 9 | ||
10 | #include <asm/sigp.h> | ||
11 | |||
10 | #ifdef CONFIG_SMP | 12 | #ifdef CONFIG_SMP |
11 | 13 | ||
12 | #include <asm/lowcore.h> | 14 | #include <asm/lowcore.h> |
@@ -50,9 +52,18 @@ static inline int smp_store_status(int cpu) { return 0; } | |||
50 | static inline int smp_vcpu_scheduled(int cpu) { return 1; } | 52 | static inline int smp_vcpu_scheduled(int cpu) { return 1; } |
51 | static inline void smp_yield_cpu(int cpu) { } | 53 | static inline void smp_yield_cpu(int cpu) { } |
52 | static inline void smp_yield(void) { } | 54 | static inline void smp_yield(void) { } |
53 | static inline void smp_stop_cpu(void) { } | ||
54 | static inline void smp_fill_possible_mask(void) { } | 55 | static inline void smp_fill_possible_mask(void) { } |
55 | 56 | ||
57 | static inline void smp_stop_cpu(void) | ||
58 | { | ||
59 | u16 pcpu = stap(); | ||
60 | |||
61 | for (;;) { | ||
62 | __pcpu_sigp(pcpu, SIGP_STOP, 0, NULL); | ||
63 | cpu_relax(); | ||
64 | } | ||
65 | } | ||
66 | |||
56 | #endif /* CONFIG_SMP */ | 67 | #endif /* CONFIG_SMP */ |
57 | 68 | ||
58 | #ifdef CONFIG_HOTPLUG_CPU | 69 | #ifdef CONFIG_HOTPLUG_CPU |
diff --git a/arch/s390/include/uapi/asm/unistd.h b/arch/s390/include/uapi/asm/unistd.h index 5eb5c9ddb120..3802d2d3a18d 100644 --- a/arch/s390/include/uapi/asm/unistd.h +++ b/arch/s390/include/uapi/asm/unistd.h | |||
@@ -282,7 +282,8 @@ | |||
282 | #define __NR_finit_module 344 | 282 | #define __NR_finit_module 344 |
283 | #define __NR_sched_setattr 345 | 283 | #define __NR_sched_setattr 345 |
284 | #define __NR_sched_getattr 346 | 284 | #define __NR_sched_getattr 346 |
285 | #define NR_syscalls 345 | 285 | #define __NR_renameat2 347 |
286 | #define NR_syscalls 348 | ||
286 | 287 | ||
287 | /* | 288 | /* |
288 | * There are some system calls that are not present on 64 bit, some | 289 | * There are some system calls that are not present on 64 bit, some |
diff --git a/arch/s390/kernel/compat_wrapper.c b/arch/s390/kernel/compat_wrapper.c index 824c39dfddfc..45cdb37aa6f8 100644 --- a/arch/s390/kernel/compat_wrapper.c +++ b/arch/s390/kernel/compat_wrapper.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Compat sytem call wrappers. | 2 | * Compat system call wrappers. |
3 | * | 3 | * |
4 | * Copyright IBM Corp. 2014 | 4 | * Copyright IBM Corp. 2014 |
5 | */ | 5 | */ |
@@ -213,3 +213,4 @@ COMPAT_SYSCALL_WRAP5(kcmp, pid_t, pid1, pid_t, pid2, int, type, unsigned long, i | |||
213 | COMPAT_SYSCALL_WRAP3(finit_module, int, fd, const char __user *, uargs, int, flags); | 213 | COMPAT_SYSCALL_WRAP3(finit_module, int, fd, const char __user *, uargs, int, flags); |
214 | COMPAT_SYSCALL_WRAP3(sched_setattr, pid_t, pid, struct sched_attr __user *, attr, unsigned int, flags); | 214 | COMPAT_SYSCALL_WRAP3(sched_setattr, pid_t, pid, struct sched_attr __user *, attr, unsigned int, flags); |
215 | COMPAT_SYSCALL_WRAP4(sched_getattr, pid_t, pid, struct sched_attr __user *, attr, unsigned int, size, unsigned int, flags); | 215 | COMPAT_SYSCALL_WRAP4(sched_getattr, pid_t, pid, struct sched_attr __user *, attr, unsigned int, size, unsigned int, flags); |
216 | COMPAT_SYSCALL_WRAP5(renameat2, int, olddfd, const char __user *, oldname, int, newdfd, const char __user *, newname, unsigned int, flags); | ||
diff --git a/arch/s390/kernel/dumpstack.c b/arch/s390/kernel/dumpstack.c index e6af9406987c..acb412442e5e 100644 --- a/arch/s390/kernel/dumpstack.c +++ b/arch/s390/kernel/dumpstack.c | |||
@@ -144,10 +144,10 @@ void show_registers(struct pt_regs *regs) | |||
144 | char *mode; | 144 | char *mode; |
145 | 145 | ||
146 | mode = user_mode(regs) ? "User" : "Krnl"; | 146 | mode = user_mode(regs) ? "User" : "Krnl"; |
147 | printk("%s PSW : %p %p (%pSR)\n", | 147 | printk("%s PSW : %p %p", mode, (void *)regs->psw.mask, (void *)regs->psw.addr); |
148 | mode, (void *) regs->psw.mask, | 148 | if (!user_mode(regs)) |
149 | (void *) regs->psw.addr, | 149 | printk(" (%pSR)", (void *)regs->psw.addr); |
150 | (void *) regs->psw.addr); | 150 | printk("\n"); |
151 | printk(" R:%x T:%x IO:%x EX:%x Key:%x M:%x W:%x " | 151 | printk(" R:%x T:%x IO:%x EX:%x Key:%x M:%x W:%x " |
152 | "P:%x AS:%x CC:%x PM:%x", mask_bits(regs, PSW_MASK_PER), | 152 | "P:%x AS:%x CC:%x PM:%x", mask_bits(regs, PSW_MASK_PER), |
153 | mask_bits(regs, PSW_MASK_DAT), mask_bits(regs, PSW_MASK_IO), | 153 | mask_bits(regs, PSW_MASK_DAT), mask_bits(regs, PSW_MASK_IO), |
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index 4ac8fafec95f..1c82619eb4f7 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c | |||
@@ -64,7 +64,7 @@ void update_cr_regs(struct task_struct *task) | |||
64 | if (task->thread.per_flags & PER_FLAG_NO_TE) | 64 | if (task->thread.per_flags & PER_FLAG_NO_TE) |
65 | cr_new &= ~(1UL << 55); | 65 | cr_new &= ~(1UL << 55); |
66 | if (cr_new != cr) | 66 | if (cr_new != cr) |
67 | __ctl_load(cr, 0, 0); | 67 | __ctl_load(cr_new, 0, 0); |
68 | /* Set or clear transaction execution TDC bits 62 and 63. */ | 68 | /* Set or clear transaction execution TDC bits 62 and 63. */ |
69 | __ctl_store(cr, 2, 2); | 69 | __ctl_store(cr, 2, 2); |
70 | cr_new = cr & ~3UL; | 70 | cr_new = cr & ~3UL; |
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index f70f2489fa5f..88d1ca81e2dd 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c | |||
@@ -1027,3 +1027,35 @@ void __init setup_arch(char **cmdline_p) | |||
1027 | /* Setup zfcpdump support */ | 1027 | /* Setup zfcpdump support */ |
1028 | setup_zfcpdump(); | 1028 | setup_zfcpdump(); |
1029 | } | 1029 | } |
1030 | |||
1031 | #ifdef CONFIG_32BIT | ||
1032 | static int no_removal_warning __initdata; | ||
1033 | |||
1034 | static int __init parse_no_removal_warning(char *str) | ||
1035 | { | ||
1036 | no_removal_warning = 1; | ||
1037 | return 0; | ||
1038 | } | ||
1039 | __setup("no_removal_warning", parse_no_removal_warning); | ||
1040 | |||
1041 | static int __init removal_warning(void) | ||
1042 | { | ||
1043 | if (no_removal_warning) | ||
1044 | return 0; | ||
1045 | printk(KERN_ALERT "\n\n"); | ||
1046 | printk(KERN_CONT "Warning - you are using a 31 bit kernel!\n\n"); | ||
1047 | printk(KERN_CONT "We plan to remove 31 bit kernel support from the kernel sources in March 2015.\n"); | ||
1048 | printk(KERN_CONT "Currently we assume that nobody is using the 31 bit kernel on old 31 bit\n"); | ||
1049 | printk(KERN_CONT "hardware anymore. If you think that the code should not be removed and also\n"); | ||
1050 | printk(KERN_CONT "future versions of the Linux kernel should be able to run in 31 bit mode\n"); | ||
1051 | printk(KERN_CONT "please let us know. Please write to:\n"); | ||
1052 | printk(KERN_CONT "linux390@de.ibm.com (mail address) and/or\n"); | ||
1053 | printk(KERN_CONT "linux-s390@vger.kernel.org (mailing list).\n\n"); | ||
1054 | printk(KERN_CONT "Thank you!\n\n"); | ||
1055 | printk(KERN_CONT "If this kernel runs on a 64 bit machine you may consider using a 64 bit kernel.\n"); | ||
1056 | printk(KERN_CONT "This message can be disabled with the \"no_removal_warning\" kernel parameter.\n"); | ||
1057 | schedule_timeout_uninterruptible(300 * HZ); | ||
1058 | return 0; | ||
1059 | } | ||
1060 | early_initcall(removal_warning); | ||
1061 | #endif | ||
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 512ce1cde2a4..86e65ec3422b 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c | |||
@@ -82,21 +82,6 @@ DEFINE_MUTEX(smp_cpu_state_mutex); | |||
82 | /* | 82 | /* |
83 | * Signal processor helper functions. | 83 | * Signal processor helper functions. |
84 | */ | 84 | */ |
85 | static inline int __pcpu_sigp(u16 addr, u8 order, u32 parm, u32 *status) | ||
86 | { | ||
87 | register unsigned int reg1 asm ("1") = parm; | ||
88 | int cc; | ||
89 | |||
90 | asm volatile( | ||
91 | " sigp %1,%2,0(%3)\n" | ||
92 | " ipm %0\n" | ||
93 | " srl %0,28\n" | ||
94 | : "=d" (cc), "+d" (reg1) : "d" (addr), "a" (order) : "cc"); | ||
95 | if (status && cc == 1) | ||
96 | *status = reg1; | ||
97 | return cc; | ||
98 | } | ||
99 | |||
100 | static inline int __pcpu_sigp_relax(u16 addr, u8 order, u32 parm, u32 *status) | 85 | static inline int __pcpu_sigp_relax(u16 addr, u8 order, u32 parm, u32 *status) |
101 | { | 86 | { |
102 | int cc; | 87 | int cc; |
diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S index 542ef488bac1..fe5cdf29a001 100644 --- a/arch/s390/kernel/syscalls.S +++ b/arch/s390/kernel/syscalls.S | |||
@@ -355,3 +355,4 @@ SYSCALL(sys_kcmp,sys_kcmp,compat_sys_kcmp) | |||
355 | SYSCALL(sys_finit_module,sys_finit_module,compat_sys_finit_module) | 355 | SYSCALL(sys_finit_module,sys_finit_module,compat_sys_finit_module) |
356 | SYSCALL(sys_sched_setattr,sys_sched_setattr,compat_sys_sched_setattr) /* 345 */ | 356 | SYSCALL(sys_sched_setattr,sys_sched_setattr,compat_sys_sched_setattr) /* 345 */ |
357 | SYSCALL(sys_sched_getattr,sys_sched_getattr,compat_sys_sched_getattr) | 357 | SYSCALL(sys_sched_getattr,sys_sched_getattr,compat_sys_sched_getattr) |
358 | SYSCALL(sys_renameat2,sys_renameat2,compat_sys_renameat2) | ||
diff --git a/arch/s390/lib/uaccess.c b/arch/s390/lib/uaccess.c index 23f866b4c7f1..7416efe8eae4 100644 --- a/arch/s390/lib/uaccess.c +++ b/arch/s390/lib/uaccess.c | |||
@@ -338,9 +338,6 @@ static inline unsigned long strnlen_user_srst(const char __user *src, | |||
338 | register unsigned long reg0 asm("0") = 0; | 338 | register unsigned long reg0 asm("0") = 0; |
339 | unsigned long tmp1, tmp2; | 339 | unsigned long tmp1, tmp2; |
340 | 340 | ||
341 | if (unlikely(!size)) | ||
342 | return 0; | ||
343 | update_primary_asce(current); | ||
344 | asm volatile( | 341 | asm volatile( |
345 | " la %2,0(%1)\n" | 342 | " la %2,0(%1)\n" |
346 | " la %3,0(%0,%1)\n" | 343 | " la %3,0(%0,%1)\n" |
@@ -359,6 +356,8 @@ static inline unsigned long strnlen_user_srst(const char __user *src, | |||
359 | 356 | ||
360 | unsigned long __strnlen_user(const char __user *src, unsigned long size) | 357 | unsigned long __strnlen_user(const char __user *src, unsigned long size) |
361 | { | 358 | { |
359 | if (unlikely(!size)) | ||
360 | return 0; | ||
362 | update_primary_asce(current); | 361 | update_primary_asce(current); |
363 | return strnlen_user_srst(src, size); | 362 | return strnlen_user_srst(src, size); |
364 | } | 363 | } |
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index 19f623f1f21c..2f51a998a67e 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c | |||
@@ -126,6 +126,133 @@ static inline int user_space_fault(struct pt_regs *regs) | |||
126 | return 0; | 126 | return 0; |
127 | } | 127 | } |
128 | 128 | ||
129 | static int bad_address(void *p) | ||
130 | { | ||
131 | unsigned long dummy; | ||
132 | |||
133 | return probe_kernel_address((unsigned long *)p, dummy); | ||
134 | } | ||
135 | |||
136 | #ifdef CONFIG_64BIT | ||
137 | static void dump_pagetable(unsigned long asce, unsigned long address) | ||
138 | { | ||
139 | unsigned long *table = __va(asce & PAGE_MASK); | ||
140 | |||
141 | pr_alert("AS:%016lx ", asce); | ||
142 | switch (asce & _ASCE_TYPE_MASK) { | ||
143 | case _ASCE_TYPE_REGION1: | ||
144 | table = table + ((address >> 53) & 0x7ff); | ||
145 | if (bad_address(table)) | ||
146 | goto bad; | ||
147 | pr_cont("R1:%016lx ", *table); | ||
148 | if (*table & _REGION_ENTRY_INVALID) | ||
149 | goto out; | ||
150 | table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); | ||
151 | /* fallthrough */ | ||
152 | case _ASCE_TYPE_REGION2: | ||
153 | table = table + ((address >> 42) & 0x7ff); | ||
154 | if (bad_address(table)) | ||
155 | goto bad; | ||
156 | pr_cont("R2:%016lx ", *table); | ||
157 | if (*table & _REGION_ENTRY_INVALID) | ||
158 | goto out; | ||
159 | table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); | ||
160 | /* fallthrough */ | ||
161 | case _ASCE_TYPE_REGION3: | ||
162 | table = table + ((address >> 31) & 0x7ff); | ||
163 | if (bad_address(table)) | ||
164 | goto bad; | ||
165 | pr_cont("R3:%016lx ", *table); | ||
166 | if (*table & (_REGION_ENTRY_INVALID | _REGION3_ENTRY_LARGE)) | ||
167 | goto out; | ||
168 | table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); | ||
169 | /* fallthrough */ | ||
170 | case _ASCE_TYPE_SEGMENT: | ||
171 | table = table + ((address >> 20) & 0x7ff); | ||
172 | if (bad_address(table)) | ||
173 | goto bad; | ||
174 | pr_cont(KERN_CONT "S:%016lx ", *table); | ||
175 | if (*table & (_SEGMENT_ENTRY_INVALID | _SEGMENT_ENTRY_LARGE)) | ||
176 | goto out; | ||
177 | table = (unsigned long *)(*table & _SEGMENT_ENTRY_ORIGIN); | ||
178 | } | ||
179 | table = table + ((address >> 12) & 0xff); | ||
180 | if (bad_address(table)) | ||
181 | goto bad; | ||
182 | pr_cont("P:%016lx ", *table); | ||
183 | out: | ||
184 | pr_cont("\n"); | ||
185 | return; | ||
186 | bad: | ||
187 | pr_cont("BAD\n"); | ||
188 | } | ||
189 | |||
190 | #else /* CONFIG_64BIT */ | ||
191 | |||
192 | static void dump_pagetable(unsigned long asce, unsigned long address) | ||
193 | { | ||
194 | unsigned long *table = __va(asce & PAGE_MASK); | ||
195 | |||
196 | pr_alert("AS:%08lx ", asce); | ||
197 | table = table + ((address >> 20) & 0x7ff); | ||
198 | if (bad_address(table)) | ||
199 | goto bad; | ||
200 | pr_cont("S:%08lx ", *table); | ||
201 | if (*table & _SEGMENT_ENTRY_INVALID) | ||
202 | goto out; | ||
203 | table = (unsigned long *)(*table & _SEGMENT_ENTRY_ORIGIN); | ||
204 | table = table + ((address >> 12) & 0xff); | ||
205 | if (bad_address(table)) | ||
206 | goto bad; | ||
207 | pr_cont("P:%08lx ", *table); | ||
208 | out: | ||
209 | pr_cont("\n"); | ||
210 | return; | ||
211 | bad: | ||
212 | pr_cont("BAD\n"); | ||
213 | } | ||
214 | |||
215 | #endif /* CONFIG_64BIT */ | ||
216 | |||
217 | static void dump_fault_info(struct pt_regs *regs) | ||
218 | { | ||
219 | unsigned long asce; | ||
220 | |||
221 | pr_alert("Fault in "); | ||
222 | switch (regs->int_parm_long & 3) { | ||
223 | case 3: | ||
224 | pr_cont("home space "); | ||
225 | break; | ||
226 | case 2: | ||
227 | pr_cont("secondary space "); | ||
228 | break; | ||
229 | case 1: | ||
230 | pr_cont("access register "); | ||
231 | break; | ||
232 | case 0: | ||
233 | pr_cont("primary space "); | ||
234 | break; | ||
235 | } | ||
236 | pr_cont("mode while using "); | ||
237 | if (!user_space_fault(regs)) { | ||
238 | asce = S390_lowcore.kernel_asce; | ||
239 | pr_cont("kernel "); | ||
240 | } | ||
241 | #ifdef CONFIG_PGSTE | ||
242 | else if ((current->flags & PF_VCPU) && S390_lowcore.gmap) { | ||
243 | struct gmap *gmap = (struct gmap *)S390_lowcore.gmap; | ||
244 | asce = gmap->asce; | ||
245 | pr_cont("gmap "); | ||
246 | } | ||
247 | #endif | ||
248 | else { | ||
249 | asce = S390_lowcore.user_asce; | ||
250 | pr_cont("user "); | ||
251 | } | ||
252 | pr_cont("ASCE.\n"); | ||
253 | dump_pagetable(asce, regs->int_parm_long & __FAIL_ADDR_MASK); | ||
254 | } | ||
255 | |||
129 | static inline void report_user_fault(struct pt_regs *regs, long signr) | 256 | static inline void report_user_fault(struct pt_regs *regs, long signr) |
130 | { | 257 | { |
131 | if ((task_pid_nr(current) > 1) && !show_unhandled_signals) | 258 | if ((task_pid_nr(current) > 1) && !show_unhandled_signals) |
@@ -138,8 +265,9 @@ static inline void report_user_fault(struct pt_regs *regs, long signr) | |||
138 | regs->int_code); | 265 | regs->int_code); |
139 | print_vma_addr(KERN_CONT "in ", regs->psw.addr & PSW_ADDR_INSN); | 266 | print_vma_addr(KERN_CONT "in ", regs->psw.addr & PSW_ADDR_INSN); |
140 | printk(KERN_CONT "\n"); | 267 | printk(KERN_CONT "\n"); |
141 | printk(KERN_ALERT "failing address: %lX\n", | 268 | printk(KERN_ALERT "failing address: %016lx TEID: %016lx\n", |
142 | regs->int_parm_long & __FAIL_ADDR_MASK); | 269 | regs->int_parm_long & __FAIL_ADDR_MASK, regs->int_parm_long); |
270 | dump_fault_info(regs); | ||
143 | show_regs(regs); | 271 | show_regs(regs); |
144 | } | 272 | } |
145 | 273 | ||
@@ -177,11 +305,13 @@ static noinline void do_no_context(struct pt_regs *regs) | |||
177 | address = regs->int_parm_long & __FAIL_ADDR_MASK; | 305 | address = regs->int_parm_long & __FAIL_ADDR_MASK; |
178 | if (!user_space_fault(regs)) | 306 | if (!user_space_fault(regs)) |
179 | printk(KERN_ALERT "Unable to handle kernel pointer dereference" | 307 | printk(KERN_ALERT "Unable to handle kernel pointer dereference" |
180 | " at virtual kernel address %p\n", (void *)address); | 308 | " in virtual kernel address space\n"); |
181 | else | 309 | else |
182 | printk(KERN_ALERT "Unable to handle kernel paging request" | 310 | printk(KERN_ALERT "Unable to handle kernel paging request" |
183 | " at virtual user address %p\n", (void *)address); | 311 | " in virtual user address space\n"); |
184 | 312 | printk(KERN_ALERT "failing address: %016lx TEID: %016lx\n", | |
313 | regs->int_parm_long & __FAIL_ADDR_MASK, regs->int_parm_long); | ||
314 | dump_fault_info(regs); | ||
185 | die(regs, "Oops"); | 315 | die(regs, "Oops"); |
186 | do_exit(SIGKILL); | 316 | do_exit(SIGKILL); |
187 | } | 317 | } |
diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c index 1990285296c6..c316051d9bda 100644 --- a/drivers/s390/char/sclp.c +++ b/drivers/s390/char/sclp.c | |||
@@ -1252,7 +1252,7 @@ static __init int sclp_initcall(void) | |||
1252 | return rc; | 1252 | return rc; |
1253 | 1253 | ||
1254 | sclp_pdev = platform_device_register_simple("sclp", -1, NULL, 0); | 1254 | sclp_pdev = platform_device_register_simple("sclp", -1, NULL, 0); |
1255 | rc = PTR_RET(sclp_pdev); | 1255 | rc = PTR_ERR_OR_ZERO(sclp_pdev); |
1256 | if (rc) | 1256 | if (rc) |
1257 | goto fail_platform_driver_unregister; | 1257 | goto fail_platform_driver_unregister; |
1258 | 1258 | ||
diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c index 6e8f90f84e49..6e14999f9e8f 100644 --- a/drivers/s390/char/sclp_cmd.c +++ b/drivers/s390/char/sclp_cmd.c | |||
@@ -515,7 +515,7 @@ static int __init sclp_detect_standby_memory(void) | |||
515 | if (rc) | 515 | if (rc) |
516 | goto out; | 516 | goto out; |
517 | sclp_pdev = platform_device_register_simple("sclp_mem", -1, NULL, 0); | 517 | sclp_pdev = platform_device_register_simple("sclp_mem", -1, NULL, 0); |
518 | rc = PTR_RET(sclp_pdev); | 518 | rc = PTR_ERR_OR_ZERO(sclp_pdev); |
519 | if (rc) | 519 | if (rc) |
520 | goto out_driver; | 520 | goto out_driver; |
521 | sclp_add_standby_memory(); | 521 | sclp_add_standby_memory(); |
diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c index 4eed38cd0af6..cd9c91909596 100644 --- a/drivers/s390/char/sclp_vt220.c +++ b/drivers/s390/char/sclp_vt220.c | |||
@@ -97,13 +97,16 @@ static void sclp_vt220_pm_event_fn(struct sclp_register *reg, | |||
97 | static int __sclp_vt220_emit(struct sclp_vt220_request *request); | 97 | static int __sclp_vt220_emit(struct sclp_vt220_request *request); |
98 | static void sclp_vt220_emit_current(void); | 98 | static void sclp_vt220_emit_current(void); |
99 | 99 | ||
100 | /* Registration structure for our interest in SCLP event buffers */ | 100 | /* Registration structure for SCLP output event buffers */ |
101 | static struct sclp_register sclp_vt220_register = { | 101 | static struct sclp_register sclp_vt220_register = { |
102 | .send_mask = EVTYP_VT220MSG_MASK, | 102 | .send_mask = EVTYP_VT220MSG_MASK, |
103 | .pm_event_fn = sclp_vt220_pm_event_fn, | ||
104 | }; | ||
105 | |||
106 | /* Registration structure for SCLP input event buffers */ | ||
107 | static struct sclp_register sclp_vt220_register_input = { | ||
103 | .receive_mask = EVTYP_VT220MSG_MASK, | 108 | .receive_mask = EVTYP_VT220MSG_MASK, |
104 | .state_change_fn = NULL, | ||
105 | .receiver_fn = sclp_vt220_receiver_fn, | 109 | .receiver_fn = sclp_vt220_receiver_fn, |
106 | .pm_event_fn = sclp_vt220_pm_event_fn, | ||
107 | }; | 110 | }; |
108 | 111 | ||
109 | 112 | ||
@@ -715,9 +718,14 @@ static int __init sclp_vt220_tty_init(void) | |||
715 | rc = tty_register_driver(driver); | 718 | rc = tty_register_driver(driver); |
716 | if (rc) | 719 | if (rc) |
717 | goto out_init; | 720 | goto out_init; |
721 | rc = sclp_register(&sclp_vt220_register_input); | ||
722 | if (rc) | ||
723 | goto out_reg; | ||
718 | sclp_vt220_driver = driver; | 724 | sclp_vt220_driver = driver; |
719 | return 0; | 725 | return 0; |
720 | 726 | ||
727 | out_reg: | ||
728 | tty_unregister_driver(driver); | ||
721 | out_init: | 729 | out_init: |
722 | __sclp_vt220_cleanup(); | 730 | __sclp_vt220_cleanup(); |
723 | out_driver: | 731 | out_driver: |