kprobes.c (16217dc79dbc599b110dda26d0421df47904bba4) kprobes.c (0edfa8391664a4f795c67d0e07480fbe801a0e1d)
1/*
2 * arch/arm64/kernel/probes/kprobes.c
3 *
4 * Kprobes support for ARM64
5 *
6 * Copyright (C) 2013 Linaro Limited.
7 * Author: Sandeepa Prabhu <sandeepa.prabhu@linaro.org>
8 *

--- 5 unchanged lines hidden (view full) ---

14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 */
19#include <linux/kasan.h>
20#include <linux/kernel.h>
21#include <linux/kprobes.h>
1/*
2 * arch/arm64/kernel/probes/kprobes.c
3 *
4 * Kprobes support for ARM64
5 *
6 * Copyright (C) 2013 Linaro Limited.
7 * Author: Sandeepa Prabhu <sandeepa.prabhu@linaro.org>
8 *

--- 5 unchanged lines hidden (view full) ---

14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 */
19#include <linux/kasan.h>
20#include <linux/kernel.h>
21#include <linux/kprobes.h>
22#include <linux/module.h>
22#include <linux/extable.h>
23#include <linux/slab.h>
24#include <linux/stop_machine.h>
25#include <linux/stringify.h>
26#include <asm/traps.h>
27#include <asm/ptrace.h>
28#include <asm/cacheflush.h>
29#include <asm/debug-monitors.h>
30#include <asm/system_misc.h>
31#include <asm/insn.h>
32#include <asm/uaccess.h>
33#include <asm/irq.h>
23#include <linux/slab.h>
24#include <linux/stop_machine.h>
25#include <linux/stringify.h>
26#include <asm/traps.h>
27#include <asm/ptrace.h>
28#include <asm/cacheflush.h>
29#include <asm/debug-monitors.h>
30#include <asm/system_misc.h>
31#include <asm/insn.h>
32#include <asm/uaccess.h>
33#include <asm/irq.h>
34#include <asm-generic/sections.h>
34#include <asm/sections.h>
35
36#include "decode-insn.h"
37
38DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
39DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
40
41static void __kprobes
42post_kprobe_handler(struct kprobe_ctlblk *, struct pt_regs *);

--- 118 unchanged lines hidden (view full) ---

161}
162
163static void __kprobes set_current_kprobe(struct kprobe *p)
164{
165 __this_cpu_write(current_kprobe, p);
166}
167
168/*
35
36#include "decode-insn.h"
37
38DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
39DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
40
41static void __kprobes
42post_kprobe_handler(struct kprobe_ctlblk *, struct pt_regs *);

--- 118 unchanged lines hidden (view full) ---

161}
162
163static void __kprobes set_current_kprobe(struct kprobe *p)
164{
165 __this_cpu_write(current_kprobe, p);
166}
167
168/*
169 * The D-flag (Debug mask) is set (masked) upon debug exception entry.
170 * Kprobes needs to clear (unmask) D-flag -ONLY- in case of recursive
171 * probe i.e. when probe hit from kprobe handler context upon
172 * executing the pre/post handlers. In this case we return with
173 * D-flag clear so that single-stepping can be carried-out.
174 *
175 * Leave D-flag set in all other cases.
169 * When PSTATE.D is set (masked), then software step exceptions can not be
170 * generated.
171 * SPSR's D bit shows the value of PSTATE.D immediately before the
172 * exception was taken. PSTATE.D is set while entering into any exception
173 * mode, however software clears it for any normal (none-debug-exception)
174 * mode in the exception entry. Therefore, when we are entering into kprobe
175 * breakpoint handler from any normal mode then SPSR.D bit is already
176 * cleared, however it is set when we are entering from any debug exception
177 * mode.
178 * Since we always need to generate single step exception after a kprobe
179 * breakpoint exception therefore we need to clear it unconditionally, when
180 * we become sure that the current breakpoint exception is for kprobe.
176 */
177static void __kprobes
178spsr_set_debug_flag(struct pt_regs *regs, int mask)
179{
180 unsigned long spsr = regs->pstate;
181
182 if (mask)
183 spsr |= PSR_D_BIT;

--- 56 unchanged lines hidden (view full) ---

240
241
242 if (p->ainsn.insn) {
243 /* prepare for single stepping */
244 slot = (unsigned long)p->ainsn.insn;
245
246 set_ss_context(kcb, slot); /* mark pending ss */
247
181 */
182static void __kprobes
183spsr_set_debug_flag(struct pt_regs *regs, int mask)
184{
185 unsigned long spsr = regs->pstate;
186
187 if (mask)
188 spsr |= PSR_D_BIT;

--- 56 unchanged lines hidden (view full) ---

245
246
247 if (p->ainsn.insn) {
248 /* prepare for single stepping */
249 slot = (unsigned long)p->ainsn.insn;
250
251 set_ss_context(kcb, slot); /* mark pending ss */
252
248 if (kcb->kprobe_status == KPROBE_REENTER)
249 spsr_set_debug_flag(regs, 0);
250 else
251 WARN_ON(regs->pstate & PSR_D_BIT);
253 spsr_set_debug_flag(regs, 0);
252
253 /* IRQs and single stepping do not mix well. */
254 kprobes_save_local_irqflag(kcb, regs);
255 kernel_enable_single_step(regs);
256 instruction_pointer_set(regs, slot);
257 } else {
258 /* insn simulation */
259 arch_simulate_insn(p, regs);

--- 68 unchanged lines hidden (view full) ---

328 * and allow the page fault handler to continue as a
329 * normal page fault.
330 */
331 instruction_pointer_set(regs, (unsigned long) cur->addr);
332 if (!instruction_pointer(regs))
333 BUG();
334
335 kernel_disable_single_step();
254
255 /* IRQs and single stepping do not mix well. */
256 kprobes_save_local_irqflag(kcb, regs);
257 kernel_enable_single_step(regs);
258 instruction_pointer_set(regs, slot);
259 } else {
260 /* insn simulation */
261 arch_simulate_insn(p, regs);

--- 68 unchanged lines hidden (view full) ---

330 * and allow the page fault handler to continue as a
331 * normal page fault.
332 */
333 instruction_pointer_set(regs, (unsigned long) cur->addr);
334 if (!instruction_pointer(regs))
335 BUG();
336
337 kernel_disable_single_step();
336 if (kcb->kprobe_status == KPROBE_REENTER)
337 spsr_set_debug_flag(regs, 1);
338
339 if (kcb->kprobe_status == KPROBE_REENTER)
340 restore_previous_kprobe(kcb);
341 else
342 reset_current_kprobe();
343
344 break;
345 case KPROBE_HIT_ACTIVE:

--- 106 unchanged lines hidden (view full) ---

452
453 /* return error if this is not our step */
454 retval = kprobe_ss_hit(kcb, instruction_pointer(regs));
455
456 if (retval == DBG_HOOK_HANDLED) {
457 kprobes_restore_local_irqflag(kcb, regs);
458 kernel_disable_single_step();
459
338
339 if (kcb->kprobe_status == KPROBE_REENTER)
340 restore_previous_kprobe(kcb);
341 else
342 reset_current_kprobe();
343
344 break;
345 case KPROBE_HIT_ACTIVE:

--- 106 unchanged lines hidden (view full) ---

452
453 /* return error if this is not our step */
454 retval = kprobe_ss_hit(kcb, instruction_pointer(regs));
455
456 if (retval == DBG_HOOK_HANDLED) {
457 kprobes_restore_local_irqflag(kcb, regs);
458 kernel_disable_single_step();
459
460 if (kcb->kprobe_status == KPROBE_REENTER)
461 spsr_set_debug_flag(regs, 1);
462
463 post_kprobe_handler(kcb, regs);
464 }
465
466 return retval;
467}
468
469int __kprobes
470kprobe_breakpoint_handler(struct pt_regs *regs, unsigned int esr)

--- 67 unchanged lines hidden (view full) ---

538 unpause_graph_tracing();
539 *regs = kcb->jprobe_saved_regs;
540 preempt_enable_no_resched();
541 return 1;
542}
543
544bool arch_within_kprobe_blacklist(unsigned long addr)
545{
460 post_kprobe_handler(kcb, regs);
461 }
462
463 return retval;
464}
465
466int __kprobes
467kprobe_breakpoint_handler(struct pt_regs *regs, unsigned int esr)

--- 67 unchanged lines hidden (view full) ---

535 unpause_graph_tracing();
536 *regs = kcb->jprobe_saved_regs;
537 preempt_enable_no_resched();
538 return 1;
539}
540
541bool arch_within_kprobe_blacklist(unsigned long addr)
542{
546 extern char __idmap_text_start[], __idmap_text_end[];
547 extern char __hyp_idmap_text_start[], __hyp_idmap_text_end[];
548
549 if ((addr >= (unsigned long)__kprobes_text_start &&
550 addr < (unsigned long)__kprobes_text_end) ||
551 (addr >= (unsigned long)__entry_text_start &&
552 addr < (unsigned long)__entry_text_end) ||
553 (addr >= (unsigned long)__idmap_text_start &&
554 addr < (unsigned long)__idmap_text_end) ||
555 !!search_exception_tables(addr))
556 return true;

--- 109 unchanged lines hidden ---
543 if ((addr >= (unsigned long)__kprobes_text_start &&
544 addr < (unsigned long)__kprobes_text_end) ||
545 (addr >= (unsigned long)__entry_text_start &&
546 addr < (unsigned long)__entry_text_end) ||
547 (addr >= (unsigned long)__idmap_text_start &&
548 addr < (unsigned long)__idmap_text_end) ||
549 !!search_exception_tables(addr))
550 return true;

--- 109 unchanged lines hidden ---