aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Lutomirski <luto@kernel.org>2015-08-21 01:03:21 -0400
committerIngo Molnar <mingo@kernel.org>2015-08-22 05:12:10 -0400
commitf0a97af83f6287357dcc100c859ec0066f164f32 (patch)
tree7be5d8bc2240bfd9533c654b464fa9ca9575947a
parent99770737ca7e3ebc14e66460a69b7032de9421e1 (diff)
x86/traps: Weaken context tracking entry assertions
We were asserting that we were all the way in CONTEXT_KERNEL when exception handlers were called. While having this be true is, I think, a nice goal (or maybe a variant in which we assert that we're in CONTEXT_KERNEL or some new IRQ context), we're not quite there. In particular, if an IRQ interrupts the SYSCALL prologue and the IRQ handler in turn causes an exception, the exception entry will be called in RCU IRQ mode but with CONTEXT_USER. This is okay (nothing goes wrong), but until we fix up the SYSCALL prologue, we need to avoid warning. Signed-off-by: Andy Lutomirski <luto@kernel.org> Acked-by: Frederic Weisbecker <fweisbec@gmail.com> Cc: Andy Lutomirski <luto@amacapital.net> Cc: Borislav Petkov <bp@alien8.de> Cc: Brian Gerst <brgerst@gmail.com> Cc: Denys Vlasenko <dvlasenk@redhat.com> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Oleg Nesterov <oleg@redhat.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Sasha Levin <sasha.levin@oracle.com> Cc: Thomas Gleixner <tglx@linutronix.de> Link: http://lkml.kernel.org/r/c81faf3916346c0e04346c441392974f49cd7184.1440133286.git.luto@kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--arch/x86/kernel/traps.c18
1 files changed, 9 insertions, 9 deletions
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index 86a82eafb96f..45e8d9891fa3 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -112,7 +112,7 @@ static inline void preempt_conditional_cli(struct pt_regs *regs)
112void ist_enter(struct pt_regs *regs) 112void ist_enter(struct pt_regs *regs)
113{ 113{
114 if (user_mode(regs)) { 114 if (user_mode(regs)) {
115 CT_WARN_ON(ct_state() != CONTEXT_KERNEL); 115 rcu_lockdep_assert(rcu_is_watching(), "entry code didn't wake RCU");
116 } else { 116 } else {
117 /* 117 /*
118 * We might have interrupted pretty much anything. In 118 * We might have interrupted pretty much anything. In
@@ -282,7 +282,7 @@ static void do_error_trap(struct pt_regs *regs, long error_code, char *str,
282{ 282{
283 siginfo_t info; 283 siginfo_t info;
284 284
285 CT_WARN_ON(ct_state() != CONTEXT_KERNEL); 285 rcu_lockdep_assert(rcu_is_watching(), "entry code didn't wake RCU");
286 286
287 if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) != 287 if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) !=
288 NOTIFY_STOP) { 288 NOTIFY_STOP) {
@@ -364,7 +364,7 @@ dotraplinkage void do_bounds(struct pt_regs *regs, long error_code)
364 const struct bndcsr *bndcsr; 364 const struct bndcsr *bndcsr;
365 siginfo_t *info; 365 siginfo_t *info;
366 366
367 CT_WARN_ON(ct_state() != CONTEXT_KERNEL); 367 rcu_lockdep_assert(rcu_is_watching(), "entry code didn't wake RCU");
368 if (notify_die(DIE_TRAP, "bounds", regs, error_code, 368 if (notify_die(DIE_TRAP, "bounds", regs, error_code,
369 X86_TRAP_BR, SIGSEGV) == NOTIFY_STOP) 369 X86_TRAP_BR, SIGSEGV) == NOTIFY_STOP)
370 return; 370 return;
@@ -442,7 +442,7 @@ do_general_protection(struct pt_regs *regs, long error_code)
442{ 442{
443 struct task_struct *tsk; 443 struct task_struct *tsk;
444 444
445 CT_WARN_ON(ct_state() != CONTEXT_KERNEL); 445 rcu_lockdep_assert(rcu_is_watching(), "entry code didn't wake RCU");
446 conditional_sti(regs); 446 conditional_sti(regs);
447 447
448 if (v8086_mode(regs)) { 448 if (v8086_mode(regs)) {
@@ -496,7 +496,7 @@ dotraplinkage void notrace do_int3(struct pt_regs *regs, long error_code)
496 return; 496 return;
497 497
498 ist_enter(regs); 498 ist_enter(regs);
499 CT_WARN_ON(ct_state() != CONTEXT_KERNEL); 499 rcu_lockdep_assert(rcu_is_watching(), "entry code didn't wake RCU");
500#ifdef CONFIG_KGDB_LOW_LEVEL_TRAP 500#ifdef CONFIG_KGDB_LOW_LEVEL_TRAP
501 if (kgdb_ll_trap(DIE_INT3, "int3", regs, error_code, X86_TRAP_BP, 501 if (kgdb_ll_trap(DIE_INT3, "int3", regs, error_code, X86_TRAP_BP,
502 SIGTRAP) == NOTIFY_STOP) 502 SIGTRAP) == NOTIFY_STOP)
@@ -729,14 +729,14 @@ static void math_error(struct pt_regs *regs, int error_code, int trapnr)
729 729
730dotraplinkage void do_coprocessor_error(struct pt_regs *regs, long error_code) 730dotraplinkage void do_coprocessor_error(struct pt_regs *regs, long error_code)
731{ 731{
732 CT_WARN_ON(ct_state() != CONTEXT_KERNEL); 732 rcu_lockdep_assert(rcu_is_watching(), "entry code didn't wake RCU");
733 math_error(regs, error_code, X86_TRAP_MF); 733 math_error(regs, error_code, X86_TRAP_MF);
734} 734}
735 735
736dotraplinkage void 736dotraplinkage void
737do_simd_coprocessor_error(struct pt_regs *regs, long error_code) 737do_simd_coprocessor_error(struct pt_regs *regs, long error_code)
738{ 738{
739 CT_WARN_ON(ct_state() != CONTEXT_KERNEL); 739 rcu_lockdep_assert(rcu_is_watching(), "entry code didn't wake RCU");
740 math_error(regs, error_code, X86_TRAP_XF); 740 math_error(regs, error_code, X86_TRAP_XF);
741} 741}
742 742
@@ -749,7 +749,7 @@ do_spurious_interrupt_bug(struct pt_regs *regs, long error_code)
749dotraplinkage void 749dotraplinkage void
750do_device_not_available(struct pt_regs *regs, long error_code) 750do_device_not_available(struct pt_regs *regs, long error_code)
751{ 751{
752 CT_WARN_ON(ct_state() != CONTEXT_KERNEL); 752 rcu_lockdep_assert(rcu_is_watching(), "entry code didn't wake RCU");
753 BUG_ON(use_eager_fpu()); 753 BUG_ON(use_eager_fpu());
754 754
755#ifdef CONFIG_MATH_EMULATION 755#ifdef CONFIG_MATH_EMULATION
@@ -775,7 +775,7 @@ dotraplinkage void do_iret_error(struct pt_regs *regs, long error_code)
775{ 775{
776 siginfo_t info; 776 siginfo_t info;
777 777
778 CT_WARN_ON(ct_state() != CONTEXT_KERNEL); 778 rcu_lockdep_assert(rcu_is_watching(), "entry code didn't wake RCU");
779 local_irq_enable(); 779 local_irq_enable();
780 780
781 info.si_signo = SIGILL; 781 info.si_signo = SIGILL;