.. | .. |
---|
45 | 45 | void do_report_trap(struct pt_regs *regs, int si_signo, int si_code, char *str) |
---|
46 | 46 | { |
---|
47 | 47 | if (user_mode(regs)) { |
---|
48 | | - force_sig_fault(si_signo, si_code, get_trap_ip(regs), current); |
---|
| 48 | + force_sig_fault(si_signo, si_code, get_trap_ip(regs)); |
---|
49 | 49 | report_user_fault(regs, si_signo, 0); |
---|
50 | 50 | } else { |
---|
51 | 51 | const struct exception_table_entry *fixup; |
---|
52 | | - fixup = search_exception_tables(regs->psw.addr); |
---|
53 | | - if (fixup) |
---|
54 | | - regs->psw.addr = extable_fixup(fixup); |
---|
55 | | - else { |
---|
56 | | - enum bug_trap_type btt; |
---|
57 | | - |
---|
58 | | - btt = report_bug(regs->psw.addr, regs); |
---|
59 | | - if (btt == BUG_TRAP_TYPE_WARN) |
---|
60 | | - return; |
---|
| 52 | + fixup = s390_search_extables(regs->psw.addr); |
---|
| 53 | + if (!fixup || !ex_handle(fixup, regs)) |
---|
61 | 54 | die(regs, str); |
---|
62 | | - } |
---|
63 | 55 | } |
---|
64 | 56 | } |
---|
65 | 57 | |
---|
.. | .. |
---|
79 | 71 | if (!current->ptrace) |
---|
80 | 72 | return; |
---|
81 | 73 | force_sig_fault(SIGTRAP, TRAP_HWBKPT, |
---|
82 | | - (void __force __user *) current->thread.per_event.address, current); |
---|
| 74 | + (void __force __user *) current->thread.per_event.address); |
---|
83 | 75 | } |
---|
84 | 76 | NOKPROBE_SYMBOL(do_per_trap); |
---|
85 | 77 | |
---|
.. | .. |
---|
165 | 157 | return; |
---|
166 | 158 | if (*((__u16 *) opcode) == S390_BREAKPOINT_U16) { |
---|
167 | 159 | if (current->ptrace) |
---|
168 | | - force_sig_fault(SIGTRAP, TRAP_BRKPT, location, current); |
---|
| 160 | + force_sig_fault(SIGTRAP, TRAP_BRKPT, location); |
---|
169 | 161 | else |
---|
170 | 162 | signal = SIGILL; |
---|
171 | 163 | #ifdef CONFIG_UPROBES |
---|
.. | .. |
---|
229 | 221 | |
---|
230 | 222 | void data_exception(struct pt_regs *regs) |
---|
231 | 223 | { |
---|
232 | | - int signal = 0; |
---|
233 | | - |
---|
234 | 224 | save_fpu_regs(); |
---|
235 | 225 | if (current->thread.fpu.fpc & FPC_DXC_MASK) |
---|
236 | | - signal = SIGFPE; |
---|
237 | | - else |
---|
238 | | - signal = SIGILL; |
---|
239 | | - if (signal == SIGFPE) |
---|
240 | 226 | do_fp_trap(regs, current->thread.fpu.fpc); |
---|
241 | | - else if (signal) |
---|
242 | | - do_trap(regs, signal, ILL_ILLOPN, "data exception"); |
---|
| 227 | + else |
---|
| 228 | + do_trap(regs, SIGILL, ILL_ILLOPN, "data exception"); |
---|
243 | 229 | } |
---|
244 | 230 | |
---|
245 | 231 | void space_switch_exception(struct pt_regs *regs) |
---|
.. | .. |
---|
249 | 235 | regs->psw.mask |= PSW_ASC_HOME; |
---|
250 | 236 | /* Send SIGILL. */ |
---|
251 | 237 | do_trap(regs, SIGILL, ILL_PRVOPC, "space switch event"); |
---|
| 238 | +} |
---|
| 239 | + |
---|
| 240 | +void monitor_event_exception(struct pt_regs *regs) |
---|
| 241 | +{ |
---|
| 242 | + const struct exception_table_entry *fixup; |
---|
| 243 | + |
---|
| 244 | + if (user_mode(regs)) |
---|
| 245 | + return; |
---|
| 246 | + |
---|
| 247 | + switch (report_bug(regs->psw.addr - (regs->int_code >> 16), regs)) { |
---|
| 248 | + case BUG_TRAP_TYPE_NONE: |
---|
| 249 | + fixup = s390_search_extables(regs->psw.addr); |
---|
| 250 | + if (fixup) |
---|
| 251 | + ex_handle(fixup, regs); |
---|
| 252 | + break; |
---|
| 253 | + case BUG_TRAP_TYPE_WARN: |
---|
| 254 | + break; |
---|
| 255 | + case BUG_TRAP_TYPE_BUG: |
---|
| 256 | + die(regs, "monitor event"); |
---|
| 257 | + break; |
---|
| 258 | + } |
---|
252 | 259 | } |
---|
253 | 260 | |
---|
254 | 261 | void kernel_stack_overflow(struct pt_regs *regs) |
---|
.. | .. |
---|
261 | 268 | } |
---|
262 | 269 | NOKPROBE_SYMBOL(kernel_stack_overflow); |
---|
263 | 270 | |
---|
| 271 | +static void __init test_monitor_call(void) |
---|
| 272 | +{ |
---|
| 273 | + int val = 1; |
---|
| 274 | + |
---|
| 275 | + if (!IS_ENABLED(CONFIG_BUG)) |
---|
| 276 | + return; |
---|
| 277 | + asm volatile( |
---|
| 278 | + " mc 0,0\n" |
---|
| 279 | + "0: xgr %0,%0\n" |
---|
| 280 | + "1:\n" |
---|
| 281 | + EX_TABLE(0b,1b) |
---|
| 282 | + : "+d" (val)); |
---|
| 283 | + if (!val) |
---|
| 284 | + panic("Monitor call doesn't work!\n"); |
---|
| 285 | +} |
---|
| 286 | + |
---|
264 | 287 | void __init trap_init(void) |
---|
265 | 288 | { |
---|
| 289 | + sort_extable(__start_dma_ex_table, __stop_dma_ex_table); |
---|
266 | 290 | local_mcck_enable(); |
---|
| 291 | + test_monitor_call(); |
---|
267 | 292 | } |
---|