xen/arm: gic: Defer the decision to unmask interrupts to do_{LPI, IRQ}()
authorAndrii Anisov <andrii_anisov@epam.com>
Mon, 27 May 2019 09:29:30 +0000 (12:29 +0300)
committerJulien Grall <julien.grall@arm.com>
Mon, 10 Jun 2019 19:48:53 +0000 (20:48 +0100)
At the moment, interrupts are unmasked by gic_interrupt() before
calling do_{IRQ, LPI}(). In the case of handling an interrupt routed
to guests, its priority will be dropped, via desc->handler->end()
called from do_irq(), with interrupt unmasked.

In other words:
    - Until the priority is dropped, only higher priority interrupt
    can be received. Today, only Xen interrupts have higher priority.
    - As soon as priority is dropped, any interrupt can be received.

This means the purpose of the loop in gic_interrupt() is defeated as
all interrupts may get trapped earlier. To reinstate the purpose of
the loop (and prevent the trap), interrupts should be masked when
dropping the priority.

For interrupts routed to Xen, priority will always be dropped with
interrupts masked. So the issue is not present. However, it means
that we are pointless try to mask the interrupts.

To avoid conflicting behavior between interrupt handling,
gic_interrupt() is now keeping interrupts masked and defer the decision
to do_{LPI, IRQ}.

Signed-off-by: Andrii Anisov <andrii_anisov@epam.com>
[julien: Reword the commit message]
Acked-by: Julien Grall <julien.grall@arm.com>
xen/arch/arm/gic.c

index 6cc7dec7067ca584f5d74d5c7b9f35a2a17cd69b..113655a78943ffd3d6417ea8913fbce56fd6225c 100644 (file)
@@ -386,17 +386,13 @@ void gic_interrupt(struct cpu_user_regs *regs, int is_fiq)
 
         if ( likely(irq >= 16 && irq < 1020) )
         {
-            local_irq_enable();
             isb();
             do_IRQ(regs, irq, is_fiq);
-            local_irq_disable();
         }
         else if ( is_lpi(irq) )
         {
-            local_irq_enable();
             isb();
             gic_hw_ops->do_LPI(irq);
-            local_irq_disable();
         }
         else if ( unlikely(irq < 16) )
         {