aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel/traps.c
diff options
context:
space:
mode:
authorHeiko Carstens <heiko.carstens@de.ibm.com>2015-02-12 07:08:27 -0500
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2015-03-25 06:49:33 -0400
commit5a79859ae0f35d25c67a03e82bf0c80592f16a39 (patch)
tree37264d49f069812f19ced94e6ae171814fb7e498 /arch/s390/kernel/traps.c
parent1833c9f647e9bda1cd24653ff8f9c207b5f5b911 (diff)
s390: remove 31 bit support
Remove the 31 bit support in order to reduce maintenance cost and effectively remove dead code. Since a couple of years there is no distribution left that comes with a 31 bit kernel. The 31 bit kernel also has been broken since more than a year before anybody noticed. In addition I added a removal warning to the kernel shown at ipl for 5 minutes: a960062e5826 ("s390: add 31 bit warning message") which let everybody know about the plan to remove 31 bit code. We didn't get any response. Given that the last 31 bit only machine was introduced in 1999 let's remove the code. Anybody with 31 bit user space code can still use the compat mode. Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/kernel/traps.c')
-rw-r--r--arch/s390/kernel/traps.c153
1 files changed, 2 insertions, 151 deletions
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
index f081cf1157c3..8be11c22ed17 100644
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -26,7 +26,6 @@ int show_unhandled_signals = 1;
26 26
27static inline void __user *get_trap_ip(struct pt_regs *regs) 27static inline void __user *get_trap_ip(struct pt_regs *regs)
28{ 28{
29#ifdef CONFIG_64BIT
30 unsigned long address; 29 unsigned long address;
31 30
32 if (regs->int_code & 0x200) 31 if (regs->int_code & 0x200)
@@ -35,10 +34,6 @@ static inline void __user *get_trap_ip(struct pt_regs *regs)
35 address = regs->psw.addr; 34 address = regs->psw.addr;
36 return (void __user *) 35 return (void __user *)
37 ((address - (regs->int_code >> 16)) & PSW_ADDR_INSN); 36 ((address - (regs->int_code >> 16)) & PSW_ADDR_INSN);
38#else
39 return (void __user *)
40 ((regs->psw.addr - (regs->int_code >> 16)) & PSW_ADDR_INSN);
41#endif
42} 37}
43 38
44static inline void report_user_fault(struct pt_regs *regs, int signr) 39static inline void report_user_fault(struct pt_regs *regs, int signr)
@@ -153,11 +148,8 @@ DO_ERROR_INFO(privileged_op, SIGILL, ILL_PRVOPC,
153 "privileged operation") 148 "privileged operation")
154DO_ERROR_INFO(special_op_exception, SIGILL, ILL_ILLOPN, 149DO_ERROR_INFO(special_op_exception, SIGILL, ILL_ILLOPN,
155 "special operation exception") 150 "special operation exception")
156
157#ifdef CONFIG_64BIT
158DO_ERROR_INFO(transaction_exception, SIGILL, ILL_ILLOPN, 151DO_ERROR_INFO(transaction_exception, SIGILL, ILL_ILLOPN,
159 "transaction constraint exception") 152 "transaction constraint exception")
160#endif
161 153
162static inline void do_fp_trap(struct pt_regs *regs, int fpc) 154static inline void do_fp_trap(struct pt_regs *regs, int fpc)
163{ 155{
@@ -211,29 +203,6 @@ void illegal_op(struct pt_regs *regs)
211 } else if (*((__u16 *) opcode) == UPROBE_SWBP_INSN) { 203 } else if (*((__u16 *) opcode) == UPROBE_SWBP_INSN) {
212 is_uprobe_insn = 1; 204 is_uprobe_insn = 1;
213#endif 205#endif
214#ifdef CONFIG_MATHEMU
215 } else if (opcode[0] == 0xb3) {
216 if (get_user(*((__u16 *) (opcode+2)), location+1))
217 return;
218 signal = math_emu_b3(opcode, regs);
219 } else if (opcode[0] == 0xed) {
220 if (get_user(*((__u32 *) (opcode+2)),
221 (__u32 __user *)(location+1)))
222 return;
223 signal = math_emu_ed(opcode, regs);
224 } else if (*((__u16 *) opcode) == 0xb299) {
225 if (get_user(*((__u16 *) (opcode+2)), location+1))
226 return;
227 signal = math_emu_srnm(opcode, regs);
228 } else if (*((__u16 *) opcode) == 0xb29c) {
229 if (get_user(*((__u16 *) (opcode+2)), location+1))
230 return;
231 signal = math_emu_stfpc(opcode, regs);
232 } else if (*((__u16 *) opcode) == 0xb29d) {
233 if (get_user(*((__u16 *) (opcode+2)), location+1))
234 return;
235 signal = math_emu_lfpc(opcode, regs);
236#endif
237 } else 206 } else
238 signal = SIGILL; 207 signal = SIGILL;
239 } 208 }
@@ -247,71 +216,14 @@ void illegal_op(struct pt_regs *regs)
247 3, SIGTRAP) != NOTIFY_STOP) 216 3, SIGTRAP) != NOTIFY_STOP)
248 signal = SIGILL; 217 signal = SIGILL;
249 } 218 }
250
251#ifdef CONFIG_MATHEMU
252 if (signal == SIGFPE)
253 do_fp_trap(regs, current->thread.fp_regs.fpc);
254 else if (signal == SIGSEGV)
255 do_trap(regs, signal, SEGV_MAPERR, "user address fault");
256 else
257#endif
258 if (signal) 219 if (signal)
259 do_trap(regs, signal, ILL_ILLOPC, "illegal operation"); 220 do_trap(regs, signal, ILL_ILLOPC, "illegal operation");
260} 221}
261NOKPROBE_SYMBOL(illegal_op); 222NOKPROBE_SYMBOL(illegal_op);
262 223
263#ifdef CONFIG_MATHEMU
264void specification_exception(struct pt_regs *regs)
265{
266 __u8 opcode[6];
267 __u16 __user *location = NULL;
268 int signal = 0;
269
270 location = (__u16 __user *) get_trap_ip(regs);
271
272 if (user_mode(regs)) {
273 get_user(*((__u16 *) opcode), location);
274 switch (opcode[0]) {
275 case 0x28: /* LDR Rx,Ry */
276 signal = math_emu_ldr(opcode);
277 break;
278 case 0x38: /* LER Rx,Ry */
279 signal = math_emu_ler(opcode);
280 break;
281 case 0x60: /* STD R,D(X,B) */
282 get_user(*((__u16 *) (opcode+2)), location+1);
283 signal = math_emu_std(opcode, regs);
284 break;
285 case 0x68: /* LD R,D(X,B) */
286 get_user(*((__u16 *) (opcode+2)), location+1);
287 signal = math_emu_ld(opcode, regs);
288 break;
289 case 0x70: /* STE R,D(X,B) */
290 get_user(*((__u16 *) (opcode+2)), location+1);
291 signal = math_emu_ste(opcode, regs);
292 break;
293 case 0x78: /* LE R,D(X,B) */
294 get_user(*((__u16 *) (opcode+2)), location+1);
295 signal = math_emu_le(opcode, regs);
296 break;
297 default:
298 signal = SIGILL;
299 break;
300 }
301 } else
302 signal = SIGILL;
303
304 if (signal == SIGFPE)
305 do_fp_trap(regs, current->thread.fp_regs.fpc);
306 else if (signal)
307 do_trap(regs, signal, ILL_ILLOPN, "specification exception");
308}
309#else
310DO_ERROR_INFO(specification_exception, SIGILL, ILL_ILLOPN, 224DO_ERROR_INFO(specification_exception, SIGILL, ILL_ILLOPN,
311 "specification exception"); 225 "specification exception");
312#endif
313 226
314#ifdef CONFIG_64BIT
315int alloc_vector_registers(struct task_struct *tsk) 227int alloc_vector_registers(struct task_struct *tsk)
316{ 228{
317 __vector128 *vxrs; 229 __vector128 *vxrs;
@@ -377,7 +289,6 @@ static int __init disable_vector_extension(char *str)
377 return 1; 289 return 1;
378} 290}
379__setup("novx", disable_vector_extension); 291__setup("novx", disable_vector_extension);
380#endif
381 292
382void data_exception(struct pt_regs *regs) 293void data_exception(struct pt_regs *regs)
383{ 294{
@@ -386,65 +297,7 @@ void data_exception(struct pt_regs *regs)
386 297
387 location = get_trap_ip(regs); 298 location = get_trap_ip(regs);
388 299
389 if (MACHINE_HAS_IEEE) 300 asm volatile("stfpc %0" : "=m" (current->thread.fp_regs.fpc));
390 asm volatile("stfpc %0" : "=m" (current->thread.fp_regs.fpc));
391
392#ifdef CONFIG_MATHEMU
393 else if (user_mode(regs)) {
394 __u8 opcode[6];
395 get_user(*((__u16 *) opcode), location);
396 switch (opcode[0]) {
397 case 0x28: /* LDR Rx,Ry */
398 signal = math_emu_ldr(opcode);
399 break;
400 case 0x38: /* LER Rx,Ry */
401 signal = math_emu_ler(opcode);
402 break;
403 case 0x60: /* STD R,D(X,B) */
404 get_user(*((__u16 *) (opcode+2)), location+1);
405 signal = math_emu_std(opcode, regs);
406 break;
407 case 0x68: /* LD R,D(X,B) */
408 get_user(*((__u16 *) (opcode+2)), location+1);
409 signal = math_emu_ld(opcode, regs);
410 break;
411 case 0x70: /* STE R,D(X,B) */
412 get_user(*((__u16 *) (opcode+2)), location+1);
413 signal = math_emu_ste(opcode, regs);
414 break;
415 case 0x78: /* LE R,D(X,B) */
416 get_user(*((__u16 *) (opcode+2)), location+1);
417 signal = math_emu_le(opcode, regs);
418 break;
419 case 0xb3:
420 get_user(*((__u16 *) (opcode+2)), location+1);
421 signal = math_emu_b3(opcode, regs);
422 break;
423 case 0xed:
424 get_user(*((__u32 *) (opcode+2)),
425 (__u32 __user *)(location+1));
426 signal = math_emu_ed(opcode, regs);
427 break;
428 case 0xb2:
429 if (opcode[1] == 0x99) {
430 get_user(*((__u16 *) (opcode+2)), location+1);
431 signal = math_emu_srnm(opcode, regs);
432 } else if (opcode[1] == 0x9c) {
433 get_user(*((__u16 *) (opcode+2)), location+1);
434 signal = math_emu_stfpc(opcode, regs);
435 } else if (opcode[1] == 0x9d) {
436 get_user(*((__u16 *) (opcode+2)), location+1);
437 signal = math_emu_lfpc(opcode, regs);
438 } else
439 signal = SIGILL;
440 break;
441 default:
442 signal = SIGILL;
443 break;
444 }
445 }
446#endif
447#ifdef CONFIG_64BIT
448 /* Check for vector register enablement */ 301 /* Check for vector register enablement */
449 if (MACHINE_HAS_VX && !current->thread.vxrs && 302 if (MACHINE_HAS_VX && !current->thread.vxrs &&
450 (current->thread.fp_regs.fpc & FPC_DXC_MASK) == 0xfe00) { 303 (current->thread.fp_regs.fpc & FPC_DXC_MASK) == 0xfe00) {
@@ -454,13 +307,11 @@ void data_exception(struct pt_regs *regs)
454 clear_pt_regs_flag(regs, PIF_PER_TRAP); 307 clear_pt_regs_flag(regs, PIF_PER_TRAP);
455 return; 308 return;
456 } 309 }
457#endif
458
459 if (current->thread.fp_regs.fpc & FPC_DXC_MASK) 310 if (current->thread.fp_regs.fpc & FPC_DXC_MASK)
460 signal = SIGFPE; 311 signal = SIGFPE;
461 else 312 else
462 signal = SIGILL; 313 signal = SIGILL;
463 if (signal == SIGFPE) 314 if (signal == SIGFPE)
464 do_fp_trap(regs, current->thread.fp_regs.fpc); 315 do_fp_trap(regs, current->thread.fp_regs.fpc);
465 else if (signal) 316 else if (signal)
466 do_trap(regs, signal, ILL_ILLOPN, "data exception"); 317 do_trap(regs, signal, ILL_ILLOPN, "data exception");