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 136*59a783dbSHelge Deller if (!p) 137*59a783dbSHelge Deller return 0; 138*59a783dbSHelge Deller 1398858ac8eSSven Schnelle if (regs->iaoq[0] != (unsigned long)p->ainsn.insn+4) 1408858ac8eSSven Schnelle return 0; 1418858ac8eSSven Schnelle 1428858ac8eSSven Schnelle /* restore back original saved kprobe variables and continue */ 1438858ac8eSSven Schnelle if (kcb->kprobe_status == KPROBE_REENTER) { 1448858ac8eSSven Schnelle restore_previous_kprobe(kcb); 1458858ac8eSSven Schnelle return 1; 1468858ac8eSSven Schnelle } 1478858ac8eSSven Schnelle 1488858ac8eSSven Schnelle /* for absolute branch instructions we can copy iaoq_b. for relative 1498858ac8eSSven Schnelle * branch instructions we need to calculate the new address based on the 1508858ac8eSSven Schnelle * difference between iaoq_f and iaoq_b. We cannot use iaoq_b without 1518858ac8eSSven Schnelle * modificationt because it's based on our ainsn.insn address. 1528858ac8eSSven Schnelle */ 1538858ac8eSSven Schnelle 1548858ac8eSSven Schnelle if (p->post_handler) 1558858ac8eSSven Schnelle p->post_handler(p, regs, 0); 1568858ac8eSSven Schnelle 1578858ac8eSSven Schnelle switch (regs->iir >> 26) { 1588858ac8eSSven Schnelle case 0x38: /* BE */ 1598858ac8eSSven Schnelle case 0x39: /* BE,L */ 1608858ac8eSSven Schnelle case 0x3a: /* BV */ 1618858ac8eSSven Schnelle case 0x3b: /* BVE */ 1628858ac8eSSven Schnelle /* for absolute branches, regs->iaoq[1] has already the right 1638858ac8eSSven Schnelle * address 1648858ac8eSSven Schnelle */ 1658858ac8eSSven Schnelle regs->iaoq[0] = kcb->iaoq[1]; 1668858ac8eSSven Schnelle break; 1678858ac8eSSven Schnelle default: 1688858ac8eSSven Schnelle regs->iaoq[1] = kcb->iaoq[0]; 1698858ac8eSSven Schnelle regs->iaoq[1] += (regs->iaoq[1] - regs->iaoq[0]) + 4; 1708858ac8eSSven Schnelle regs->iaoq[0] = kcb->iaoq[1]; 1718858ac8eSSven Schnelle break; 1728858ac8eSSven Schnelle } 1738858ac8eSSven Schnelle kcb->kprobe_status = KPROBE_HIT_SSDONE; 1748858ac8eSSven Schnelle reset_current_kprobe(); 1758858ac8eSSven Schnelle return 1; 1768858ac8eSSven Schnelle } 1778858ac8eSSven Schnelle 178e0b59b7bSSven Schnelle static inline void kretprobe_trampoline(void) 179e0b59b7bSSven Schnelle { 180e0b59b7bSSven Schnelle asm volatile("nop"); 181e0b59b7bSSven Schnelle asm volatile("nop"); 182e0b59b7bSSven Schnelle } 183e0b59b7bSSven Schnelle 184e0b59b7bSSven Schnelle static int __kprobes trampoline_probe_handler(struct kprobe *p, 185e0b59b7bSSven Schnelle struct pt_regs *regs); 186e0b59b7bSSven Schnelle 187e0b59b7bSSven Schnelle static struct kprobe trampoline_p = { 188e0b59b7bSSven Schnelle .pre_handler = trampoline_probe_handler 189e0b59b7bSSven Schnelle }; 190e0b59b7bSSven Schnelle 191e0b59b7bSSven Schnelle static int __kprobes trampoline_probe_handler(struct kprobe *p, 192e0b59b7bSSven Schnelle struct pt_regs *regs) 193e0b59b7bSSven Schnelle { 194e0b59b7bSSven Schnelle struct kretprobe_instance *ri = NULL; 195e0b59b7bSSven Schnelle struct hlist_head *head, empty_rp; 196e0b59b7bSSven Schnelle struct hlist_node *tmp; 197e0b59b7bSSven Schnelle unsigned long flags, orig_ret_address = 0; 198e0b59b7bSSven Schnelle unsigned long trampoline_address = (unsigned long)trampoline_p.addr; 199e0b59b7bSSven Schnelle kprobe_opcode_t *correct_ret_addr = NULL; 200e0b59b7bSSven Schnelle 201e0b59b7bSSven Schnelle INIT_HLIST_HEAD(&empty_rp); 202e0b59b7bSSven Schnelle kretprobe_hash_lock(current, &head, &flags); 203e0b59b7bSSven Schnelle 204e0b59b7bSSven Schnelle /* 205e0b59b7bSSven Schnelle * It is possible to have multiple instances associated with a given 206e0b59b7bSSven Schnelle * task either because multiple functions in the call path have 207e0b59b7bSSven Schnelle * a return probe installed on them, and/or more than one return 208e0b59b7bSSven Schnelle * probe was registered for a target function. 209e0b59b7bSSven Schnelle * 210e0b59b7bSSven Schnelle * We can handle this because: 211e0b59b7bSSven Schnelle * - instances are always inserted at the head of the list 212e0b59b7bSSven Schnelle * - when multiple return probes are registered for the same 213e0b59b7bSSven Schnelle * function, the first instance's ret_addr will point to the 214e0b59b7bSSven Schnelle * real return address, and all the rest will point to 215e0b59b7bSSven Schnelle * kretprobe_trampoline 216e0b59b7bSSven Schnelle */ 217e0b59b7bSSven Schnelle hlist_for_each_entry_safe(ri, tmp, head, hlist) { 218e0b59b7bSSven Schnelle if (ri->task != current) 219e0b59b7bSSven Schnelle /* another task is sharing our hash bucket */ 220e0b59b7bSSven Schnelle continue; 221e0b59b7bSSven Schnelle 222e0b59b7bSSven Schnelle orig_ret_address = (unsigned long)ri->ret_addr; 223e0b59b7bSSven Schnelle 224e0b59b7bSSven Schnelle if (orig_ret_address != trampoline_address) 225e0b59b7bSSven Schnelle /* 226e0b59b7bSSven Schnelle * This is the real return address. Any other 227e0b59b7bSSven Schnelle * instances associated with this task are for 228e0b59b7bSSven Schnelle * other calls deeper on the call stack 229e0b59b7bSSven Schnelle */ 230e0b59b7bSSven Schnelle break; 231e0b59b7bSSven Schnelle } 232e0b59b7bSSven Schnelle 233e0b59b7bSSven Schnelle kretprobe_assert(ri, orig_ret_address, trampoline_address); 234e0b59b7bSSven Schnelle 235e0b59b7bSSven Schnelle correct_ret_addr = ri->ret_addr; 236e0b59b7bSSven Schnelle hlist_for_each_entry_safe(ri, tmp, head, hlist) { 237e0b59b7bSSven Schnelle if (ri->task != current) 238e0b59b7bSSven Schnelle /* another task is sharing our hash bucket */ 239e0b59b7bSSven Schnelle continue; 240e0b59b7bSSven Schnelle 241e0b59b7bSSven Schnelle orig_ret_address = (unsigned long)ri->ret_addr; 242e0b59b7bSSven Schnelle if (ri->rp && ri->rp->handler) { 243e0b59b7bSSven Schnelle __this_cpu_write(current_kprobe, &ri->rp->kp); 244e0b59b7bSSven Schnelle get_kprobe_ctlblk()->kprobe_status = KPROBE_HIT_ACTIVE; 245e0b59b7bSSven Schnelle ri->ret_addr = correct_ret_addr; 246e0b59b7bSSven Schnelle ri->rp->handler(ri, regs); 247e0b59b7bSSven Schnelle __this_cpu_write(current_kprobe, NULL); 248e0b59b7bSSven Schnelle } 249e0b59b7bSSven Schnelle 250e0b59b7bSSven Schnelle recycle_rp_inst(ri, &empty_rp); 251e0b59b7bSSven Schnelle 252e0b59b7bSSven Schnelle if (orig_ret_address != trampoline_address) 253e0b59b7bSSven Schnelle /* 254e0b59b7bSSven Schnelle * This is the real return address. Any other 255e0b59b7bSSven Schnelle * instances associated with this task are for 256e0b59b7bSSven Schnelle * other calls deeper on the call stack 257e0b59b7bSSven Schnelle */ 258e0b59b7bSSven Schnelle break; 259e0b59b7bSSven Schnelle } 260e0b59b7bSSven Schnelle 261e0b59b7bSSven Schnelle kretprobe_hash_unlock(current, &flags); 262e0b59b7bSSven Schnelle 263e0b59b7bSSven Schnelle hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) { 264e0b59b7bSSven Schnelle hlist_del(&ri->hlist); 265e0b59b7bSSven Schnelle kfree(ri); 266e0b59b7bSSven Schnelle } 267e0b59b7bSSven Schnelle instruction_pointer_set(regs, orig_ret_address); 268e0b59b7bSSven Schnelle return 1; 269e0b59b7bSSven Schnelle } 270e0b59b7bSSven Schnelle 271e0b59b7bSSven Schnelle void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri, 272e0b59b7bSSven Schnelle struct pt_regs *regs) 273e0b59b7bSSven Schnelle { 274e0b59b7bSSven Schnelle ri->ret_addr = (kprobe_opcode_t *)regs->gr[2]; 275e0b59b7bSSven Schnelle 276e0b59b7bSSven Schnelle /* Replace the return addr with trampoline addr. */ 277e0b59b7bSSven Schnelle regs->gr[2] = (unsigned long)trampoline_p.addr; 278e0b59b7bSSven Schnelle } 279e0b59b7bSSven Schnelle 280e0b59b7bSSven Schnelle int __kprobes arch_trampoline_kprobe(struct kprobe *p) 281e0b59b7bSSven Schnelle { 282e0b59b7bSSven Schnelle return p->addr == trampoline_p.addr; 283e0b59b7bSSven Schnelle } 2848858ac8eSSven Schnelle bool arch_kprobe_on_func_entry(unsigned long offset) 2858858ac8eSSven Schnelle { 2868858ac8eSSven Schnelle return !offset; 2878858ac8eSSven Schnelle } 2888858ac8eSSven Schnelle 2898858ac8eSSven Schnelle int __init arch_init_kprobes(void) 2908858ac8eSSven Schnelle { 291e0b59b7bSSven Schnelle trampoline_p.addr = (kprobe_opcode_t *) 292e0b59b7bSSven Schnelle dereference_function_descriptor(kretprobe_trampoline); 293e0b59b7bSSven Schnelle return register_kprobe(&trampoline_p); 2948858ac8eSSven Schnelle } 295