174784081SGuo Ren // SPDX-License-Identifier: GPL-2.0-only 274784081SGuo Ren 374784081SGuo Ren #include <linux/highmem.h> 474784081SGuo Ren #include <linux/ptrace.h> 574784081SGuo Ren #include <linux/uprobes.h> 6*b701f9e7SNam Cao #include <asm/insn.h> 774784081SGuo Ren 874784081SGuo Ren #include "decode-insn.h" 974784081SGuo Ren 1074784081SGuo Ren #define UPROBE_TRAP_NR UINT_MAX 1174784081SGuo Ren 1274784081SGuo Ren bool is_swbp_insn(uprobe_opcode_t *insn) 1374784081SGuo Ren { 1474784081SGuo Ren #ifdef CONFIG_RISCV_ISA_C 1574784081SGuo Ren return (*insn & 0xffff) == UPROBE_SWBP_INSN; 1674784081SGuo Ren #else 1774784081SGuo Ren return *insn == UPROBE_SWBP_INSN; 1874784081SGuo Ren #endif 1974784081SGuo Ren } 2074784081SGuo Ren 21*b701f9e7SNam Cao bool is_trap_insn(uprobe_opcode_t *insn) 22*b701f9e7SNam Cao { 23*b701f9e7SNam Cao return riscv_insn_is_ebreak(*insn) || riscv_insn_is_c_ebreak(*insn); 24*b701f9e7SNam Cao } 25*b701f9e7SNam Cao 2674784081SGuo Ren unsigned long uprobe_get_swbp_addr(struct pt_regs *regs) 2774784081SGuo Ren { 2874784081SGuo Ren return instruction_pointer(regs); 2974784081SGuo Ren } 3074784081SGuo Ren 3174784081SGuo Ren int arch_uprobe_analyze_insn(struct arch_uprobe *auprobe, struct mm_struct *mm, 3274784081SGuo Ren unsigned long addr) 3374784081SGuo Ren { 3474784081SGuo Ren probe_opcode_t opcode; 3574784081SGuo Ren 3674784081SGuo Ren opcode = *(probe_opcode_t *)(&auprobe->insn[0]); 3774784081SGuo Ren 3874784081SGuo Ren auprobe->insn_size = GET_INSN_LENGTH(opcode); 3974784081SGuo Ren 4074784081SGuo Ren switch (riscv_probe_decode_insn(&opcode, &auprobe->api)) { 4174784081SGuo Ren case INSN_REJECTED: 4274784081SGuo Ren return -EINVAL; 4374784081SGuo Ren 4474784081SGuo Ren case INSN_GOOD_NO_SLOT: 4574784081SGuo Ren auprobe->simulate = true; 4674784081SGuo Ren break; 4774784081SGuo Ren 4874784081SGuo Ren case INSN_GOOD: 4974784081SGuo Ren auprobe->simulate = false; 5074784081SGuo Ren break; 5174784081SGuo Ren 5274784081SGuo Ren default: 5374784081SGuo Ren return -EINVAL; 5474784081SGuo Ren } 5574784081SGuo Ren 5674784081SGuo Ren return 0; 5774784081SGuo Ren } 5874784081SGuo Ren 5974784081SGuo Ren int arch_uprobe_pre_xol(struct arch_uprobe *auprobe, struct pt_regs *regs) 6074784081SGuo Ren { 6174784081SGuo Ren struct uprobe_task *utask = current->utask; 6274784081SGuo Ren 6374784081SGuo Ren utask->autask.saved_cause = current->thread.bad_cause; 6474784081SGuo Ren current->thread.bad_cause = UPROBE_TRAP_NR; 6574784081SGuo Ren 6674784081SGuo Ren instruction_pointer_set(regs, utask->xol_vaddr); 6774784081SGuo Ren 6874784081SGuo Ren return 0; 6974784081SGuo Ren } 7074784081SGuo Ren 7174784081SGuo Ren int arch_uprobe_post_xol(struct arch_uprobe *auprobe, struct pt_regs *regs) 7274784081SGuo Ren { 7374784081SGuo Ren struct uprobe_task *utask = current->utask; 7474784081SGuo Ren 7574784081SGuo Ren WARN_ON_ONCE(current->thread.bad_cause != UPROBE_TRAP_NR); 7658b1294dSTiezhu Yang current->thread.bad_cause = utask->autask.saved_cause; 7774784081SGuo Ren 7874784081SGuo Ren instruction_pointer_set(regs, utask->vaddr + auprobe->insn_size); 7974784081SGuo Ren 8074784081SGuo Ren return 0; 8174784081SGuo Ren } 8274784081SGuo Ren 8374784081SGuo Ren bool arch_uprobe_xol_was_trapped(struct task_struct *t) 8474784081SGuo Ren { 8574784081SGuo Ren if (t->thread.bad_cause != UPROBE_TRAP_NR) 8674784081SGuo Ren return true; 8774784081SGuo Ren 8874784081SGuo Ren return false; 8974784081SGuo Ren } 9074784081SGuo Ren 9174784081SGuo Ren bool arch_uprobe_skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs) 9274784081SGuo Ren { 9374784081SGuo Ren probe_opcode_t insn; 9474784081SGuo Ren unsigned long addr; 9574784081SGuo Ren 9674784081SGuo Ren if (!auprobe->simulate) 9774784081SGuo Ren return false; 9874784081SGuo Ren 9974784081SGuo Ren insn = *(probe_opcode_t *)(&auprobe->insn[0]); 10074784081SGuo Ren addr = instruction_pointer(regs); 10174784081SGuo Ren 10274784081SGuo Ren if (auprobe->api.handler) 10374784081SGuo Ren auprobe->api.handler(insn, addr, regs); 10474784081SGuo Ren 10574784081SGuo Ren return true; 10674784081SGuo Ren } 10774784081SGuo Ren 10874784081SGuo Ren void arch_uprobe_abort_xol(struct arch_uprobe *auprobe, struct pt_regs *regs) 10974784081SGuo Ren { 11074784081SGuo Ren struct uprobe_task *utask = current->utask; 11174784081SGuo Ren 11258b1294dSTiezhu Yang current->thread.bad_cause = utask->autask.saved_cause; 11374784081SGuo Ren /* 11474784081SGuo Ren * Task has received a fatal signal, so reset back to probbed 11574784081SGuo Ren * address. 11674784081SGuo Ren */ 11774784081SGuo Ren instruction_pointer_set(regs, utask->vaddr); 11874784081SGuo Ren } 11974784081SGuo Ren 12074784081SGuo Ren bool arch_uretprobe_is_alive(struct return_instance *ret, enum rp_check ctx, 12174784081SGuo Ren struct pt_regs *regs) 12274784081SGuo Ren { 12374784081SGuo Ren if (ctx == RP_CHECK_CHAIN_CALL) 12474784081SGuo Ren return regs->sp <= ret->stack; 12574784081SGuo Ren else 12674784081SGuo Ren return regs->sp < ret->stack; 12774784081SGuo Ren } 12874784081SGuo Ren 12974784081SGuo Ren unsigned long 13074784081SGuo Ren arch_uretprobe_hijack_return_addr(unsigned long trampoline_vaddr, 13174784081SGuo Ren struct pt_regs *regs) 13274784081SGuo Ren { 13374784081SGuo Ren unsigned long ra; 13474784081SGuo Ren 13574784081SGuo Ren ra = regs->ra; 13674784081SGuo Ren 13774784081SGuo Ren regs->ra = trampoline_vaddr; 13874784081SGuo Ren 13974784081SGuo Ren return ra; 14074784081SGuo Ren } 14174784081SGuo Ren 14274784081SGuo Ren int arch_uprobe_exception_notify(struct notifier_block *self, 14374784081SGuo Ren unsigned long val, void *data) 14474784081SGuo Ren { 14574784081SGuo Ren return NOTIFY_DONE; 14674784081SGuo Ren } 14774784081SGuo Ren 14874784081SGuo Ren bool uprobe_breakpoint_handler(struct pt_regs *regs) 14974784081SGuo Ren { 15074784081SGuo Ren if (uprobe_pre_sstep_notifier(regs)) 15174784081SGuo Ren return true; 15274784081SGuo Ren 15374784081SGuo Ren return false; 15474784081SGuo Ren } 15574784081SGuo Ren 15674784081SGuo Ren bool uprobe_single_step_handler(struct pt_regs *regs) 15774784081SGuo Ren { 15874784081SGuo Ren if (uprobe_post_sstep_notifier(regs)) 15974784081SGuo Ren return true; 16074784081SGuo Ren 16174784081SGuo Ren return false; 16274784081SGuo Ren } 16374784081SGuo Ren 16474784081SGuo Ren void arch_uprobe_copy_ixol(struct page *page, unsigned long vaddr, 16574784081SGuo Ren void *src, unsigned long len) 16674784081SGuo Ren { 16774784081SGuo Ren /* Initialize the slot */ 16874784081SGuo Ren void *kaddr = kmap_atomic(page); 16974784081SGuo Ren void *dst = kaddr + (vaddr & ~PAGE_MASK); 17074784081SGuo Ren 17174784081SGuo Ren memcpy(dst, src, len); 17274784081SGuo Ren 17374784081SGuo Ren /* Add ebreak behind opcode to simulate singlestep */ 17474784081SGuo Ren if (vaddr) { 17574784081SGuo Ren dst += GET_INSN_LENGTH(*(probe_opcode_t *)src); 17674784081SGuo Ren *(uprobe_opcode_t *)dst = __BUG_INSN_32; 17774784081SGuo Ren } 17874784081SGuo Ren 17974784081SGuo Ren kunmap_atomic(kaddr); 18074784081SGuo Ren 18174784081SGuo Ren /* 18274784081SGuo Ren * We probably need flush_icache_user_page() but it needs vma. 18374784081SGuo Ren * This should work on most of architectures by default. If 18474784081SGuo Ren * architecture needs to do something different it can define 18574784081SGuo Ren * its own version of the function. 18674784081SGuo Ren */ 18774784081SGuo Ren flush_dcache_page(page); 18874784081SGuo Ren } 189