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
is_swbp_insn(uprobe_opcode_t * insn)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
is_trap_insn(uprobe_opcode_t * insn)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
uprobe_get_swbp_addr(struct pt_regs * regs)2674784081SGuo Ren unsigned long uprobe_get_swbp_addr(struct pt_regs *regs)
2774784081SGuo Ren {
2874784081SGuo Ren return instruction_pointer(regs);
2974784081SGuo Ren }
3074784081SGuo Ren
arch_uprobe_analyze_insn(struct arch_uprobe * auprobe,struct mm_struct * mm,unsigned long addr)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
arch_uprobe_pre_xol(struct arch_uprobe * auprobe,struct pt_regs * regs)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
arch_uprobe_post_xol(struct arch_uprobe * auprobe,struct pt_regs * regs)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
arch_uprobe_xol_was_trapped(struct task_struct * t)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
arch_uprobe_skip_sstep(struct arch_uprobe * auprobe,struct pt_regs * regs)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
arch_uprobe_abort_xol(struct arch_uprobe * auprobe,struct pt_regs * regs)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
arch_uretprobe_is_alive(struct return_instance * ret,enum rp_check ctx,struct pt_regs * regs)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
arch_uretprobe_hijack_return_addr(unsigned long trampoline_vaddr,struct pt_regs * regs)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
arch_uprobe_exception_notify(struct notifier_block * self,unsigned long val,void * data)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
uprobe_breakpoint_handler(struct pt_regs * regs)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
uprobe_single_step_handler(struct pt_regs * regs)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
arch_uprobe_copy_ixol(struct page * page,unsigned long vaddr,void * src,unsigned long len)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