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 --- |