• Christoffer Dall's avatar
    arm/arm64: KVM: Fix disabled distributor operation · 0d997491
    Christoffer Dall authored
    We currently do a single update of the vgic state when the distributor
    enable/disable control register is accessed and then bypass updating the
    state for as long as the distributor remains disabled.
    
    This is incorrect, because updating the state does not consider the
    distributor enable bit, and this you can end up in a situation where an
    interrupt is marked as pending on the CPU interface, but not pending on
    the distributor, which is an impossible state to be in, and triggers a
    warning.  Consider for example the following sequence of events:
    
    1. An interrupt is marked as pending on the distributor
       - the interrupt is also forwarded to the CPU interface
    2. The guest turns off the distributor (it's about to do a reboot)
       - we stop updating the CPU interface state from now on
    3. The guest disables the pending interrupt
       - we remove the pending state from the distributor, but don't touch
         the CPU interface, see point 2.
    
    Since the distributor disable bit really means that no interrupts should
    be forwarded to the CPU interface, we modify the code to keep updating
    the internal VGIC state, but always set the CPU interface pending bits
    to zero when the distributor is disabled.
    Signed-off-by: default avatarChristoffer Dall <christoffer.dall@linaro.org>
    0d997491
vgic.c 64.5 KB