18858ac8eSSven Schnelle // SPDX-License-Identifier: GPL-2.0 28858ac8eSSven Schnelle /* 38858ac8eSSven Schnelle * arch/parisc/kernel/kprobes.c 48858ac8eSSven Schnelle * 58858ac8eSSven Schnelle * PA-RISC kprobes implementation 68858ac8eSSven Schnelle * 78858ac8eSSven Schnelle * Copyright (c) 2019 Sven Schnelle <svens@stackframe.org> 88858ac8eSSven Schnelle */ 98858ac8eSSven Schnelle 108858ac8eSSven Schnelle #include <linux/types.h> 118858ac8eSSven Schnelle #include <linux/kprobes.h> 128858ac8eSSven Schnelle #include <linux/slab.h> 138858ac8eSSven Schnelle #include <asm/cacheflush.h> 148858ac8eSSven Schnelle #include <asm/patch.h> 158858ac8eSSven Schnelle 168858ac8eSSven Schnelle DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL; 178858ac8eSSven Schnelle DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); 188858ac8eSSven Schnelle 198858ac8eSSven Schnelle int __kprobes arch_prepare_kprobe(struct kprobe *p) 208858ac8eSSven Schnelle { 218858ac8eSSven Schnelle if ((unsigned long)p->addr & 3UL) 228858ac8eSSven Schnelle return -EINVAL; 238858ac8eSSven Schnelle 248858ac8eSSven Schnelle p->ainsn.insn = get_insn_slot(); 258858ac8eSSven Schnelle if (!p->ainsn.insn) 268858ac8eSSven Schnelle return -ENOMEM; 278858ac8eSSven Schnelle 288858ac8eSSven Schnelle memcpy(p->ainsn.insn, p->addr, 298858ac8eSSven Schnelle MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); 308858ac8eSSven Schnelle p->opcode = *p->addr; 318858ac8eSSven Schnelle flush_insn_slot(p); 328858ac8eSSven Schnelle return 0; 338858ac8eSSven Schnelle } 348858ac8eSSven Schnelle 358858ac8eSSven Schnelle void __kprobes arch_remove_kprobe(struct kprobe *p) 368858ac8eSSven Schnelle { 378858ac8eSSven Schnelle if (!p->ainsn.insn) 388858ac8eSSven Schnelle return; 398858ac8eSSven Schnelle 408858ac8eSSven Schnelle free_insn_slot(p->ainsn.insn, 0); 418858ac8eSSven Schnelle p->ainsn.insn = NULL; 428858ac8eSSven Schnelle } 438858ac8eSSven Schnelle 448858ac8eSSven Schnelle void __kprobes arch_arm_kprobe(struct kprobe *p) 458858ac8eSSven Schnelle { 468858ac8eSSven Schnelle patch_text(p->addr, PARISC_KPROBES_BREAK_INSN); 478858ac8eSSven Schnelle } 488858ac8eSSven Schnelle 498858ac8eSSven Schnelle void __kprobes arch_disarm_kprobe(struct kprobe *p) 508858ac8eSSven Schnelle { 518858ac8eSSven Schnelle patch_text(p->addr, p->opcode); 528858ac8eSSven Schnelle } 538858ac8eSSven Schnelle 548858ac8eSSven Schnelle static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb) 558858ac8eSSven Schnelle { 568858ac8eSSven Schnelle kcb->prev_kprobe.kp = kprobe_running(); 578858ac8eSSven Schnelle kcb->prev_kprobe.status = kcb->kprobe_status; 588858ac8eSSven Schnelle } 598858ac8eSSven Schnelle 608858ac8eSSven Schnelle static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb) 618858ac8eSSven Schnelle { 628858ac8eSSven Schnelle __this_cpu_write(current_kprobe, kcb->prev_kprobe.kp); 638858ac8eSSven Schnelle kcb->kprobe_status = kcb->prev_kprobe.status; 648858ac8eSSven Schnelle } 658858ac8eSSven Schnelle 668858ac8eSSven Schnelle static inline void __kprobes set_current_kprobe(struct kprobe *p) 678858ac8eSSven Schnelle { 688858ac8eSSven Schnelle __this_cpu_write(current_kprobe, p); 698858ac8eSSven Schnelle } 708858ac8eSSven Schnelle 718858ac8eSSven Schnelle static void __kprobes setup_singlestep(struct kprobe *p, 728858ac8eSSven Schnelle struct kprobe_ctlblk *kcb, struct pt_regs *regs) 738858ac8eSSven Schnelle { 748858ac8eSSven Schnelle kcb->iaoq[0] = regs->iaoq[0]; 758858ac8eSSven Schnelle kcb->iaoq[1] = regs->iaoq[1]; 768858ac8eSSven Schnelle regs->iaoq[0] = (unsigned long)p->ainsn.insn; 778858ac8eSSven Schnelle mtctl(0, 0); 788858ac8eSSven Schnelle regs->gr[0] |= PSW_R; 798858ac8eSSven Schnelle } 808858ac8eSSven Schnelle 818858ac8eSSven Schnelle int __kprobes parisc_kprobe_break_handler(struct pt_regs *regs) 828858ac8eSSven Schnelle { 838858ac8eSSven Schnelle struct kprobe *p; 848858ac8eSSven Schnelle struct kprobe_ctlblk *kcb; 858858ac8eSSven Schnelle 868858ac8eSSven Schnelle preempt_disable(); 878858ac8eSSven Schnelle 888858ac8eSSven Schnelle kcb = get_kprobe_ctlblk(); 898858ac8eSSven Schnelle p = get_kprobe((unsigned long *)regs->iaoq[0]); 908858ac8eSSven Schnelle 918858ac8eSSven Schnelle if (!p) { 928858ac8eSSven Schnelle preempt_enable_no_resched(); 938858ac8eSSven Schnelle return 0; 948858ac8eSSven Schnelle } 958858ac8eSSven Schnelle 968858ac8eSSven Schnelle if (kprobe_running()) { 978858ac8eSSven Schnelle /* 988858ac8eSSven Schnelle * We have reentered the kprobe_handler, since another kprobe 998858ac8eSSven Schnelle * was hit while within the handler, we save the original 1008858ac8eSSven Schnelle * kprobes and single step on the instruction of the new probe 1018858ac8eSSven Schnelle * without calling any user handlers to avoid recursive 1028858ac8eSSven Schnelle * kprobes. 1038858ac8eSSven Schnelle */ 1048858ac8eSSven Schnelle save_previous_kprobe(kcb); 1058858ac8eSSven Schnelle set_current_kprobe(p); 1068858ac8eSSven Schnelle kprobes_inc_nmissed_count(p); 1078858ac8eSSven Schnelle setup_singlestep(p, kcb, regs); 1088858ac8eSSven Schnelle kcb->kprobe_status = KPROBE_REENTER; 1098858ac8eSSven Schnelle return 1; 1108858ac8eSSven Schnelle } 1118858ac8eSSven Schnelle 1128858ac8eSSven Schnelle set_current_kprobe(p); 1138858ac8eSSven Schnelle kcb->kprobe_status = KPROBE_HIT_ACTIVE; 1148858ac8eSSven Schnelle 1158858ac8eSSven Schnelle /* If we have no pre-handler or it returned 0, we continue with 1168858ac8eSSven Schnelle * normal processing. If we have a pre-handler and it returned 1178858ac8eSSven Schnelle * non-zero - which means user handler setup registers to exit 1188858ac8eSSven Schnelle * to another instruction, we must skip the single stepping. 1198858ac8eSSven Schnelle */ 1208858ac8eSSven Schnelle 1218858ac8eSSven Schnelle if (!p->pre_handler || !p->pre_handler(p, regs)) { 1228858ac8eSSven Schnelle setup_singlestep(p, kcb, regs); 1238858ac8eSSven Schnelle kcb->kprobe_status = KPROBE_HIT_SS; 1248858ac8eSSven Schnelle } else { 1258858ac8eSSven Schnelle reset_current_kprobe(); 1268858ac8eSSven Schnelle preempt_enable_no_resched(); 1278858ac8eSSven Schnelle } 1288858ac8eSSven Schnelle return 1; 1298858ac8eSSven Schnelle } 1308858ac8eSSven Schnelle 1318858ac8eSSven Schnelle int __kprobes parisc_kprobe_ss_handler(struct pt_regs *regs) 1328858ac8eSSven Schnelle { 1338858ac8eSSven Schnelle struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); 1348858ac8eSSven Schnelle struct kprobe *p = kprobe_running(); 1358858ac8eSSven Schnelle 1368858ac8eSSven Schnelle if (regs->iaoq[0] != (unsigned long)p->ainsn.insn+4) 1378858ac8eSSven Schnelle return 0; 1388858ac8eSSven Schnelle 1398858ac8eSSven Schnelle /* restore back original saved kprobe variables and continue */ 1408858ac8eSSven Schnelle if (kcb->kprobe_status == KPROBE_REENTER) { 1418858ac8eSSven Schnelle restore_previous_kprobe(kcb); 1428858ac8eSSven Schnelle return 1; 1438858ac8eSSven Schnelle } 1448858ac8eSSven Schnelle 1458858ac8eSSven Schnelle /* for absolute branch instructions we can copy iaoq_b. for relative 1468858ac8eSSven Schnelle * branch instructions we need to calculate the new address based on the 1478858ac8eSSven Schnelle * difference between iaoq_f and iaoq_b. We cannot use iaoq_b without 1488858ac8eSSven Schnelle * modificationt because it's based on our ainsn.insn address. 1498858ac8eSSven Schnelle */ 1508858ac8eSSven Schnelle 1518858ac8eSSven Schnelle if (p->post_handler) 1528858ac8eSSven Schnelle p->post_handler(p, regs, 0); 1538858ac8eSSven Schnelle 1548858ac8eSSven Schnelle switch (regs->iir >> 26) { 1558858ac8eSSven Schnelle case 0x38: /* BE */ 1568858ac8eSSven Schnelle case 0x39: /* BE,L */ 1578858ac8eSSven Schnelle case 0x3a: /* BV */ 1588858ac8eSSven Schnelle case 0x3b: /* BVE */ 1598858ac8eSSven Schnelle /* for absolute branches, regs->iaoq[1] has already the right 1608858ac8eSSven Schnelle * address 1618858ac8eSSven Schnelle */ 1628858ac8eSSven Schnelle regs->iaoq[0] = kcb->iaoq[1]; 1638858ac8eSSven Schnelle break; 1648858ac8eSSven Schnelle default: 1658858ac8eSSven Schnelle regs->iaoq[1] = kcb->iaoq[0]; 1668858ac8eSSven Schnelle regs->iaoq[1] += (regs->iaoq[1] - regs->iaoq[0]) + 4; 1678858ac8eSSven Schnelle regs->iaoq[0] = kcb->iaoq[1]; 1688858ac8eSSven Schnelle break; 1698858ac8eSSven Schnelle } 1708858ac8eSSven Schnelle kcb->kprobe_status = KPROBE_HIT_SSDONE; 1718858ac8eSSven Schnelle reset_current_kprobe(); 1728858ac8eSSven Schnelle return 1; 1738858ac8eSSven Schnelle } 1748858ac8eSSven Schnelle 175*e0b59b7bSSven Schnelle static inline void kretprobe_trampoline(void) 176*e0b59b7bSSven Schnelle { 177*e0b59b7bSSven Schnelle asm volatile("nop"); 178*e0b59b7bSSven Schnelle asm volatile("nop"); 179*e0b59b7bSSven Schnelle } 180*e0b59b7bSSven Schnelle 181*e0b59b7bSSven Schnelle static int __kprobes trampoline_probe_handler(struct kprobe *p, 182*e0b59b7bSSven Schnelle struct pt_regs *regs); 183*e0b59b7bSSven Schnelle 184*e0b59b7bSSven Schnelle static struct kprobe trampoline_p = { 185*e0b59b7bSSven Schnelle .pre_handler = trampoline_probe_handler 186*e0b59b7bSSven Schnelle }; 187*e0b59b7bSSven Schnelle 188*e0b59b7bSSven Schnelle static int __kprobes trampoline_probe_handler(struct kprobe *p, 189*e0b59b7bSSven Schnelle struct pt_regs *regs) 190*e0b59b7bSSven Schnelle { 191*e0b59b7bSSven Schnelle struct kretprobe_instance *ri = NULL; 192*e0b59b7bSSven Schnelle struct hlist_head *head, empty_rp; 193*e0b59b7bSSven Schnelle struct hlist_node *tmp; 194*e0b59b7bSSven Schnelle unsigned long flags, orig_ret_address = 0; 195*e0b59b7bSSven Schnelle unsigned long trampoline_address = (unsigned long)trampoline_p.addr; 196*e0b59b7bSSven Schnelle kprobe_opcode_t *correct_ret_addr = NULL; 197*e0b59b7bSSven Schnelle 198*e0b59b7bSSven Schnelle INIT_HLIST_HEAD(&empty_rp); 199*e0b59b7bSSven Schnelle kretprobe_hash_lock(current, &head, &flags); 200*e0b59b7bSSven Schnelle 201*e0b59b7bSSven Schnelle /* 202*e0b59b7bSSven Schnelle * It is possible to have multiple instances associated with a given 203*e0b59b7bSSven Schnelle * task either because multiple functions in the call path have 204*e0b59b7bSSven Schnelle * a return probe installed on them, and/or more than one return 205*e0b59b7bSSven Schnelle * probe was registered for a target function. 206*e0b59b7bSSven Schnelle * 207*e0b59b7bSSven Schnelle * We can handle this because: 208*e0b59b7bSSven Schnelle * - instances are always inserted at the head of the list 209*e0b59b7bSSven Schnelle * - when multiple return probes are registered for the same 210*e0b59b7bSSven Schnelle * function, the first instance's ret_addr will point to the 211*e0b59b7bSSven Schnelle * real return address, and all the rest will point to 212*e0b59b7bSSven Schnelle * kretprobe_trampoline 213*e0b59b7bSSven Schnelle */ 214*e0b59b7bSSven Schnelle hlist_for_each_entry_safe(ri, tmp, head, hlist) { 215*e0b59b7bSSven Schnelle if (ri->task != current) 216*e0b59b7bSSven Schnelle /* another task is sharing our hash bucket */ 217*e0b59b7bSSven Schnelle continue; 218*e0b59b7bSSven Schnelle 219*e0b59b7bSSven Schnelle orig_ret_address = (unsigned long)ri->ret_addr; 220*e0b59b7bSSven Schnelle 221*e0b59b7bSSven Schnelle if (orig_ret_address != trampoline_address) 222*e0b59b7bSSven Schnelle /* 223*e0b59b7bSSven Schnelle * This is the real return address. Any other 224*e0b59b7bSSven Schnelle * instances associated with this task are for 225*e0b59b7bSSven Schnelle * other calls deeper on the call stack 226*e0b59b7bSSven Schnelle */ 227*e0b59b7bSSven Schnelle break; 228*e0b59b7bSSven Schnelle } 229*e0b59b7bSSven Schnelle 230*e0b59b7bSSven Schnelle kretprobe_assert(ri, orig_ret_address, trampoline_address); 231*e0b59b7bSSven Schnelle 232*e0b59b7bSSven Schnelle correct_ret_addr = ri->ret_addr; 233*e0b59b7bSSven Schnelle hlist_for_each_entry_safe(ri, tmp, head, hlist) { 234*e0b59b7bSSven Schnelle if (ri->task != current) 235*e0b59b7bSSven Schnelle /* another task is sharing our hash bucket */ 236*e0b59b7bSSven Schnelle continue; 237*e0b59b7bSSven Schnelle 238*e0b59b7bSSven Schnelle orig_ret_address = (unsigned long)ri->ret_addr; 239*e0b59b7bSSven Schnelle if (ri->rp && ri->rp->handler) { 240*e0b59b7bSSven Schnelle __this_cpu_write(current_kprobe, &ri->rp->kp); 241*e0b59b7bSSven Schnelle get_kprobe_ctlblk()->kprobe_status = KPROBE_HIT_ACTIVE; 242*e0b59b7bSSven Schnelle ri->ret_addr = correct_ret_addr; 243*e0b59b7bSSven Schnelle ri->rp->handler(ri, regs); 244*e0b59b7bSSven Schnelle __this_cpu_write(current_kprobe, NULL); 245*e0b59b7bSSven Schnelle } 246*e0b59b7bSSven Schnelle 247*e0b59b7bSSven Schnelle recycle_rp_inst(ri, &empty_rp); 248*e0b59b7bSSven Schnelle 249*e0b59b7bSSven Schnelle if (orig_ret_address != trampoline_address) 250*e0b59b7bSSven Schnelle /* 251*e0b59b7bSSven Schnelle * This is the real return address. Any other 252*e0b59b7bSSven Schnelle * instances associated with this task are for 253*e0b59b7bSSven Schnelle * other calls deeper on the call stack 254*e0b59b7bSSven Schnelle */ 255*e0b59b7bSSven Schnelle break; 256*e0b59b7bSSven Schnelle } 257*e0b59b7bSSven Schnelle 258*e0b59b7bSSven Schnelle kretprobe_hash_unlock(current, &flags); 259*e0b59b7bSSven Schnelle 260*e0b59b7bSSven Schnelle hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) { 261*e0b59b7bSSven Schnelle hlist_del(&ri->hlist); 262*e0b59b7bSSven Schnelle kfree(ri); 263*e0b59b7bSSven Schnelle } 264*e0b59b7bSSven Schnelle instruction_pointer_set(regs, orig_ret_address); 265*e0b59b7bSSven Schnelle return 1; 266*e0b59b7bSSven Schnelle } 267*e0b59b7bSSven Schnelle 268*e0b59b7bSSven Schnelle void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri, 269*e0b59b7bSSven Schnelle struct pt_regs *regs) 270*e0b59b7bSSven Schnelle { 271*e0b59b7bSSven Schnelle ri->ret_addr = (kprobe_opcode_t *)regs->gr[2]; 272*e0b59b7bSSven Schnelle 273*e0b59b7bSSven Schnelle /* Replace the return addr with trampoline addr. */ 274*e0b59b7bSSven Schnelle regs->gr[2] = (unsigned long)trampoline_p.addr; 275*e0b59b7bSSven Schnelle } 276*e0b59b7bSSven Schnelle 277*e0b59b7bSSven Schnelle int __kprobes arch_trampoline_kprobe(struct kprobe *p) 278*e0b59b7bSSven Schnelle { 279*e0b59b7bSSven Schnelle return p->addr == trampoline_p.addr; 280*e0b59b7bSSven Schnelle } 2818858ac8eSSven Schnelle bool arch_kprobe_on_func_entry(unsigned long offset) 2828858ac8eSSven Schnelle { 2838858ac8eSSven Schnelle return !offset; 2848858ac8eSSven Schnelle } 2858858ac8eSSven Schnelle 2868858ac8eSSven Schnelle int __init arch_init_kprobes(void) 2878858ac8eSSven Schnelle { 288*e0b59b7bSSven Schnelle trampoline_p.addr = (kprobe_opcode_t *) 289*e0b59b7bSSven Schnelle dereference_function_descriptor(kretprobe_trampoline); 290*e0b59b7bSSven Schnelle return register_kprobe(&trampoline_p); 2918858ac8eSSven Schnelle } 292