Lines Matching +full:pre +full:- +full:processing
1 // SPDX-License-Identifier: GPL-2.0-only
31 #include "../decode-arm.h"
32 #include "../decode-thumb.h"
37 (unsigned long)current_thread_info() + THREAD_START_SP - (addr))
52 unsigned long addr = (unsigned long)p->addr; in arch_prepare_kprobe()
77 return -EINVAL; in arch_prepare_kprobe()
78 insn = __mem_to_opcode_arm(*p->addr); in arch_prepare_kprobe()
84 p->opcode = insn; in arch_prepare_kprobe()
85 p->ainsn.insn = tmp_insn; in arch_prepare_kprobe()
87 switch ((*decode_insn)(insn, &p->ainsn, true, actions, checkers)) { in arch_prepare_kprobe()
89 return -EINVAL; in arch_prepare_kprobe()
92 p->ainsn.insn = get_insn_slot(); in arch_prepare_kprobe()
93 if (!p->ainsn.insn) in arch_prepare_kprobe()
94 return -ENOMEM; in arch_prepare_kprobe()
96 p->ainsn.insn[is] = tmp_insn[is]; in arch_prepare_kprobe()
97 flush_insns(p->ainsn.insn, in arch_prepare_kprobe()
98 sizeof(p->ainsn.insn[0]) * MAX_INSN_SIZE); in arch_prepare_kprobe()
99 p->ainsn.insn_fn = (probes_insn_fn_t *) in arch_prepare_kprobe()
100 ((uintptr_t)p->ainsn.insn | thumb); in arch_prepare_kprobe()
104 p->ainsn.insn = NULL; in arch_prepare_kprobe()
109 * Never instrument insn like 'str r0, [sp, +/-r1]'. Also, insn likes in arch_prepare_kprobe()
110 * 'str r0, [sp, #-68]' should also be prohibited. in arch_prepare_kprobe()
113 if ((p->ainsn.stack_space < 0) || in arch_prepare_kprobe()
114 (p->ainsn.stack_space > MAX_STACK_SIZE)) in arch_prepare_kprobe()
115 return -EINVAL; in arch_prepare_kprobe()
127 addr = (void *)((uintptr_t)p->addr & ~1); in arch_arm_kprobe()
129 if (is_wide_instruction(p->opcode)) in arch_arm_kprobe()
134 kprobe_opcode_t insn = p->opcode; in arch_arm_kprobe()
136 addr = p->addr; in arch_arm_kprobe()
153 * memory. It is also needed to atomically set the two half-words of a 32-bit
164 __patch_text(p->addr, p->insn); in __kprobes_remove_breakpoint()
180 kprobes_remove_breakpoint((void *)((uintptr_t)p->addr & ~1), in arch_disarm_kprobe()
181 p->opcode); in arch_disarm_kprobe()
186 if (p->ainsn.insn) { in arch_remove_kprobe()
187 free_insn_slot(p->ainsn.insn, 0); in arch_remove_kprobe()
188 p->ainsn.insn = NULL; in arch_remove_kprobe()
194 kcb->prev_kprobe.kp = kprobe_running(); in save_previous_kprobe()
195 kcb->prev_kprobe.status = kcb->kprobe_status; in save_previous_kprobe()
200 __this_cpu_write(current_kprobe, kcb->prev_kprobe.kp); in restore_previous_kprobe()
201 kcb->kprobe_status = kcb->prev_kprobe.status; in restore_previous_kprobe()
213 regs->ARM_cpsr = it_advance(regs->ARM_cpsr); in singlestep_skip()
214 if (is_wide_instruction(p->opcode)) in singlestep_skip()
215 regs->ARM_pc += 4; in singlestep_skip()
217 regs->ARM_pc += 2; in singlestep_skip()
219 regs->ARM_pc += 4; in singlestep_skip()
226 p->ainsn.insn_singlestep(p->opcode, &p->ainsn, regs); in singlestep()
231 * all the way until processing this kprobe is complete. The current
250 p = get_kprobe((kprobe_opcode_t *)(regs->ARM_pc | 1)); in kprobe_handler()
252 p = get_kprobe((kprobe_opcode_t *)regs->ARM_pc); in kprobe_handler()
255 p = get_kprobe((kprobe_opcode_t *)regs->ARM_pc); in kprobe_handler()
259 if (!p->ainsn.insn_check_cc(regs->ARM_cpsr)) { in kprobe_handler()
269 switch (kcb->kprobe_status) { in kprobe_handler()
273 /* A pre- or post-handler probe got us here. */ in kprobe_handler()
277 kcb->kprobe_status = KPROBE_REENTER; in kprobe_handler()
293 kcb->kprobe_status = KPROBE_HIT_ACTIVE; in kprobe_handler()
296 * If we have no pre-handler or it returned 0, we in kprobe_handler()
297 * continue with normal processing. If we have a in kprobe_handler()
298 * pre-handler and it returned non-zero, it will in kprobe_handler()
302 if (!p->pre_handler || !p->pre_handler(p, regs)) { in kprobe_handler()
303 kcb->kprobe_status = KPROBE_HIT_SS; in kprobe_handler()
305 if (p->post_handler) { in kprobe_handler()
306 kcb->kprobe_status = KPROBE_HIT_SSDONE; in kprobe_handler()
307 p->post_handler(p, regs, 0); in kprobe_handler()
336 switch (kcb->kprobe_status) { in kprobe_fault_handler()
346 regs->ARM_pc = (long)cur->addr; in kprobe_fault_handler()
347 if (kcb->kprobe_status == KPROBE_REENTER) { in kprobe_fault_handler()
371 * give a view of registers r0-r11, sp, lr, and pc to the user
372 * return-handler. This is not a complete pt_regs structure, but that
385 /* In clang case, pt_regs->ip = lr. */ in __kretprobe_trampoline()
386 "stmdb sp!, {r0 - r11, lr} \n\t" in __kretprobe_trampoline()
387 /* fp points regs->r11 (fp) */ in __kretprobe_trampoline()
390 /* In gcc case, pt_regs->ip = fp. */ in __kretprobe_trampoline()
393 "stmdb sp!, {r0 - r11} \n\t" in __kretprobe_trampoline()
394 /* fp points regs->r15 (pc) */ in __kretprobe_trampoline()
399 "stmdb sp!, {r0 - r11} \n\t" in __kretprobe_trampoline()
404 "ldmia sp!, {r0 - r11} \n\t" in __kretprobe_trampoline()
417 return (void *)kretprobe_trampoline_handler(regs, (void *)regs->ARM_fp); in trampoline_handler()
423 ri->ret_addr = (kprobe_opcode_t *)regs->ARM_lr; in arch_prepare_kretprobe()
424 ri->fp = (void *)regs->ARM_fp; in arch_prepare_kretprobe()
427 regs->ARM_lr = (unsigned long)&__kretprobe_trampoline; in arch_prepare_kretprobe()