1 // SPDX-License-Identifier: GPL-2.0-only 2 3 #include <linux/highmem.h> 4 #include <linux/ptrace.h> 5 #include <linux/uprobes.h> 6 #include <asm/insn.h> 7 8 #include "decode-insn.h" 9 10 #define UPROBE_TRAP_NR UINT_MAX 11 12 bool is_swbp_insn(uprobe_opcode_t *insn) 13 { 14 #ifdef CONFIG_RISCV_ISA_C 15 return (*insn & 0xffff) == UPROBE_SWBP_INSN; 16 #else 17 return *insn == UPROBE_SWBP_INSN; 18 #endif 19 } 20 21 bool is_trap_insn(uprobe_opcode_t *insn) 22 { 23 return riscv_insn_is_ebreak(*insn) || riscv_insn_is_c_ebreak(*insn); 24 } 25 26 unsigned long uprobe_get_swbp_addr(struct pt_regs *regs) 27 { 28 return instruction_pointer(regs); 29 } 30 31 int arch_uprobe_analyze_insn(struct arch_uprobe *auprobe, struct mm_struct *mm, 32 unsigned long addr) 33 { 34 probe_opcode_t opcode; 35 36 opcode = *(probe_opcode_t *)(&auprobe->insn[0]); 37 38 auprobe->insn_size = GET_INSN_LENGTH(opcode); 39 40 switch (riscv_probe_decode_insn(&opcode, &auprobe->api)) { 41 case INSN_REJECTED: 42 return -EINVAL; 43 44 case INSN_GOOD_NO_SLOT: 45 auprobe->simulate = true; 46 break; 47 48 case INSN_GOOD: 49 auprobe->simulate = false; 50 break; 51 52 default: 53 return -EINVAL; 54 } 55 56 return 0; 57 } 58 59 int arch_uprobe_pre_xol(struct arch_uprobe *auprobe, struct pt_regs *regs) 60 { 61 struct uprobe_task *utask = current->utask; 62 63 utask->autask.saved_cause = current->thread.bad_cause; 64 current->thread.bad_cause = UPROBE_TRAP_NR; 65 66 instruction_pointer_set(regs, utask->xol_vaddr); 67 68 return 0; 69 } 70 71 int arch_uprobe_post_xol(struct arch_uprobe *auprobe, struct pt_regs *regs) 72 { 73 struct uprobe_task *utask = current->utask; 74 75 WARN_ON_ONCE(current->thread.bad_cause != UPROBE_TRAP_NR); 76 current->thread.bad_cause = utask->autask.saved_cause; 77 78 instruction_pointer_set(regs, utask->vaddr + auprobe->insn_size); 79 80 return 0; 81 } 82 83 bool arch_uprobe_xol_was_trapped(struct task_struct *t) 84 { 85 if (t->thread.bad_cause != UPROBE_TRAP_NR) 86 return true; 87 88 return false; 89 } 90 91 bool arch_uprobe_skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs) 92 { 93 probe_opcode_t insn; 94 unsigned long addr; 95 96 if (!auprobe->simulate) 97 return false; 98 99 insn = *(probe_opcode_t *)(&auprobe->insn[0]); 100 addr = instruction_pointer(regs); 101 102 if (auprobe->api.handler) 103 auprobe->api.handler(insn, addr, regs); 104 105 return true; 106 } 107 108 void arch_uprobe_abort_xol(struct arch_uprobe *auprobe, struct pt_regs *regs) 109 { 110 struct uprobe_task *utask = current->utask; 111 112 current->thread.bad_cause = utask->autask.saved_cause; 113 /* 114 * Task has received a fatal signal, so reset back to probbed 115 * address. 116 */ 117 instruction_pointer_set(regs, utask->vaddr); 118 } 119 120 bool arch_uretprobe_is_alive(struct return_instance *ret, enum rp_check ctx, 121 struct pt_regs *regs) 122 { 123 if (ctx == RP_CHECK_CHAIN_CALL) 124 return regs->sp <= ret->stack; 125 else 126 return regs->sp < ret->stack; 127 } 128 129 unsigned long 130 arch_uretprobe_hijack_return_addr(unsigned long trampoline_vaddr, 131 struct pt_regs *regs) 132 { 133 unsigned long ra; 134 135 ra = regs->ra; 136 137 regs->ra = trampoline_vaddr; 138 139 return ra; 140 } 141 142 int arch_uprobe_exception_notify(struct notifier_block *self, 143 unsigned long val, void *data) 144 { 145 return NOTIFY_DONE; 146 } 147 148 bool uprobe_breakpoint_handler(struct pt_regs *regs) 149 { 150 if (uprobe_pre_sstep_notifier(regs)) 151 return true; 152 153 return false; 154 } 155 156 bool uprobe_single_step_handler(struct pt_regs *regs) 157 { 158 if (uprobe_post_sstep_notifier(regs)) 159 return true; 160 161 return false; 162 } 163 164 void arch_uprobe_copy_ixol(struct page *page, unsigned long vaddr, 165 void *src, unsigned long len) 166 { 167 /* Initialize the slot */ 168 void *kaddr = kmap_atomic(page); 169 void *dst = kaddr + (vaddr & ~PAGE_MASK); 170 171 memcpy(dst, src, len); 172 173 /* Add ebreak behind opcode to simulate singlestep */ 174 if (vaddr) { 175 dst += GET_INSN_LENGTH(*(probe_opcode_t *)src); 176 *(uprobe_opcode_t *)dst = __BUG_INSN_32; 177 } 178 179 kunmap_atomic(kaddr); 180 181 /* 182 * We probably need flush_icache_user_page() but it needs vma. 183 * This should work on most of architectures by default. If 184 * architecture needs to do something different it can define 185 * its own version of the function. 186 */ 187 flush_dcache_page(page); 188 } 189