This is an attempt to fix the broken root domain state adjustment in __ipipe_handle_exception. Patch below fixes the issues recently reported by Roman Pisl. Also, it currently makes much more sense to me than what we have so far.
In short, this patch propagates the hardware irq state into the root domains stall flag shortly before calling into the Linux handler, and only then. This avoids spurious root domain stalls the end up over the wrong Linux context due to context switches between enter and exit of ipipe_handle_exception. Also, this patch drops the bogus local_irq_save/restore pair that doesn't account for Linux irq state changes inside its fault handler. But that doesn't mean that the ripped-out code may not have been there for a reason. Maybe I oversee some corner case that regresses now. If anyone knows such a case, please share your knowledge so that it can be addressed and (very important!) properly documented in the code. Signed-off-by: Jan Kiszka <[email protected]> --- arch/x86/kernel/ipipe.c | 34 +++++++++------------------------- 1 file changed, 9 insertions(+), 25 deletions(-) Index: b/arch/x86/kernel/ipipe.c =================================================================== --- a/arch/x86/kernel/ipipe.c +++ b/arch/x86/kernel/ipipe.c @@ -755,39 +755,18 @@ static int __ipipe_xlate_signo[] = { int __ipipe_handle_exception(struct pt_regs *regs, long error_code, int vector) { - unsigned long flags; - - local_save_flags(flags); - - /* Track the hw interrupt state before calling the Linux - * exception handler, replicating it into the virtual mask. */ - - if (irqs_disabled_hw()) { - /* Do not trigger the alarm in ipipe_check_context() by using - * plain local_irq_disable(). */ - __ipipe_stall_root(); - trace_hardirqs_off(); - barrier(); - } + int irqs_disabled = irqs_disabled_hw(); #ifdef CONFIG_KGDB /* catch exception KGDB is interested in over non-root domains */ if (!ipipe_root_domain_p && __ipipe_xlate_signo[vector] >= 0 && - !kgdb_handle_exception(vector, __ipipe_xlate_signo[vector], error_code, regs)) { - if (flags & X86_EFLAGS_IF) - __clear_bit(IPIPE_STALL_FLAG, - &ipipe_root_cpudom_var(status)); + !kgdb_handle_exception(vector, __ipipe_xlate_signo[vector], error_code, regs)) return 1; - } #endif /* CONFIG_KGDB */ - if (unlikely(ipipe_trap_notify(vector, regs))) { - if (flags & X86_EFLAGS_IF) - __clear_bit(IPIPE_STALL_FLAG, - &ipipe_root_cpudom_var(status)); + if (unlikely(ipipe_trap_notify(vector, regs))) return 1; - } /* Detect unhandled faults over non-root domains. */ @@ -818,9 +797,14 @@ int __ipipe_handle_exception(struct pt_r } } + /* Track the hw interrupt state before calling the Linux + * exception handler, replicating it into the virtual mask. */ + + if (irqs_disabled) + local_irq_disable(); + __ipipe_std_extable[vector](regs, error_code); local_irq_disable_hw(); - local_irq_restore(flags); __fixup_if(regs); return 0; _______________________________________________ Adeos-main mailing list [email protected] https://mail.gna.org/listinfo/adeos-main
