Skip to content

Commit 9d449c7

Browse files
author
Marc Zyngier
committed
KVM: arm64: vgic-v3: Align emulated cpuif LPI state machine with the pseudocode
Having realised that a virtual LPI does transition through an active state that does not exist on bare metal, align the CPU interface emulation with the behaviour specified in the architecture pseudocode. The LPIs now transition to active on IAR read, and to inactive on EOI write. Special care is taken not to increment the EOIcount for an LPI that isn't present in the LRs. Signed-off-by: Marc Zyngier <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent f87ab68 commit 9d449c7

File tree

1 file changed

+8
-12
lines changed

1 file changed

+8
-12
lines changed

arch/arm64/kvm/hyp/vgic-v3-sr.c

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -695,9 +695,7 @@ static void __vgic_v3_read_iar(struct kvm_vcpu *vcpu, u32 vmcr, int rt)
695695
goto spurious;
696696

697697
lr_val &= ~ICH_LR_STATE;
698-
/* No active state for LPIs */
699-
if ((lr_val & ICH_LR_VIRTUAL_ID_MASK) <= VGIC_MAX_SPI)
700-
lr_val |= ICH_LR_ACTIVE_BIT;
698+
lr_val |= ICH_LR_ACTIVE_BIT;
701699
__gic_v3_set_lr(lr_val, lr);
702700
__vgic_v3_set_active_priority(lr_prio, vmcr, grp);
703701
vcpu_set_reg(vcpu, rt, lr_val & ICH_LR_VIRTUAL_ID_MASK);
@@ -764,20 +762,18 @@ static void __vgic_v3_write_eoir(struct kvm_vcpu *vcpu, u32 vmcr, int rt)
764762
/* Drop priority in any case */
765763
act_prio = __vgic_v3_clear_highest_active_priority();
766764

767-
/* If EOIing an LPI, no deactivate to be performed */
768-
if (vid >= VGIC_MIN_LPI)
769-
return;
770-
771-
/* EOImode == 1, nothing to be done here */
772-
if (vmcr & ICH_VMCR_EOIM_MASK)
773-
return;
774-
775765
lr = __vgic_v3_find_active_lr(vcpu, vid, &lr_val);
776766
if (lr == -1) {
777-
__vgic_v3_bump_eoicount();
767+
/* Do not bump EOIcount for LPIs that aren't in the LRs */
768+
if (!(vid >= VGIC_MIN_LPI))
769+
__vgic_v3_bump_eoicount();
778770
return;
779771
}
780772

773+
/* EOImode == 1 and not an LPI, nothing to be done here */
774+
if ((vmcr & ICH_VMCR_EOIM_MASK) && !(vid >= VGIC_MIN_LPI))
775+
return;
776+
781777
lr_prio = (lr_val & ICH_LR_PRIORITY_MASK) >> ICH_LR_PRIORITY_SHIFT;
782778

783779
/* If priorities or group do not match, the guest has fscked-up. */

0 commit comments

Comments
 (0)