Skip to content

Commit d11a327

Browse files
author
Marc Zyngier
committed
KVM: arm64: vgic-v3: Restrict SEIS workaround to known broken systems
Contrary to what df652bc ("KVM: arm64: vgic-v3: Work around GICv3 locally generated SErrors") was asserting, there is at least one other system out there (Cavium ThunderX2) implementing SEIS, and not in an obviously broken way. So instead of imposing the M1 workaround on an innocent bystander, let's limit it to the two known broken Apple implementations. Fixes: df652bc ("KVM: arm64: vgic-v3: Work around GICv3 locally generated SErrors") Reported-by: Ard Biesheuvel <[email protected]> Tested-by: Ard Biesheuvel <[email protected]> Acked-by: Ard Biesheuvel <[email protected]> Signed-off-by: Marc Zyngier <[email protected]> Cc: [email protected] Link: https://lore.kernel.org/r/[email protected]
1 parent 094d00f commit d11a327

File tree

2 files changed

+18
-2
lines changed

2 files changed

+18
-2
lines changed

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -983,6 +983,9 @@ static void __vgic_v3_read_ctlr(struct kvm_vcpu *vcpu, u32 vmcr, int rt)
983983
val = ((vtr >> 29) & 7) << ICC_CTLR_EL1_PRI_BITS_SHIFT;
984984
/* IDbits */
985985
val |= ((vtr >> 23) & 7) << ICC_CTLR_EL1_ID_BITS_SHIFT;
986+
/* SEIS */
987+
if (kvm_vgic_global_state.ich_vtr_el2 & ICH_VTR_SEIS_MASK)
988+
val |= BIT(ICC_CTLR_EL1_SEIS_SHIFT);
986989
/* A3V */
987990
val |= ((vtr >> 21) & 1) << ICC_CTLR_EL1_A3V_SHIFT;
988991
/* EOImode */

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

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -609,6 +609,18 @@ static int __init early_gicv4_enable(char *buf)
609609
}
610610
early_param("kvm-arm.vgic_v4_enable", early_gicv4_enable);
611611

612+
static const struct midr_range broken_seis[] = {
613+
MIDR_ALL_VERSIONS(MIDR_APPLE_M1_ICESTORM),
614+
MIDR_ALL_VERSIONS(MIDR_APPLE_M1_FIRESTORM),
615+
{},
616+
};
617+
618+
static bool vgic_v3_broken_seis(void)
619+
{
620+
return ((kvm_vgic_global_state.ich_vtr_el2 & ICH_VTR_SEIS_MASK) &&
621+
is_midr_in_range_list(read_cpuid_id(), broken_seis));
622+
}
623+
612624
/**
613625
* vgic_v3_probe - probe for a VGICv3 compatible interrupt controller
614626
* @info: pointer to the GIC description
@@ -676,9 +688,10 @@ int vgic_v3_probe(const struct gic_kvm_info *info)
676688
group1_trap = true;
677689
}
678690

679-
if (kvm_vgic_global_state.ich_vtr_el2 & ICH_VTR_SEIS_MASK) {
680-
kvm_info("GICv3 with locally generated SEI\n");
691+
if (vgic_v3_broken_seis()) {
692+
kvm_info("GICv3 with broken locally generated SEI\n");
681693

694+
kvm_vgic_global_state.ich_vtr_el2 &= ~ICH_VTR_SEIS_MASK;
682695
group0_trap = true;
683696
group1_trap = true;
684697
if (ich_vtr_el2 & ICH_VTR_TDS_MASK)

0 commit comments

Comments
 (0)