x86/ipipe: Fix root state on return from certain exceptions
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
@@ -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
Quoted 34 lines · Jan Kiszka
do_stack_segment,do_int3anddo_debugdisable 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 enablingCONFIG_DEBUG_ATOMIC_SLEEPand 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.Signed-off-by Jan Kiszka <[email protected]>---
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@@ -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