Preemption check of the Linux interrupt tail verifies, among other things, that IF set for the preempted context. If it's not, no Linux task switch is initiated. As we fake the context on root IRQ replay, we must ensure that IF is faked properly as well, otherwise long Linux rescheduling latencies up to deadlocks can occur.
Based on suggestion by Philippe. Signed-off-by: Jan Kiszka <[email protected]> --- arch/x86/include/asm/ipipe_32.h | 8 ++++++-- arch/x86/include/asm/ipipe_64.h | 8 ++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/arch/x86/include/asm/ipipe_32.h b/arch/x86/include/asm/ipipe_32.h index 4263a7f..61d7913 100644 --- a/arch/x86/include/asm/ipipe_32.h +++ b/arch/x86/include/asm/ipipe_32.h @@ -70,6 +70,7 @@ static inline void __do_root_xirq(ipipe_irq_handler_t handler, regs->orig_ax = ~__ipipe_get_irq_vector(irq); __asm__ __volatile__("pushfl\n\t" + "orl %[x86if],(%%esp)\n\t" "pushl %%cs\n\t" "pushl $__xirq_end\n\t" "pushl %%eax\n\t" @@ -89,7 +90,8 @@ static inline void __do_root_xirq(ipipe_irq_handler_t handler, "jmp ret_from_intr\n\t" "__xirq_end: cli\n" : /* no output */ - : "a" (~irq), "r" (handler), "rm" (regs)); + : "a" (~irq), "r" (handler), "rm" (regs), + [x86if] "i" (X86_EFLAGS_IF)); } #define __ipipe_do_root_xirq(ipd, irq) \ @@ -103,6 +105,7 @@ static inline void __do_root_virq(ipipe_irq_handler_t handler, irq_enter(); __asm__ __volatile__("pushfl\n\t" + "orl %[x86if],(%%esp)\n\t" "pushl %%cs\n\t" "pushl $__virq_end\n\t" "pushl $-1\n\t" @@ -122,7 +125,8 @@ static inline void __do_root_virq(ipipe_irq_handler_t handler, "call *%1\n\t" "addl $8,%%esp\n" : /* no output */ - : "a" (irq), "r" (handler), "d" (cookie)); + : "a" (irq), "r" (handler), "d" (cookie), + [x86if] "i" (X86_EFLAGS_IF)); irq_exit(); __asm__ __volatile__("jmp ret_from_intr\n\t" "__virq_end: cli\n" diff --git a/arch/x86/include/asm/ipipe_64.h b/arch/x86/include/asm/ipipe_64.h index b9367f6..c8f2c54 100644 --- a/arch/x86/include/asm/ipipe_64.h +++ b/arch/x86/include/asm/ipipe_64.h @@ -71,6 +71,7 @@ static inline void __do_root_xirq(ipipe_irq_handler_t handler, "pushq $0\n\t" "pushq %%rax\n\t" "pushfq\n\t" + "orq %[x86if],(%%rsp)\n\t" "pushq %[kernel_cs]\n\t" "pushq $__xirq_end\n\t" "pushq %[vector]\n\t" @@ -91,7 +92,8 @@ static inline void __do_root_xirq(ipipe_irq_handler_t handler, : /* no output */ : [kernel_cs] "i" (__KERNEL_CS), [vector] "rm" (regs->orig_ax), - [handler] "r" (handler), "D" (regs) + [handler] "r" (handler), "D" (regs), + [x86if] "i" (X86_EFLAGS_IF) : "rax"); } @@ -109,6 +111,7 @@ static inline void __do_root_virq(ipipe_irq_handler_t handler, "pushq $0\n\t" "pushq %%rax\n\t" "pushfq\n\t" + "orq %[x86if],(%%rsp)\n\t" "pushq %[kernel_cs]\n\t" "pushq $__virq_end\n\t" "pushq $-1\n\t" @@ -125,7 +128,8 @@ static inline void __do_root_virq(ipipe_irq_handler_t handler, "call *%[handler]\n\t" : /* no output */ : [kernel_cs] "i" (__KERNEL_CS), - [handler] "r" (handler), "D" (irq), "S" (cookie) + [handler] "r" (handler), "D" (irq), + "S" (cookie), [x86if] "i" (X86_EFLAGS_IF) : "rax"); irq_exit(); __asm__ __volatile__("cli\n\t" -- 1.7.1 _______________________________________________ Adeos-main mailing list [email protected] https://mail.gna.org/listinfo/adeos-main
