Skip to contentSkip to conversation

x86/ipipe: Fix root state on return from certain exceptions

PATCH In review Jan Kiszka 1 participant 2 messages Nov 27, 2014 – Dec 8, 2016 x86

lore
Share & tools
lore

Jan Kiszka

author
#0 lore raw

PATCH 1/1 x86/ipipe: Fix root state on return from certain exceptions

do_stack_segment, do_int3 and do_debug disable interrupts of the root domain before returning the exception trampoline code. However, I-ipipe does not update the root state before returning from exceptions. So we erroneously stalled root this way, specifically during gdb sessions. The issue was easily triggerable by enabling CONFIG_DEBUG_ATOMIC_SLEEP and then trying to debug a program.

This now simply disables physical interrupts and leaves the root state untouched across exception return.

Note: There is also conditional_cli, but that's unused by Linux.

---

For review. Still not totally sure if there aren't more of such corner cases or if this can have some side effect.

 arch/x86/kernel/traps.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)
arch/x86/kernel/traps.c +10 -1
index c086b59..f78f79c 100644
@@ -102,7 +102,16 @@ static inline void conditional_cli(struct pt_regs *regs)
 static inline void preempt_conditional_cli(struct pt_regs *regs)
 {
 	if (regs->flags & X86_EFLAGS_IF)
-		local_irq_disable();
+		/*
+		 * I-pipe doesn't virtualize the IRQ flags in the entry code.
+		 * Therefore we cannot call the original local_irq_disable here
+		 * because there will be no pairing IRQ enable for the root
+		 * domain. So just disable interrupts physically.
+		 *
+		 * There is also no I-pipe hard-irq tracing on return from the
+		 * exception, so do not trace here either.
+		 */
+		hard_local_irq_disable_notrace();
 	preempt_count_dec();
 }
 
Signature · 1 line
1.8.4.5
author
#1 lore raw
Quoted 34 lines · Jan Kiszka

do_stack_segment, do_int3 and do_debug disable interrupts of the root domain before returning the exception trampoline code. However, I-ipipe does not update the root state before returning from exceptions. So we erroneously stalled root this way, specifically during gdb sessions. The issue was easily triggerable by enabling CONFIG_DEBUG_ATOMIC_SLEEP and then trying to debug a program.

This now simply disables physical interrupts and leaves the root state untouched across exception return.

Note: There is also conditional_cli, but that's unused by Linux.

---

For review. Still not totally sure if there aren't more of such corner cases or if this can have some side effect.

 arch/x86/kernel/traps.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)
arch/x86/kernel/traps.c +3 -1
index c086b59..f78f79c 100644
@@ -102,7 +102,16 @@ static inline void conditional_cli(struct pt_regs *regs)
 static inline void preempt_conditional_cli(struct pt_regs *regs)
 {
 	if (regs->flags & X86_EFLAGS_IF)
-		local_irq_disable();
+		/*
+		 * I-pipe doesn't virtualize the IRQ flags in the entry code.
+		 * Therefore we cannot call the original local_irq_disable here

arch/x86/kernel/traps.c static inline void conditional_cli(struct pt_regs *regs) · line 117

Quoted 10 lines
arch/x86/kernel/traps.c +7 -0
+		 * because there will be no pairing IRQ enable for the root
+		 * domain. So just disable interrupts physically.
+		 *
+		 * There is also no I-pipe hard-irq tracing on return from the
+		 * exception, so do not trace here either.
+		 */
+		hard_local_irq_disable_notrace();
 	preempt_count_dec();
 }
 

Just noticed, after debugging the same issue over 4.4 again, that this patch never made it into anything but 3.14. Only fair that it hits me again, I should have pushed harder back then...

Loosing such fixes between the maintained stable branches is too easy when patches aren't filed against a development head first, and only ported back afterwards.

Jan

Signature · 2 lines
Siemens AG, Corporate Technology, CT RDA ITP SES-DE
Corporate Competence Center Embedded Linux