33 * S390 version
44 * Copyright IBM Corp. 1999, 2000
55 * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
6- * Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com),
6+ * Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com),
77 *
88 * Derived from "arch/i386/kernel/traps.c"
99 * Copyright (C) 1991, 1992 Linus Torvalds
1010 */
1111
12- /*
13- * 'Traps.c' handles hardware traps and faults after we have saved some
14- * state in 'asm.s'.
15- */
1612#include <linux/cpufeature.h>
1713#include <linux/kprobes.h>
1814#include <linux/kdebug.h>
@@ -43,7 +39,7 @@ static inline void __user *get_trap_ip(struct pt_regs *regs)
4339 address = current -> thread .trap_tdb .data [3 ];
4440 else
4541 address = regs -> psw .addr ;
46- return (void __user * ) (address - (regs -> int_code >> 16 ));
42+ return (void __user * )(address - (regs -> int_code >> 16 ));
4743}
4844
4945#ifdef CONFIG_GENERIC_BUG
@@ -58,16 +54,15 @@ void do_report_trap(struct pt_regs *regs, int si_signo, int si_code, char *str)
5854 if (user_mode (regs )) {
5955 force_sig_fault (si_signo , si_code , get_trap_ip (regs ));
6056 report_user_fault (regs , si_signo , 0 );
61- } else {
57+ } else {
6258 if (!fixup_exception (regs ))
6359 die (regs , str );
64- }
60+ }
6561}
6662
6763static void do_trap (struct pt_regs * regs , int si_signo , int si_code , char * str )
6864{
69- if (notify_die (DIE_TRAP , str , regs , 0 ,
70- regs -> int_code , si_signo ) == NOTIFY_STOP )
65+ if (notify_die (DIE_TRAP , str , regs , 0 , regs -> int_code , si_signo ) == NOTIFY_STOP )
7166 return ;
7267 do_report_trap (regs , si_signo , si_code , str );
7368}
@@ -79,8 +74,7 @@ void do_per_trap(struct pt_regs *regs)
7974 return ;
8075 if (!current -> ptrace )
8176 return ;
82- force_sig_fault (SIGTRAP , TRAP_HWBKPT ,
83- (void __force __user * ) current -> thread .per_event .address );
77+ force_sig_fault (SIGTRAP , TRAP_HWBKPT , (void __force __user * )current -> thread .per_event .address );
8478}
8579NOKPROBE_SYMBOL (do_per_trap );
8680
@@ -99,36 +93,25 @@ static void name(struct pt_regs *regs) \
9993 do_trap(regs, signr, sicode, str); \
10094}
10195
102- DO_ERROR_INFO (addressing_exception , SIGILL , ILL_ILLADR ,
103- "addressing exception" )
104- DO_ERROR_INFO (execute_exception , SIGILL , ILL_ILLOPN ,
105- "execute exception" )
106- DO_ERROR_INFO (divide_exception , SIGFPE , FPE_INTDIV ,
107- "fixpoint divide exception" )
108- DO_ERROR_INFO (overflow_exception , SIGFPE , FPE_INTOVF ,
109- "fixpoint overflow exception" )
110- DO_ERROR_INFO (hfp_overflow_exception , SIGFPE , FPE_FLTOVF ,
111- "HFP overflow exception" )
112- DO_ERROR_INFO (hfp_underflow_exception , SIGFPE , FPE_FLTUND ,
113- "HFP underflow exception" )
114- DO_ERROR_INFO (hfp_significance_exception , SIGFPE , FPE_FLTRES ,
115- "HFP significance exception" )
116- DO_ERROR_INFO (hfp_divide_exception , SIGFPE , FPE_FLTDIV ,
117- "HFP divide exception" )
118- DO_ERROR_INFO (hfp_sqrt_exception , SIGFPE , FPE_FLTINV ,
119- "HFP square root exception" )
120- DO_ERROR_INFO (operand_exception , SIGILL , ILL_ILLOPN ,
121- "operand exception" )
122- DO_ERROR_INFO (privileged_op , SIGILL , ILL_PRVOPC ,
123- "privileged operation" )
124- DO_ERROR_INFO (special_op_exception , SIGILL , ILL_ILLOPN ,
125- "special operation exception" )
126- DO_ERROR_INFO (transaction_exception , SIGILL , ILL_ILLOPN ,
127- "transaction constraint exception" )
96+ DO_ERROR_INFO (addressing_exception , SIGILL , ILL_ILLADR , "addressing exception" )
97+ DO_ERROR_INFO (divide_exception , SIGFPE , FPE_INTDIV , "fixpoint divide exception" )
98+ DO_ERROR_INFO (execute_exception , SIGILL , ILL_ILLOPN , "execute exception" )
99+ DO_ERROR_INFO (hfp_divide_exception , SIGFPE , FPE_FLTDIV , "HFP divide exception" )
100+ DO_ERROR_INFO (hfp_overflow_exception , SIGFPE , FPE_FLTOVF , "HFP overflow exception" )
101+ DO_ERROR_INFO (hfp_significance_exception , SIGFPE , FPE_FLTRES , "HFP significance exception" )
102+ DO_ERROR_INFO (hfp_sqrt_exception , SIGFPE , FPE_FLTINV , "HFP square root exception" )
103+ DO_ERROR_INFO (hfp_underflow_exception , SIGFPE , FPE_FLTUND , "HFP underflow exception" )
104+ DO_ERROR_INFO (operand_exception , SIGILL , ILL_ILLOPN , "operand exception" )
105+ DO_ERROR_INFO (overflow_exception , SIGFPE , FPE_INTOVF , "fixpoint overflow exception" )
106+ DO_ERROR_INFO (privileged_op , SIGILL , ILL_PRVOPC , "privileged operation" )
107+ DO_ERROR_INFO (special_op_exception , SIGILL , ILL_ILLOPN , "special operation exception" )
108+ DO_ERROR_INFO (specification_exception , SIGILL , ILL_ILLOPN , "specification exception" );
109+ DO_ERROR_INFO (transaction_exception , SIGILL , ILL_ILLOPN , "transaction constraint exception" )
128110
129111static inline void do_fp_trap (struct pt_regs * regs , __u32 fpc )
130112{
131113 int si_code = 0 ;
114+
132115 /* FPC[2] is Data Exception Code */
133116 if ((fpc & 0x00000300 ) == 0 ) {
134117 /* bits 6 and 7 of DXC are 0 iff IEEE exception */
@@ -160,7 +143,6 @@ static void illegal_op(struct pt_regs *regs)
160143 u16 opcode ;
161144
162145 location = get_trap_ip (regs );
163-
164146 if (user_mode (regs )) {
165147 if (get_user (opcode , location ))
166148 return ;
@@ -173,27 +155,24 @@ static void illegal_op(struct pt_regs *regs)
173155 } else if (opcode == UPROBE_SWBP_INSN ) {
174156 is_uprobe_insn = 1 ;
175157#endif
176- } else
158+ } else {
177159 signal = SIGILL ;
160+ }
178161 }
179162 /*
180- * We got either an illegal op in kernel mode, or user space trapped
163+ * This is either an illegal op in kernel mode, or user space trapped
181164 * on a uprobes illegal instruction. See if kprobes or uprobes picks
182165 * it up. If not, SIGILL.
183166 */
184167 if (is_uprobe_insn || !user_mode (regs )) {
185- if (notify_die (DIE_BPT , "bpt" , regs , 0 ,
186- 3 , SIGTRAP ) != NOTIFY_STOP )
168+ if (notify_die (DIE_BPT , "bpt" , regs , 0 , 3 , SIGTRAP ) != NOTIFY_STOP )
187169 signal = SIGILL ;
188170 }
189171 if (signal )
190172 do_trap (regs , signal , ILL_ILLOPC , "illegal operation" );
191173}
192174NOKPROBE_SYMBOL (illegal_op );
193175
194- DO_ERROR_INFO (specification_exception , SIGILL , ILL_ILLOPN ,
195- "specification exception" );
196-
197176static void vector_exception (struct pt_regs * regs )
198177{
199178 int si_code , vic ;
@@ -245,7 +224,6 @@ static void monitor_event_exception(struct pt_regs *regs)
245224{
246225 if (user_mode (regs ))
247226 return ;
248-
249227 switch (report_bug (regs -> psw .addr - (regs -> int_code >> 16 ), regs )) {
250228 case BUG_TRAP_TYPE_NONE :
251229 fixup_exception (regs );
@@ -319,7 +297,6 @@ void noinstr __do_pgm_check(struct pt_regs *regs)
319297 teid .val = lc -> trans_exc_code ;
320298 regs -> int_code = lc -> pgm_int_code ;
321299 regs -> int_parm_long = teid .val ;
322-
323300 /*
324301 * In case of a guest fault, short-circuit the fault handler and return.
325302 * This way the sie64a() function will return 0; fault address and
@@ -332,9 +309,7 @@ void noinstr __do_pgm_check(struct pt_regs *regs)
332309 current -> thread .gmap_int_code = regs -> int_code & 0xffff ;
333310 return ;
334311 }
335-
336312 state = irqentry_enter (regs );
337-
338313 if (user_mode (regs )) {
339314 update_timer_sys ();
340315 if (!cpu_has_bear ()) {
@@ -343,12 +318,10 @@ void noinstr __do_pgm_check(struct pt_regs *regs)
343318 }
344319 current -> thread .last_break = regs -> last_break ;
345320 }
346-
347321 if (lc -> pgm_code & 0x0200 ) {
348322 /* transaction abort */
349323 current -> thread .trap_tdb = lc -> pgm_tdb ;
350324 }
351-
352325 if (lc -> pgm_code & PGM_INT_CODE_PER ) {
353326 if (user_mode (regs )) {
354327 struct per_event * ev = & current -> thread .per_event ;
@@ -364,11 +337,9 @@ void noinstr __do_pgm_check(struct pt_regs *regs)
364337 goto out ;
365338 }
366339 }
367-
368340 if (!irqs_disabled_flags (regs -> psw .mask ))
369341 trace_hardirqs_on ();
370342 __arch_local_irq_ssm (regs -> psw .mask & ~PSW_MASK_PER );
371-
372343 trapnr = regs -> int_code & PGM_INT_CODE_MASK ;
373344 if (trapnr )
374345 pgm_check_table [trapnr ](regs );
0 commit comments