^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Kernel probes (kprobes) for SuperH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2007 Chris Smith <chris.smith@st.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2006 Lineo Solutions, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/kprobes.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/extable.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/ptrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/preempt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/kdebug.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <asm/cacheflush.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) static DEFINE_PER_CPU(struct kprobe, saved_current_opcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) static DEFINE_PER_CPU(struct kprobe, saved_next_opcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) static DEFINE_PER_CPU(struct kprobe, saved_next_opcode2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define OPCODE_JMP(x) (((x) & 0xF0FF) == 0x402b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define OPCODE_JSR(x) (((x) & 0xF0FF) == 0x400b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define OPCODE_BRA(x) (((x) & 0xF000) == 0xa000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define OPCODE_BRAF(x) (((x) & 0xF0FF) == 0x0023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define OPCODE_BSR(x) (((x) & 0xF000) == 0xb000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define OPCODE_BSRF(x) (((x) & 0xF0FF) == 0x0003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define OPCODE_BF_S(x) (((x) & 0xFF00) == 0x8f00)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define OPCODE_BT_S(x) (((x) & 0xFF00) == 0x8d00)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define OPCODE_BF(x) (((x) & 0xFF00) == 0x8b00)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define OPCODE_BT(x) (((x) & 0xFF00) == 0x8900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define OPCODE_RTS(x) (((x) & 0x000F) == 0x000b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define OPCODE_RTE(x) (((x) & 0xFFFF) == 0x002b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) int __kprobes arch_prepare_kprobe(struct kprobe *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) kprobe_opcode_t opcode = *(kprobe_opcode_t *) (p->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) if (OPCODE_RTE(opcode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) return -EFAULT; /* Bad breakpoint */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) p->opcode = opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) void __kprobes arch_copy_kprobe(struct kprobe *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) p->opcode = *p->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) void __kprobes arch_arm_kprobe(struct kprobe *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) *p->addr = BREAKPOINT_INSTRUCTION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) flush_icache_range((unsigned long)p->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) (unsigned long)p->addr + sizeof(kprobe_opcode_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) void __kprobes arch_disarm_kprobe(struct kprobe *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) *p->addr = p->opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) flush_icache_range((unsigned long)p->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) (unsigned long)p->addr + sizeof(kprobe_opcode_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) int __kprobes arch_trampoline_kprobe(struct kprobe *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) if (*p->addr == BREAKPOINT_INSTRUCTION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * If an illegal slot instruction exception occurs for an address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * containing a kprobe, remove the probe.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * Returns 0 if the exception was handled successfully, 1 otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) int __kprobes kprobe_handle_illslot(unsigned long pc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) struct kprobe *p = get_kprobe((kprobe_opcode_t *) pc + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) if (p != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) printk("Warning: removing kprobe from delay slot: 0x%.8x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) (unsigned int)pc + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) unregister_kprobe(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) void __kprobes arch_remove_kprobe(struct kprobe *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) struct kprobe *saved = this_cpu_ptr(&saved_next_opcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) if (saved->addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) arch_disarm_kprobe(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) arch_disarm_kprobe(saved);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) saved->addr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) saved->opcode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) saved = this_cpu_ptr(&saved_next_opcode2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) if (saved->addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) arch_disarm_kprobe(saved);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) saved->addr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) saved->opcode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) kcb->prev_kprobe.kp = kprobe_running();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) kcb->prev_kprobe.status = kcb->kprobe_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) __this_cpu_write(current_kprobe, kcb->prev_kprobe.kp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) kcb->kprobe_status = kcb->prev_kprobe.status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) struct kprobe_ctlblk *kcb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) __this_cpu_write(current_kprobe, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) * Singlestep is implemented by disabling the current kprobe and setting one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * on the next instruction, following branches. Two probes are set if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) * branch is conditional.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) __this_cpu_write(saved_current_opcode.addr, (kprobe_opcode_t *)regs->pc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) if (p != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) struct kprobe *op1, *op2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) arch_disarm_kprobe(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) op1 = this_cpu_ptr(&saved_next_opcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) op2 = this_cpu_ptr(&saved_next_opcode2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) if (OPCODE_JSR(p->opcode) || OPCODE_JMP(p->opcode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) unsigned int reg_nr = ((p->opcode >> 8) & 0x000F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) op1->addr = (kprobe_opcode_t *) regs->regs[reg_nr];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) } else if (OPCODE_BRA(p->opcode) || OPCODE_BSR(p->opcode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) unsigned long disp = (p->opcode & 0x0FFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) op1->addr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) (kprobe_opcode_t *) (regs->pc + 4 + disp * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) } else if (OPCODE_BRAF(p->opcode) || OPCODE_BSRF(p->opcode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) unsigned int reg_nr = ((p->opcode >> 8) & 0x000F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) op1->addr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) (kprobe_opcode_t *) (regs->pc + 4 +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) regs->regs[reg_nr]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) } else if (OPCODE_RTS(p->opcode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) op1->addr = (kprobe_opcode_t *) regs->pr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) } else if (OPCODE_BF(p->opcode) || OPCODE_BT(p->opcode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) unsigned long disp = (p->opcode & 0x00FF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) /* case 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) op1->addr = p->addr + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) /* case 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) op2->addr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) (kprobe_opcode_t *) (regs->pc + 4 + disp * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) op2->opcode = *(op2->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) arch_arm_kprobe(op2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) } else if (OPCODE_BF_S(p->opcode) || OPCODE_BT_S(p->opcode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) unsigned long disp = (p->opcode & 0x00FF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) /* case 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) op1->addr = p->addr + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) /* case 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) op2->addr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) (kprobe_opcode_t *) (regs->pc + 4 + disp * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) op2->opcode = *(op2->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) arch_arm_kprobe(op2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) op1->addr = p->addr + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) op1->opcode = *(op1->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) arch_arm_kprobe(op1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) /* Called with kretprobe_lock held */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) ri->ret_addr = (kprobe_opcode_t *) regs->pr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) ri->fp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) /* Replace the return addr with trampoline addr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) regs->pr = (unsigned long)kretprobe_trampoline;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) static int __kprobes kprobe_handler(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) struct kprobe *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) kprobe_opcode_t *addr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) struct kprobe_ctlblk *kcb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) * We don't want to be preempted for the entire
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) * duration of kprobe processing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) preempt_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) kcb = get_kprobe_ctlblk();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) addr = (kprobe_opcode_t *) (regs->pc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) /* Check we're not actually recursing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) if (kprobe_running()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) p = get_kprobe(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) if (p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) if (kcb->kprobe_status == KPROBE_HIT_SS &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) *p->ainsn.insn == BREAKPOINT_INSTRUCTION) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) goto no_kprobe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) /* We have reentered the kprobe_handler(), since
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) * another probe was hit while within the handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) * We here save the original kprobes variables and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) * just single step on the instruction of the new probe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) * without calling any user handlers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) save_previous_kprobe(kcb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) set_current_kprobe(p, regs, kcb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) kprobes_inc_nmissed_count(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) prepare_singlestep(p, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) kcb->kprobe_status = KPROBE_REENTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) goto no_kprobe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) p = get_kprobe(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) if (!p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) /* Not one of ours: let kernel handle it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) if (*(kprobe_opcode_t *)addr != BREAKPOINT_INSTRUCTION) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) * The breakpoint instruction was removed right
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) * after we hit it. Another cpu has removed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) * either a probepoint or a debugger breakpoint
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) * at this address. In either case, no further
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) * handling of this interrupt is appropriate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) ret = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) goto no_kprobe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) set_current_kprobe(p, regs, kcb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) kcb->kprobe_status = KPROBE_HIT_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) if (p->pre_handler && p->pre_handler(p, regs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) /* handler has already set things up, so skip ss setup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) reset_current_kprobe();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) preempt_enable_no_resched();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) prepare_singlestep(p, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) kcb->kprobe_status = KPROBE_HIT_SS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) no_kprobe:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) preempt_enable_no_resched();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) * For function-return probes, init_kprobes() establishes a probepoint
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) * here. When a retprobed function returns, this probe is hit and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) * trampoline_probe_handler() runs, calling the kretprobe's handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) static void __used kretprobe_trampoline_holder(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) asm volatile (".globl kretprobe_trampoline\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) "kretprobe_trampoline:\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) "nop\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) * Called when we hit the probe point at kretprobe_trampoline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) regs->pc = __kretprobe_trampoline_handler(regs, &kretprobe_trampoline, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) static int __kprobes post_kprobe_handler(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) struct kprobe *cur = kprobe_running();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) kprobe_opcode_t *addr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) struct kprobe *p = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) if (!cur)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) kcb->kprobe_status = KPROBE_HIT_SSDONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) cur->post_handler(cur, regs, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) p = this_cpu_ptr(&saved_next_opcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) if (p->addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) arch_disarm_kprobe(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) p->addr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) p->opcode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) addr = __this_cpu_read(saved_current_opcode.addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) __this_cpu_write(saved_current_opcode.addr, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) p = get_kprobe(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) arch_arm_kprobe(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) p = this_cpu_ptr(&saved_next_opcode2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) if (p->addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) arch_disarm_kprobe(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) p->addr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) p->opcode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) /* Restore back the original saved kprobes variables and continue. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) if (kcb->kprobe_status == KPROBE_REENTER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) restore_previous_kprobe(kcb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) reset_current_kprobe();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) preempt_enable_no_resched();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) struct kprobe *cur = kprobe_running();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) const struct exception_table_entry *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) switch (kcb->kprobe_status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) case KPROBE_HIT_SS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) case KPROBE_REENTER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) * We are here because the instruction being single
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) * stepped caused a page fault. We reset the current
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) * kprobe, point the pc back to the probe address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) * and allow the page fault handler to continue as a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) * normal page fault.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) regs->pc = (unsigned long)cur->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) if (kcb->kprobe_status == KPROBE_REENTER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) restore_previous_kprobe(kcb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) reset_current_kprobe();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) preempt_enable_no_resched();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) case KPROBE_HIT_ACTIVE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) case KPROBE_HIT_SSDONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) * We increment the nmissed count for accounting,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) * we can also use npre/npostfault count for accounting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) * these specific fault cases.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) kprobes_inc_nmissed_count(cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) * We come here because instructions in the pre/post
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) * handler caused the page_fault, this could happen
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) * if handler tries to access user space by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) * copy_from_user(), get_user() etc. Let the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) * user-specified handler try to fix it first.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) * In case the user-specified fault handler returned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) * zero, try to fix up.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) if ((entry = search_exception_tables(regs->pc)) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) regs->pc = entry->fixup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) * fixup_exception() could not handle it,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) * Let do_page_fault() fix it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) * Wrapper routine to for handling exceptions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) unsigned long val, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) struct kprobe *p = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) struct die_args *args = (struct die_args *)data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) int ret = NOTIFY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) kprobe_opcode_t *addr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) addr = (kprobe_opcode_t *) (args->regs->pc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) if (val == DIE_TRAP &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) args->trapnr == (BREAKPOINT_INSTRUCTION & 0xff)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) if (!kprobe_running()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) if (kprobe_handler(args->regs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) ret = NOTIFY_STOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) /* Not a kprobe trap */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) ret = NOTIFY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) p = get_kprobe(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) if ((kcb->kprobe_status == KPROBE_HIT_SS) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) (kcb->kprobe_status == KPROBE_REENTER)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) if (post_kprobe_handler(args->regs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) ret = NOTIFY_STOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) if (kprobe_handler(args->regs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) ret = NOTIFY_STOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) static struct kprobe trampoline_p = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) .addr = (kprobe_opcode_t *)&kretprobe_trampoline,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) .pre_handler = trampoline_probe_handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) int __init arch_init_kprobes(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) return register_kprobe(&trampoline_p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) }