• Christoffer Dall's avatar
    KVM: arm/arm64: vgic: Support level-triggered mapped interrupts · e40cc57b
    Christoffer Dall authored
    Level-triggered mapped IRQs are special because we only observe rising
    edges as input to the VGIC, and we don't set the EOI flag and therefore
    are not told when the level goes down, so that we can re-queue a new
    interrupt when the level goes up.
    
    One way to solve this problem is to side-step the logic of the VGIC and
    special case the validation in the injection path, but it has the
    unfortunate drawback of having to peak into the physical GIC state
    whenever we want to know if the interrupt is pending on the virtual
    distributor.
    
    Instead, we can maintain the current semantics of a level triggered
    interrupt by sort of treating it as an edge-triggered interrupt,
    following from the fact that we only observe an asserting edge.  This
    requires us to be a bit careful when populating the LRs and when folding
    the state back in though:
    
     * We lower the line level when populating the LR, so that when
       subsequently observing an asserting edge, the VGIC will do the right
       thing.
    
     * If the guest never acked the interrupt while running (for example if
       it had masked interrupts at the CPU level while running), we have
       to preserve the pending state of the LR and move it back to the
       line_level field of the struct irq when folding LR state.
    
       If the guest never acked the interrupt while running, but changed the
       device state and lowered the line (again with interrupts masked) then
       we need to observe this change in the line_level.
    
       Both of the above situations are solved by sampling the physical line
       and set the line level when folding the LR back.
    
     * Finally, if the guest never acked the interrupt while running and
       sampling the line reveals that the device state has changed and the
       line has been lowered, we must clear the physical active state, since
       we will otherwise never be told when the interrupt becomes asserted
       again.
    
    This has the added benefit of making the timer optimization patches
    (https://lists.cs.columbia.edu/pipermail/kvmarm/2017-July/026343.html) a
    bit simpler, because the timer code doesn't have to clear the active
    state on the sync anymore.  It also potentially improves the performance
    of the timer implementation because the GIC knows the state or the LR
    and only needs to clear the
    active state when the pending bit in the LR is still set, where the
    timer has to always clear it when returning from running the guest with
    an injected timer interrupt.
    Reviewed-by: default avatarMarc Zyngier <marc.zyngier@arm.com>
    Reviewed-by: default avatarEric Auger <eric.auger@redhat.com>
    Signed-off-by: default avatarChristoffer Dall <christoffer.dall@linaro.org>
    e40cc57b
vgic.c 22.2 KB