aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/include/asm/kprobes.h2
-rw-r--r--arch/x86/kernel/kprobes/core.c24
-rw-r--r--arch/x86/kernel/traps.c10
3 files changed, 15 insertions, 21 deletions
diff --git a/arch/x86/include/asm/kprobes.h b/arch/x86/include/asm/kprobes.h
index 9454c167629f..53cdfb2857ab 100644
--- a/arch/x86/include/asm/kprobes.h
+++ b/arch/x86/include/asm/kprobes.h
@@ -116,4 +116,6 @@ struct kprobe_ctlblk {
116extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr); 116extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr);
117extern int kprobe_exceptions_notify(struct notifier_block *self, 117extern int kprobe_exceptions_notify(struct notifier_block *self,
118 unsigned long val, void *data); 118 unsigned long val, void *data);
119extern int kprobe_int3_handler(struct pt_regs *regs);
120extern int kprobe_debug_handler(struct pt_regs *regs);
119#endif /* _ASM_X86_KPROBES_H */ 121#endif /* _ASM_X86_KPROBES_H */
diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c
index 7751b3dee53a..9b80aec1ea1a 100644
--- a/arch/x86/kernel/kprobes/core.c
+++ b/arch/x86/kernel/kprobes/core.c
@@ -559,7 +559,7 @@ reenter_kprobe(struct kprobe *p, struct pt_regs *regs, struct kprobe_ctlblk *kcb
559 * Interrupts are disabled on entry as trap3 is an interrupt gate and they 559 * Interrupts are disabled on entry as trap3 is an interrupt gate and they
560 * remain disabled throughout this function. 560 * remain disabled throughout this function.
561 */ 561 */
562static int __kprobes kprobe_handler(struct pt_regs *regs) 562int __kprobes kprobe_int3_handler(struct pt_regs *regs)
563{ 563{
564 kprobe_opcode_t *addr; 564 kprobe_opcode_t *addr;
565 struct kprobe *p; 565 struct kprobe *p;
@@ -857,7 +857,7 @@ no_change:
857 * Interrupts are disabled on entry as trap1 is an interrupt gate and they 857 * Interrupts are disabled on entry as trap1 is an interrupt gate and they
858 * remain disabled throughout this function. 858 * remain disabled throughout this function.
859 */ 859 */
860static int __kprobes post_kprobe_handler(struct pt_regs *regs) 860int __kprobes kprobe_debug_handler(struct pt_regs *regs)
861{ 861{
862 struct kprobe *cur = kprobe_running(); 862 struct kprobe *cur = kprobe_running();
863 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); 863 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
@@ -963,22 +963,7 @@ kprobe_exceptions_notify(struct notifier_block *self, unsigned long val, void *d
963 if (args->regs && user_mode_vm(args->regs)) 963 if (args->regs && user_mode_vm(args->regs))
964 return ret; 964 return ret;
965 965
966 switch (val) { 966 if (val == DIE_GPF) {
967 case DIE_INT3:
968 if (kprobe_handler(args->regs))
969 ret = NOTIFY_STOP;
970 break;
971 case DIE_DEBUG:
972 if (post_kprobe_handler(args->regs)) {
973 /*
974 * Reset the BS bit in dr6 (pointed by args->err) to
975 * denote completion of processing
976 */
977 (*(unsigned long *)ERR_PTR(args->err)) &= ~DR_STEP;
978 ret = NOTIFY_STOP;
979 }
980 break;
981 case DIE_GPF:
982 /* 967 /*
983 * To be potentially processing a kprobe fault and to 968 * To be potentially processing a kprobe fault and to
984 * trust the result from kprobe_running(), we have 969 * trust the result from kprobe_running(), we have
@@ -987,9 +972,6 @@ kprobe_exceptions_notify(struct notifier_block *self, unsigned long val, void *d
987 if (!preemptible() && kprobe_running() && 972 if (!preemptible() && kprobe_running() &&
988 kprobe_fault_handler(args->regs, args->trapnr)) 973 kprobe_fault_handler(args->regs, args->trapnr))
989 ret = NOTIFY_STOP; 974 ret = NOTIFY_STOP;
990 break;
991 default:
992 break;
993 } 975 }
994 return ret; 976 return ret;
995} 977}
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index 57409f6b8c62..e5d4a70814d7 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -334,6 +334,11 @@ dotraplinkage void __kprobes notrace do_int3(struct pt_regs *regs, long error_co
334 goto exit; 334 goto exit;
335#endif /* CONFIG_KGDB_LOW_LEVEL_TRAP */ 335#endif /* CONFIG_KGDB_LOW_LEVEL_TRAP */
336 336
337#ifdef CONFIG_KPROBES
338 if (kprobe_int3_handler(regs))
339 return;
340#endif
341
337 if (notify_die(DIE_INT3, "int3", regs, error_code, X86_TRAP_BP, 342 if (notify_die(DIE_INT3, "int3", regs, error_code, X86_TRAP_BP,
338 SIGTRAP) == NOTIFY_STOP) 343 SIGTRAP) == NOTIFY_STOP)
339 goto exit; 344 goto exit;
@@ -440,6 +445,11 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code)
440 /* Store the virtualized DR6 value */ 445 /* Store the virtualized DR6 value */
441 tsk->thread.debugreg6 = dr6; 446 tsk->thread.debugreg6 = dr6;
442 447
448#ifdef CONFIG_KPROBES
449 if (kprobe_debug_handler(regs))
450 goto exit;
451#endif
452
443 if (notify_die(DIE_DEBUG, "debug", regs, (long)&dr6, error_code, 453 if (notify_die(DIE_DEBUG, "debug", regs, (long)&dr6, error_code,
444 SIGTRAP) == NOTIFY_STOP) 454 SIGTRAP) == NOTIFY_STOP)
445 goto exit; 455 goto exit;