| .. | .. |
|---|
| 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 | } |
|---|