12a0a5b22SJan Willeke /* 22a0a5b22SJan Willeke * User-space Probes (UProbes) for s390 32a0a5b22SJan Willeke * 42a0a5b22SJan Willeke * Copyright IBM Corp. 2014 52a0a5b22SJan Willeke * Author(s): Jan Willeke, 62a0a5b22SJan Willeke */ 72a0a5b22SJan Willeke 82a0a5b22SJan Willeke #include <linux/uaccess.h> 92a0a5b22SJan Willeke #include <linux/uprobes.h> 102a0a5b22SJan Willeke #include <linux/compat.h> 112a0a5b22SJan Willeke #include <linux/kdebug.h> 1268db0cf1SIngo Molnar #include <linux/sched/task_stack.h> 1368db0cf1SIngo Molnar 142a0a5b22SJan Willeke #include <asm/switch_to.h> 152a0a5b22SJan Willeke #include <asm/facility.h> 16d6fe5be3SJan Willeke #include <asm/kprobes.h> 172a0a5b22SJan Willeke #include <asm/dis.h> 182a0a5b22SJan Willeke #include "entry.h" 192a0a5b22SJan Willeke 202a0a5b22SJan Willeke #define UPROBE_TRAP_NR UINT_MAX 212a0a5b22SJan Willeke 222a0a5b22SJan Willeke int arch_uprobe_analyze_insn(struct arch_uprobe *auprobe, struct mm_struct *mm, 232a0a5b22SJan Willeke unsigned long addr) 242a0a5b22SJan Willeke { 252a0a5b22SJan Willeke return probe_is_prohibited_opcode(auprobe->insn); 262a0a5b22SJan Willeke } 272a0a5b22SJan Willeke 282a0a5b22SJan Willeke int arch_uprobe_pre_xol(struct arch_uprobe *auprobe, struct pt_regs *regs) 292a0a5b22SJan Willeke { 30*8bb3fdd6SHeiko Carstens if (psw_bits(regs->psw).eaba == PSW_BITS_AMODE_24BIT) 312a0a5b22SJan Willeke return -EINVAL; 32*8bb3fdd6SHeiko Carstens if (!is_compat_task() && psw_bits(regs->psw).eaba == PSW_BITS_AMODE_31BIT) 332a0a5b22SJan Willeke return -EINVAL; 342a0a5b22SJan Willeke clear_pt_regs_flag(regs, PIF_PER_TRAP); 352a0a5b22SJan Willeke auprobe->saved_per = psw_bits(regs->psw).r; 362a0a5b22SJan Willeke auprobe->saved_int_code = regs->int_code; 372a0a5b22SJan Willeke regs->int_code = UPROBE_TRAP_NR; 382a0a5b22SJan Willeke regs->psw.addr = current->utask->xol_vaddr; 392a0a5b22SJan Willeke set_tsk_thread_flag(current, TIF_UPROBE_SINGLESTEP); 402a0a5b22SJan Willeke update_cr_regs(current); 412a0a5b22SJan Willeke return 0; 422a0a5b22SJan Willeke } 432a0a5b22SJan Willeke 442a0a5b22SJan Willeke bool arch_uprobe_xol_was_trapped(struct task_struct *tsk) 452a0a5b22SJan Willeke { 462a0a5b22SJan Willeke struct pt_regs *regs = task_pt_regs(tsk); 472a0a5b22SJan Willeke 482a0a5b22SJan Willeke if (regs->int_code != UPROBE_TRAP_NR) 492a0a5b22SJan Willeke return true; 502a0a5b22SJan Willeke return false; 512a0a5b22SJan Willeke } 522a0a5b22SJan Willeke 538d1a2427SJan Willeke static int check_per_event(unsigned short cause, unsigned long control, 548d1a2427SJan Willeke struct pt_regs *regs) 558d1a2427SJan Willeke { 568d1a2427SJan Willeke if (!(regs->psw.mask & PSW_MASK_PER)) 578d1a2427SJan Willeke return 0; 588d1a2427SJan Willeke /* user space single step */ 598d1a2427SJan Willeke if (control == 0) 608d1a2427SJan Willeke return 1; 618d1a2427SJan Willeke /* over indication for storage alteration */ 628d1a2427SJan Willeke if ((control & 0x20200000) && (cause & 0x2000)) 638d1a2427SJan Willeke return 1; 648d1a2427SJan Willeke if (cause & 0x8000) { 658d1a2427SJan Willeke /* all branches */ 668d1a2427SJan Willeke if ((control & 0x80800000) == 0x80000000) 678d1a2427SJan Willeke return 1; 688d1a2427SJan Willeke /* branch into selected range */ 698d1a2427SJan Willeke if (((control & 0x80800000) == 0x80800000) && 708d1a2427SJan Willeke regs->psw.addr >= current->thread.per_user.start && 718d1a2427SJan Willeke regs->psw.addr <= current->thread.per_user.end) 728d1a2427SJan Willeke return 1; 738d1a2427SJan Willeke } 748d1a2427SJan Willeke return 0; 758d1a2427SJan Willeke } 768d1a2427SJan Willeke 772a0a5b22SJan Willeke int arch_uprobe_post_xol(struct arch_uprobe *auprobe, struct pt_regs *regs) 782a0a5b22SJan Willeke { 792a0a5b22SJan Willeke int fixup = probe_get_fixup_type(auprobe->insn); 802a0a5b22SJan Willeke struct uprobe_task *utask = current->utask; 812a0a5b22SJan Willeke 822a0a5b22SJan Willeke clear_tsk_thread_flag(current, TIF_UPROBE_SINGLESTEP); 832a0a5b22SJan Willeke update_cr_regs(current); 842a0a5b22SJan Willeke psw_bits(regs->psw).r = auprobe->saved_per; 852a0a5b22SJan Willeke regs->int_code = auprobe->saved_int_code; 862a0a5b22SJan Willeke 872a0a5b22SJan Willeke if (fixup & FIXUP_PSW_NORMAL) 882a0a5b22SJan Willeke regs->psw.addr += utask->vaddr - utask->xol_vaddr; 892a0a5b22SJan Willeke if (fixup & FIXUP_RETURN_REGISTER) { 902a0a5b22SJan Willeke int reg = (auprobe->insn[0] & 0xf0) >> 4; 912a0a5b22SJan Willeke 922a0a5b22SJan Willeke regs->gprs[reg] += utask->vaddr - utask->xol_vaddr; 932a0a5b22SJan Willeke } 942a0a5b22SJan Willeke if (fixup & FIXUP_BRANCH_NOT_TAKEN) { 952a0a5b22SJan Willeke int ilen = insn_length(auprobe->insn[0] >> 8); 962a0a5b22SJan Willeke 972a0a5b22SJan Willeke if (regs->psw.addr - utask->xol_vaddr == ilen) 982a0a5b22SJan Willeke regs->psw.addr = utask->vaddr + ilen; 992a0a5b22SJan Willeke } 1008d1a2427SJan Willeke if (check_per_event(current->thread.per_event.cause, 1018d1a2427SJan Willeke current->thread.per_user.control, regs)) { 1028d1a2427SJan Willeke /* fix per address */ 1038d1a2427SJan Willeke current->thread.per_event.address = utask->vaddr; 1048d1a2427SJan Willeke /* trigger per event */ 1058d1a2427SJan Willeke set_pt_regs_flag(regs, PIF_PER_TRAP); 1068d1a2427SJan Willeke } 1072a0a5b22SJan Willeke return 0; 1082a0a5b22SJan Willeke } 1092a0a5b22SJan Willeke 1102a0a5b22SJan Willeke int arch_uprobe_exception_notify(struct notifier_block *self, unsigned long val, 1112a0a5b22SJan Willeke void *data) 1122a0a5b22SJan Willeke { 1132a0a5b22SJan Willeke struct die_args *args = data; 1142a0a5b22SJan Willeke struct pt_regs *regs = args->regs; 1152a0a5b22SJan Willeke 1162a0a5b22SJan Willeke if (!user_mode(regs)) 1172a0a5b22SJan Willeke return NOTIFY_DONE; 1182a0a5b22SJan Willeke if (regs->int_code & 0x200) /* Trap during transaction */ 1192a0a5b22SJan Willeke return NOTIFY_DONE; 1202a0a5b22SJan Willeke switch (val) { 1212a0a5b22SJan Willeke case DIE_BPT: 1222a0a5b22SJan Willeke if (uprobe_pre_sstep_notifier(regs)) 1232a0a5b22SJan Willeke return NOTIFY_STOP; 1242a0a5b22SJan Willeke break; 1252a0a5b22SJan Willeke case DIE_SSTEP: 1262a0a5b22SJan Willeke if (uprobe_post_sstep_notifier(regs)) 1272a0a5b22SJan Willeke return NOTIFY_STOP; 1282a0a5b22SJan Willeke default: 1292a0a5b22SJan Willeke break; 1302a0a5b22SJan Willeke } 1312a0a5b22SJan Willeke return NOTIFY_DONE; 1322a0a5b22SJan Willeke } 1332a0a5b22SJan Willeke 1342a0a5b22SJan Willeke void arch_uprobe_abort_xol(struct arch_uprobe *auprobe, struct pt_regs *regs) 1352a0a5b22SJan Willeke { 1362a0a5b22SJan Willeke clear_thread_flag(TIF_UPROBE_SINGLESTEP); 1372a0a5b22SJan Willeke regs->int_code = auprobe->saved_int_code; 1382a0a5b22SJan Willeke regs->psw.addr = current->utask->vaddr; 1398d1a2427SJan Willeke current->thread.per_event.address = current->utask->vaddr; 1402a0a5b22SJan Willeke } 1412a0a5b22SJan Willeke 1422a0a5b22SJan Willeke unsigned long arch_uretprobe_hijack_return_addr(unsigned long trampoline, 1432a0a5b22SJan Willeke struct pt_regs *regs) 1442a0a5b22SJan Willeke { 1452a0a5b22SJan Willeke unsigned long orig; 1462a0a5b22SJan Willeke 1472a0a5b22SJan Willeke orig = regs->gprs[14]; 1482a0a5b22SJan Willeke regs->gprs[14] = trampoline; 1492a0a5b22SJan Willeke return orig; 1502a0a5b22SJan Willeke } 1512a0a5b22SJan Willeke 1522a0a5b22SJan Willeke /* Instruction Emulation */ 1532a0a5b22SJan Willeke 1542a0a5b22SJan Willeke static void adjust_psw_addr(psw_t *psw, unsigned long len) 1552a0a5b22SJan Willeke { 1562a0a5b22SJan Willeke psw->addr = __rewind_psw(*psw, -len); 1572a0a5b22SJan Willeke } 1582a0a5b22SJan Willeke 1592a0a5b22SJan Willeke #define EMU_ILLEGAL_OP 1 1602a0a5b22SJan Willeke #define EMU_SPECIFICATION 2 1612a0a5b22SJan Willeke #define EMU_ADDRESSING 3 1622a0a5b22SJan Willeke 1632a0a5b22SJan Willeke #define emu_load_ril(ptr, output) \ 1642a0a5b22SJan Willeke ({ \ 1652a0a5b22SJan Willeke unsigned int mask = sizeof(*(ptr)) - 1; \ 1662a0a5b22SJan Willeke __typeof__(*(ptr)) input; \ 1672a0a5b22SJan Willeke int __rc = 0; \ 1682a0a5b22SJan Willeke \ 1692a0a5b22SJan Willeke if (!test_facility(34)) \ 1702a0a5b22SJan Willeke __rc = EMU_ILLEGAL_OP; \ 1712a0a5b22SJan Willeke else if ((u64 __force)ptr & mask) \ 1722a0a5b22SJan Willeke __rc = EMU_SPECIFICATION; \ 1732a0a5b22SJan Willeke else if (get_user(input, ptr)) \ 1742a0a5b22SJan Willeke __rc = EMU_ADDRESSING; \ 1752a0a5b22SJan Willeke else \ 1762a0a5b22SJan Willeke *(output) = input; \ 1772a0a5b22SJan Willeke __rc; \ 1782a0a5b22SJan Willeke }) 1792a0a5b22SJan Willeke 1808d1a2427SJan Willeke #define emu_store_ril(regs, ptr, input) \ 1812a0a5b22SJan Willeke ({ \ 1822a0a5b22SJan Willeke unsigned int mask = sizeof(*(ptr)) - 1; \ 1838d1a2427SJan Willeke __typeof__(ptr) __ptr = (ptr); \ 1842a0a5b22SJan Willeke int __rc = 0; \ 1852a0a5b22SJan Willeke \ 1862a0a5b22SJan Willeke if (!test_facility(34)) \ 1872a0a5b22SJan Willeke __rc = EMU_ILLEGAL_OP; \ 1888d1a2427SJan Willeke else if ((u64 __force)__ptr & mask) \ 1892a0a5b22SJan Willeke __rc = EMU_SPECIFICATION; \ 1908d1a2427SJan Willeke else if (put_user(*(input), __ptr)) \ 1912a0a5b22SJan Willeke __rc = EMU_ADDRESSING; \ 1928d1a2427SJan Willeke if (__rc == 0) \ 1939f9d86e1SHeiko Carstens sim_stor_event(regs, \ 1949f9d86e1SHeiko Carstens (void __force *)__ptr, \ 1959f9d86e1SHeiko Carstens mask + 1); \ 1962a0a5b22SJan Willeke __rc; \ 1972a0a5b22SJan Willeke }) 1982a0a5b22SJan Willeke 1992a0a5b22SJan Willeke #define emu_cmp_ril(regs, ptr, cmp) \ 2002a0a5b22SJan Willeke ({ \ 2012a0a5b22SJan Willeke unsigned int mask = sizeof(*(ptr)) - 1; \ 2022a0a5b22SJan Willeke __typeof__(*(ptr)) input; \ 2032a0a5b22SJan Willeke int __rc = 0; \ 2042a0a5b22SJan Willeke \ 2052a0a5b22SJan Willeke if (!test_facility(34)) \ 2062a0a5b22SJan Willeke __rc = EMU_ILLEGAL_OP; \ 2072a0a5b22SJan Willeke else if ((u64 __force)ptr & mask) \ 2082a0a5b22SJan Willeke __rc = EMU_SPECIFICATION; \ 2092a0a5b22SJan Willeke else if (get_user(input, ptr)) \ 2102a0a5b22SJan Willeke __rc = EMU_ADDRESSING; \ 2112a0a5b22SJan Willeke else if (input > *(cmp)) \ 2122a0a5b22SJan Willeke psw_bits((regs)->psw).cc = 1; \ 2132a0a5b22SJan Willeke else if (input < *(cmp)) \ 2142a0a5b22SJan Willeke psw_bits((regs)->psw).cc = 2; \ 2152a0a5b22SJan Willeke else \ 2162a0a5b22SJan Willeke psw_bits((regs)->psw).cc = 0; \ 2172a0a5b22SJan Willeke __rc; \ 2182a0a5b22SJan Willeke }) 2192a0a5b22SJan Willeke 2202a0a5b22SJan Willeke struct insn_ril { 2212a0a5b22SJan Willeke u8 opc0; 2222a0a5b22SJan Willeke u8 reg : 4; 2232a0a5b22SJan Willeke u8 opc1 : 4; 2242a0a5b22SJan Willeke s32 disp; 2252a0a5b22SJan Willeke } __packed; 2262a0a5b22SJan Willeke 2272a0a5b22SJan Willeke union split_register { 2282a0a5b22SJan Willeke u64 u64; 2292a0a5b22SJan Willeke u32 u32[2]; 2302a0a5b22SJan Willeke u16 u16[4]; 2312a0a5b22SJan Willeke s64 s64; 2322a0a5b22SJan Willeke s32 s32[2]; 2332a0a5b22SJan Willeke s16 s16[4]; 2342a0a5b22SJan Willeke }; 2352a0a5b22SJan Willeke 2362a0a5b22SJan Willeke /* 2378d1a2427SJan Willeke * If user per registers are setup to trace storage alterations and an 2388d1a2427SJan Willeke * emulated store took place on a fitting address a user trap is generated. 2398d1a2427SJan Willeke */ 2408d1a2427SJan Willeke static void sim_stor_event(struct pt_regs *regs, void *addr, int len) 2418d1a2427SJan Willeke { 2428d1a2427SJan Willeke if (!(regs->psw.mask & PSW_MASK_PER)) 2438d1a2427SJan Willeke return; 2448d1a2427SJan Willeke if (!(current->thread.per_user.control & PER_EVENT_STORE)) 2458d1a2427SJan Willeke return; 2468d1a2427SJan Willeke if ((void *)current->thread.per_user.start > (addr + len)) 2478d1a2427SJan Willeke return; 2488d1a2427SJan Willeke if ((void *)current->thread.per_user.end < addr) 2498d1a2427SJan Willeke return; 2508d1a2427SJan Willeke current->thread.per_event.address = regs->psw.addr; 2518d1a2427SJan Willeke current->thread.per_event.cause = PER_EVENT_STORE >> 16; 2528d1a2427SJan Willeke set_pt_regs_flag(regs, PIF_PER_TRAP); 2538d1a2427SJan Willeke } 2548d1a2427SJan Willeke 2558d1a2427SJan Willeke /* 2562a0a5b22SJan Willeke * pc relative instructions are emulated, since parameters may not be 2572a0a5b22SJan Willeke * accessible from the xol area due to range limitations. 2582a0a5b22SJan Willeke */ 2592a0a5b22SJan Willeke static void handle_insn_ril(struct arch_uprobe *auprobe, struct pt_regs *regs) 2602a0a5b22SJan Willeke { 2612a0a5b22SJan Willeke union split_register *rx; 2622a0a5b22SJan Willeke struct insn_ril *insn; 2632a0a5b22SJan Willeke unsigned int ilen; 2642a0a5b22SJan Willeke void *uptr; 2652a0a5b22SJan Willeke int rc = 0; 2662a0a5b22SJan Willeke 2672a0a5b22SJan Willeke insn = (struct insn_ril *) &auprobe->insn; 2682a0a5b22SJan Willeke rx = (union split_register *) ®s->gprs[insn->reg]; 2692a0a5b22SJan Willeke uptr = (void *)(regs->psw.addr + (insn->disp * 2)); 2702a0a5b22SJan Willeke ilen = insn_length(insn->opc0); 2712a0a5b22SJan Willeke 2722a0a5b22SJan Willeke switch (insn->opc0) { 2732a0a5b22SJan Willeke case 0xc0: 2742a0a5b22SJan Willeke switch (insn->opc1) { 2752a0a5b22SJan Willeke case 0x00: /* larl */ 2762a0a5b22SJan Willeke rx->u64 = (unsigned long)uptr; 2772a0a5b22SJan Willeke break; 2782a0a5b22SJan Willeke } 2792a0a5b22SJan Willeke break; 2802a0a5b22SJan Willeke case 0xc4: 2812a0a5b22SJan Willeke switch (insn->opc1) { 2822a0a5b22SJan Willeke case 0x02: /* llhrl */ 2832a0a5b22SJan Willeke rc = emu_load_ril((u16 __user *)uptr, &rx->u32[1]); 2842a0a5b22SJan Willeke break; 2852a0a5b22SJan Willeke case 0x04: /* lghrl */ 2862a0a5b22SJan Willeke rc = emu_load_ril((s16 __user *)uptr, &rx->u64); 2872a0a5b22SJan Willeke break; 2882a0a5b22SJan Willeke case 0x05: /* lhrl */ 2892a0a5b22SJan Willeke rc = emu_load_ril((s16 __user *)uptr, &rx->u32[1]); 2902a0a5b22SJan Willeke break; 2912a0a5b22SJan Willeke case 0x06: /* llghrl */ 2922a0a5b22SJan Willeke rc = emu_load_ril((u16 __user *)uptr, &rx->u64); 2932a0a5b22SJan Willeke break; 2942a0a5b22SJan Willeke case 0x08: /* lgrl */ 2952a0a5b22SJan Willeke rc = emu_load_ril((u64 __user *)uptr, &rx->u64); 2962a0a5b22SJan Willeke break; 2972a0a5b22SJan Willeke case 0x0c: /* lgfrl */ 2982a0a5b22SJan Willeke rc = emu_load_ril((s32 __user *)uptr, &rx->u64); 2992a0a5b22SJan Willeke break; 3002a0a5b22SJan Willeke case 0x0d: /* lrl */ 3012a0a5b22SJan Willeke rc = emu_load_ril((u32 __user *)uptr, &rx->u32[1]); 3022a0a5b22SJan Willeke break; 3032a0a5b22SJan Willeke case 0x0e: /* llgfrl */ 3042a0a5b22SJan Willeke rc = emu_load_ril((u32 __user *)uptr, &rx->u64); 3052a0a5b22SJan Willeke break; 3062a0a5b22SJan Willeke case 0x07: /* sthrl */ 3078d1a2427SJan Willeke rc = emu_store_ril(regs, (u16 __user *)uptr, &rx->u16[3]); 3082a0a5b22SJan Willeke break; 3092a0a5b22SJan Willeke case 0x0b: /* stgrl */ 3108d1a2427SJan Willeke rc = emu_store_ril(regs, (u64 __user *)uptr, &rx->u64); 3112a0a5b22SJan Willeke break; 3122a0a5b22SJan Willeke case 0x0f: /* strl */ 3138d1a2427SJan Willeke rc = emu_store_ril(regs, (u32 __user *)uptr, &rx->u32[1]); 3142a0a5b22SJan Willeke break; 3152a0a5b22SJan Willeke } 3162a0a5b22SJan Willeke break; 3172a0a5b22SJan Willeke case 0xc6: 3182a0a5b22SJan Willeke switch (insn->opc1) { 3192a0a5b22SJan Willeke case 0x02: /* pfdrl */ 3202a0a5b22SJan Willeke if (!test_facility(34)) 3212a0a5b22SJan Willeke rc = EMU_ILLEGAL_OP; 3222a0a5b22SJan Willeke break; 3232a0a5b22SJan Willeke case 0x04: /* cghrl */ 3242a0a5b22SJan Willeke rc = emu_cmp_ril(regs, (s16 __user *)uptr, &rx->s64); 3252a0a5b22SJan Willeke break; 3262a0a5b22SJan Willeke case 0x05: /* chrl */ 3272a0a5b22SJan Willeke rc = emu_cmp_ril(regs, (s16 __user *)uptr, &rx->s32[1]); 3282a0a5b22SJan Willeke break; 3292a0a5b22SJan Willeke case 0x06: /* clghrl */ 3302a0a5b22SJan Willeke rc = emu_cmp_ril(regs, (u16 __user *)uptr, &rx->u64); 3312a0a5b22SJan Willeke break; 3322a0a5b22SJan Willeke case 0x07: /* clhrl */ 3332a0a5b22SJan Willeke rc = emu_cmp_ril(regs, (u16 __user *)uptr, &rx->u32[1]); 3342a0a5b22SJan Willeke break; 3352a0a5b22SJan Willeke case 0x08: /* cgrl */ 3362a0a5b22SJan Willeke rc = emu_cmp_ril(regs, (s64 __user *)uptr, &rx->s64); 3372a0a5b22SJan Willeke break; 3382a0a5b22SJan Willeke case 0x0a: /* clgrl */ 3392a0a5b22SJan Willeke rc = emu_cmp_ril(regs, (u64 __user *)uptr, &rx->u64); 3402a0a5b22SJan Willeke break; 3412a0a5b22SJan Willeke case 0x0c: /* cgfrl */ 3422a0a5b22SJan Willeke rc = emu_cmp_ril(regs, (s32 __user *)uptr, &rx->s64); 3432a0a5b22SJan Willeke break; 3442a0a5b22SJan Willeke case 0x0d: /* crl */ 3452a0a5b22SJan Willeke rc = emu_cmp_ril(regs, (s32 __user *)uptr, &rx->s32[1]); 3462a0a5b22SJan Willeke break; 3472a0a5b22SJan Willeke case 0x0e: /* clgfrl */ 3482a0a5b22SJan Willeke rc = emu_cmp_ril(regs, (u32 __user *)uptr, &rx->u64); 3492a0a5b22SJan Willeke break; 3502a0a5b22SJan Willeke case 0x0f: /* clrl */ 3512a0a5b22SJan Willeke rc = emu_cmp_ril(regs, (u32 __user *)uptr, &rx->u32[1]); 3522a0a5b22SJan Willeke break; 3532a0a5b22SJan Willeke } 3542a0a5b22SJan Willeke break; 3552a0a5b22SJan Willeke } 3562a0a5b22SJan Willeke adjust_psw_addr(®s->psw, ilen); 3572a0a5b22SJan Willeke switch (rc) { 3582a0a5b22SJan Willeke case EMU_ILLEGAL_OP: 3592a0a5b22SJan Willeke regs->int_code = ilen << 16 | 0x0001; 3602a0a5b22SJan Willeke do_report_trap(regs, SIGILL, ILL_ILLOPC, NULL); 3612a0a5b22SJan Willeke break; 3622a0a5b22SJan Willeke case EMU_SPECIFICATION: 3632a0a5b22SJan Willeke regs->int_code = ilen << 16 | 0x0006; 3642a0a5b22SJan Willeke do_report_trap(regs, SIGILL, ILL_ILLOPC , NULL); 3652a0a5b22SJan Willeke break; 3662a0a5b22SJan Willeke case EMU_ADDRESSING: 3672a0a5b22SJan Willeke regs->int_code = ilen << 16 | 0x0005; 3682a0a5b22SJan Willeke do_report_trap(regs, SIGSEGV, SEGV_MAPERR, NULL); 3692a0a5b22SJan Willeke break; 3702a0a5b22SJan Willeke } 3712a0a5b22SJan Willeke } 3722a0a5b22SJan Willeke 3732a0a5b22SJan Willeke bool arch_uprobe_skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs) 3742a0a5b22SJan Willeke { 375*8bb3fdd6SHeiko Carstens if ((psw_bits(regs->psw).eaba == PSW_BITS_AMODE_24BIT) || 376*8bb3fdd6SHeiko Carstens ((psw_bits(regs->psw).eaba == PSW_BITS_AMODE_31BIT) && 3772a0a5b22SJan Willeke !is_compat_task())) { 3782a0a5b22SJan Willeke regs->psw.addr = __rewind_psw(regs->psw, UPROBE_SWBP_INSN_SIZE); 3792a0a5b22SJan Willeke do_report_trap(regs, SIGILL, ILL_ILLADR, NULL); 3802a0a5b22SJan Willeke return true; 3812a0a5b22SJan Willeke } 3822a0a5b22SJan Willeke if (probe_is_insn_relative_long(auprobe->insn)) { 3832a0a5b22SJan Willeke handle_insn_ril(auprobe, regs); 3842a0a5b22SJan Willeke return true; 3852a0a5b22SJan Willeke } 3862a0a5b22SJan Willeke return false; 3872a0a5b22SJan Willeke } 388