3
3
* S390 version
4
4
* Copyright IBM Corp. 1999, 2000
5
5
* Author(s): Martin Schwidefsky ([email protected] ),
6
-
6
+
7
7
*
8
8
* Derived from "arch/i386/kernel/traps.c"
9
9
* Copyright (C) 1991, 1992 Linus Torvalds
10
10
*/
11
11
12
- /*
13
- * 'Traps.c' handles hardware traps and faults after we have saved some
14
- * state in 'asm.s'.
15
- */
16
12
#include <linux/cpufeature.h>
17
13
#include <linux/kprobes.h>
18
14
#include <linux/kdebug.h>
@@ -43,7 +39,7 @@ static inline void __user *get_trap_ip(struct pt_regs *regs)
43
39
address = current -> thread .trap_tdb .data [3 ];
44
40
else
45
41
address = regs -> psw .addr ;
46
- return (void __user * ) (address - (regs -> int_code >> 16 ));
42
+ return (void __user * )(address - (regs -> int_code >> 16 ));
47
43
}
48
44
49
45
#ifdef CONFIG_GENERIC_BUG
@@ -58,16 +54,15 @@ void do_report_trap(struct pt_regs *regs, int si_signo, int si_code, char *str)
58
54
if (user_mode (regs )) {
59
55
force_sig_fault (si_signo , si_code , get_trap_ip (regs ));
60
56
report_user_fault (regs , si_signo , 0 );
61
- } else {
57
+ } else {
62
58
if (!fixup_exception (regs ))
63
59
die (regs , str );
64
- }
60
+ }
65
61
}
66
62
67
63
static void do_trap (struct pt_regs * regs , int si_signo , int si_code , char * str )
68
64
{
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 )
71
66
return ;
72
67
do_report_trap (regs , si_signo , si_code , str );
73
68
}
@@ -79,8 +74,7 @@ void do_per_trap(struct pt_regs *regs)
79
74
return ;
80
75
if (!current -> ptrace )
81
76
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 );
84
78
}
85
79
NOKPROBE_SYMBOL (do_per_trap );
86
80
@@ -99,36 +93,25 @@ static void name(struct pt_regs *regs) \
99
93
do_trap(regs, signr, sicode, str); \
100
94
}
101
95
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" )
128
110
129
111
static inline void do_fp_trap (struct pt_regs * regs , __u32 fpc )
130
112
{
131
113
int si_code = 0 ;
114
+
132
115
/* FPC[2] is Data Exception Code */
133
116
if ((fpc & 0x00000300 ) == 0 ) {
134
117
/* bits 6 and 7 of DXC are 0 iff IEEE exception */
@@ -160,7 +143,6 @@ static void illegal_op(struct pt_regs *regs)
160
143
u16 opcode ;
161
144
162
145
location = get_trap_ip (regs );
163
-
164
146
if (user_mode (regs )) {
165
147
if (get_user (opcode , location ))
166
148
return ;
@@ -173,27 +155,24 @@ static void illegal_op(struct pt_regs *regs)
173
155
} else if (opcode == UPROBE_SWBP_INSN ) {
174
156
is_uprobe_insn = 1 ;
175
157
#endif
176
- } else
158
+ } else {
177
159
signal = SIGILL ;
160
+ }
178
161
}
179
162
/*
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
181
164
* on a uprobes illegal instruction. See if kprobes or uprobes picks
182
165
* it up. If not, SIGILL.
183
166
*/
184
167
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 )
187
169
signal = SIGILL ;
188
170
}
189
171
if (signal )
190
172
do_trap (regs , signal , ILL_ILLOPC , "illegal operation" );
191
173
}
192
174
NOKPROBE_SYMBOL (illegal_op );
193
175
194
- DO_ERROR_INFO (specification_exception , SIGILL , ILL_ILLOPN ,
195
- "specification exception" );
196
-
197
176
static void vector_exception (struct pt_regs * regs )
198
177
{
199
178
int si_code , vic ;
@@ -245,7 +224,6 @@ static void monitor_event_exception(struct pt_regs *regs)
245
224
{
246
225
if (user_mode (regs ))
247
226
return ;
248
-
249
227
switch (report_bug (regs -> psw .addr - (regs -> int_code >> 16 ), regs )) {
250
228
case BUG_TRAP_TYPE_NONE :
251
229
fixup_exception (regs );
@@ -319,7 +297,6 @@ void noinstr __do_pgm_check(struct pt_regs *regs)
319
297
teid .val = lc -> trans_exc_code ;
320
298
regs -> int_code = lc -> pgm_int_code ;
321
299
regs -> int_parm_long = teid .val ;
322
-
323
300
/*
324
301
* In case of a guest fault, short-circuit the fault handler and return.
325
302
* This way the sie64a() function will return 0; fault address and
@@ -332,9 +309,7 @@ void noinstr __do_pgm_check(struct pt_regs *regs)
332
309
current -> thread .gmap_int_code = regs -> int_code & 0xffff ;
333
310
return ;
334
311
}
335
-
336
312
state = irqentry_enter (regs );
337
-
338
313
if (user_mode (regs )) {
339
314
update_timer_sys ();
340
315
if (!cpu_has_bear ()) {
@@ -343,12 +318,10 @@ void noinstr __do_pgm_check(struct pt_regs *regs)
343
318
}
344
319
current -> thread .last_break = regs -> last_break ;
345
320
}
346
-
347
321
if (lc -> pgm_code & 0x0200 ) {
348
322
/* transaction abort */
349
323
current -> thread .trap_tdb = lc -> pgm_tdb ;
350
324
}
351
-
352
325
if (lc -> pgm_code & PGM_INT_CODE_PER ) {
353
326
if (user_mode (regs )) {
354
327
struct per_event * ev = & current -> thread .per_event ;
@@ -364,11 +337,9 @@ void noinstr __do_pgm_check(struct pt_regs *regs)
364
337
goto out ;
365
338
}
366
339
}
367
-
368
340
if (!irqs_disabled_flags (regs -> psw .mask ))
369
341
trace_hardirqs_on ();
370
342
__arch_local_irq_ssm (regs -> psw .mask & ~PSW_MASK_PER );
371
-
372
343
trapnr = regs -> int_code & PGM_INT_CODE_MASK ;
373
344
if (trapnr )
374
345
pgm_check_table [trapnr ](regs );
0 commit comments