aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r--arch/x86/kernel/cpu/common.c6
-rw-r--r--arch/x86/kernel/traps.c14
2 files changed, 18 insertions, 2 deletions
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index caa404556b9..266e4649b1d 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -1093,11 +1093,13 @@ unsigned long kernel_eflags;
1093DEFINE_PER_CPU(struct orig_ist, orig_ist); 1093DEFINE_PER_CPU(struct orig_ist, orig_ist);
1094 1094
1095static DEFINE_PER_CPU(unsigned long, debug_stack_addr); 1095static DEFINE_PER_CPU(unsigned long, debug_stack_addr);
1096DEFINE_PER_CPU(int, debug_stack_usage);
1096 1097
1097int is_debug_stack(unsigned long addr) 1098int is_debug_stack(unsigned long addr)
1098{ 1099{
1099 return addr <= __get_cpu_var(debug_stack_addr) && 1100 return __get_cpu_var(debug_stack_usage) ||
1100 addr > (__get_cpu_var(debug_stack_addr) - DEBUG_STKSZ); 1101 (addr <= __get_cpu_var(debug_stack_addr) &&
1102 addr > (__get_cpu_var(debug_stack_addr) - DEBUG_STKSZ));
1101} 1103}
1102 1104
1103void debug_stack_set_zero(void) 1105void debug_stack_set_zero(void)
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index a93c5cabc36..0072b38e3ea 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -316,9 +316,15 @@ dotraplinkage void __kprobes do_int3(struct pt_regs *regs, long error_code)
316 return; 316 return;
317#endif 317#endif
318 318
319 /*
320 * Let others (NMI) know that the debug stack is in use
321 * as we may switch to the interrupt stack.
322 */
323 debug_stack_usage_inc();
319 preempt_conditional_sti(regs); 324 preempt_conditional_sti(regs);
320 do_trap(3, SIGTRAP, "int3", regs, error_code, NULL); 325 do_trap(3, SIGTRAP, "int3", regs, error_code, NULL);
321 preempt_conditional_cli(regs); 326 preempt_conditional_cli(regs);
327 debug_stack_usage_dec();
322} 328}
323 329
324#ifdef CONFIG_X86_64 330#ifdef CONFIG_X86_64
@@ -411,6 +417,12 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code)
411 SIGTRAP) == NOTIFY_STOP) 417 SIGTRAP) == NOTIFY_STOP)
412 return; 418 return;
413 419
420 /*
421 * Let others (NMI) know that the debug stack is in use
422 * as we may switch to the interrupt stack.
423 */
424 debug_stack_usage_inc();
425
414 /* It's safe to allow irq's after DR6 has been saved */ 426 /* It's safe to allow irq's after DR6 has been saved */
415 preempt_conditional_sti(regs); 427 preempt_conditional_sti(regs);
416 428
@@ -418,6 +430,7 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code)
418 handle_vm86_trap((struct kernel_vm86_regs *) regs, 430 handle_vm86_trap((struct kernel_vm86_regs *) regs,
419 error_code, 1); 431 error_code, 1);
420 preempt_conditional_cli(regs); 432 preempt_conditional_cli(regs);
433 debug_stack_usage_dec();
421 return; 434 return;
422 } 435 }
423 436
@@ -437,6 +450,7 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code)
437 if (tsk->thread.debugreg6 & (DR_STEP | DR_TRAP_BITS) || user_icebp) 450 if (tsk->thread.debugreg6 & (DR_STEP | DR_TRAP_BITS) || user_icebp)
438 send_sigtrap(tsk, regs, error_code, si_code); 451 send_sigtrap(tsk, regs, error_code, si_code);
439 preempt_conditional_cli(regs); 452 preempt_conditional_cli(regs);
453 debug_stack_usage_dec();
440 454
441 return; 455 return;
442} 456}