KVM: arm64: Fix CPU interface MMIO compatibility detection
Marc Zyngier
maintainerPATCH 1/1 KVM: arm64: Fix CPU interface MMIO compatibility detection
In order to detect whether a GICv3 CPU interface is MMIO capable, we switch ICC_SRE_EL1.SRE to 0 and check whether it sticks.
However, this is only possible if *ALL* of the HCR_EL2 interrupt overrides are set, and the CPU is perfectly allowed to ignore the write to ICC_SRE_EL1 otherwise. This leads KVM to pretend that a whole bunch of ARMv8.0 CPUs aren't MMIO-capable, and breaks VMs that should work correctly otherwise.
Fix this by setting IMO/FMO/IMO before touching ICC_SRE_EL1, and clear them afterwards. This allows us to reliably detect the CPU interface capabilities.
--- arch/arm64/kvm/hyp/vgic-v3-sr.c | 9 +++++++++ 1 file changed, 9 insertions(+)
arch/arm64/kvm/hyp/vgic-v3-sr.c +9 -0
@@ -429,6 +429,13 @@ u64 __vgic_v3_get_gic_config(void)if (has_vhe ()) flags =local_daif_save (); +/* +* Table 11-2 "Permitted ICC_SRE_ELx.SRE settings" indicates +* that to be able to set ICC_SRE_EL1.SRE to 0, all the +* interrupt overrides must be set. You've got to love this. +*/ +sysreg_clear_set (hcr_el2,0 ,HCR_AMO |HCR_FMO |HCR_IMO ); +isb ();write_gicreg (0 ,ICC_SRE_EL1 );isb ();
@@ -436,6 +443,8 @@ u64 __vgic_v3_get_gic_config(void)write_gicreg (sre,ICC_SRE_EL1 );isb (); +sysreg_clear_set (hcr_el2,HCR_AMO |HCR_FMO |HCR_IMO ,0 ); +isb ();if (has_vhe ())local_daif_restore (flags);
Signature · 6 lines
2.30.0 _______________________________________________ kvmarm mailing list [email protected] https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Quoted 20 lines
-----Original Message-----
From: Marc Zyngier [mailto:[email protected]]
Sent: 23 March 2021 16:23
To: [email protected]; [email protected]; [email protected]
Cc: Ard Biesheuvel <[email protected]>; [email protected]; Shameerali Kolothum Thodi <[email protected]>
Subject: [PATCH] KVM: arm64: Fix CPU interface MMIO compatibility detectionIn order to detect whether a GICv3 CPU interface is MMIO capable, we switch ICC_SRE_EL1.SRE to 0 and check whether it sticks.
However, this is only possible if *ALL* of the
HCR_EL2interrupt overrides are set, and the CPU is perfectly allowed to ignore the write toICC_SRE_EL1otherwise. This leads KVM to pretend that a whole bunch of ARMv8.0 CPUs aren't MMIO-capable, and breaks VMs that should work correctly otherwise.
Quoted 4 lines
Fix this by setting IMO/FMO/IMO before touching
ICC_SRE_EL1, and clear them afterwards. This allows us to reliably detect the CPU interface capabilities.
Tested on HiSilicon D06 platform where the original issue(firmware wrongly advertising GICv2-on-v3 compatibility) was reported and all seems to be fine.
Though not sure whether this fix is relevant to this particular platform, FWIW,
Thanks,
Shameer
Quoted 37 lines
Cc Shameerali Kolothum Thodi <[email protected]>Fixes 9739f6ef053f ("KVM: arm64: Workaround firmware wrongly advertisingGICv2-on-v3 compatibility")
Signed-off-by Marc Zyngier <[email protected]>--- arch/arm64/kvm/hyp/vgic-v3-sr.c | 9 +++++++++ 1 file changed, 9 insertions(+)arch/arm64/kvm/hyp/vgic-v3-sr.c +9
-1@@ -429,6 +429,13 @@ u64 __vgic_v3_get_gic_config(void)if (has_vhe ()) flags =local_daif_save (); +/* +* Table 11-2 "Permitted ICC_SRE_ELx.SRE settings" indicates +* that to be able to set ICC_SRE_EL1.SRE to 0, all the +* interrupt overrides must be set. You've got to love this. +*/ +sysreg_clear_set (hcr_el2,0 ,HCR_AMO |HCR_FMO |HCR_IMO ); +isb ();write_gicreg (0 ,ICC_SRE_EL1 );isb ();@@ -436,6 +443,8 @@ u64 __vgic_v3_get_gic_config(void)write_gicreg (sre,ICC_SRE_EL1 );isb (); +sysreg_clear_set (hcr_el2,HCR_AMO |HCR_FMO |HCR_IMO ,0 ); +isb ();if (has_vhe ())local_daif_restore (flags); --
Quoted 1 line
2.30.0
_______________________________________________
kvmarm mailing list
[email protected]
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm