Prior to commit e8cde32f111f ("arm64/cpufeatures/kvm: Add ARMv8.9 FEAT_ECBHB bits in ID_AA64MMFR1 register") KVM was erroneously masking FEAT_ECBHB from VMs, giving the perception that safe implementations are actually vulnerable to Spectre-BHB. And, after commit e403e8538359 ("arm64: errata: Assume that unknown CPUs _are_ vulnerable to Spectre BHB") guests are enabling the loop mitigation.
This broken virtual hardware is going to be around for some time, so do the ugly thing and check for revisions of Neoverse-V2 [1], Cortex-X3 [2], Cortex-A720 [3], and Neoverse-N3 [4] that are documented to have FEAT_ECBHB.
Cc: stable@vger.kernel.org Link: https://developer.arm.com/documentation/102375/0002 Link: https://developer.arm.com/documentation/101593/0102 Link: https://developer.arm.com/documentation/102530/0002 Link: https://developer.arm.com/documentation/107997/0001 Signed-off-by: Oliver Upton oliver.upton@linux.dev ---
I thoroughly hate this but the alternative of nuking these busted VMs isn't exactly popular...
arch/arm64/include/asm/cputype.h | 1 + arch/arm64/kernel/proton-pack.c | 16 ++++++++++++++++ 2 files changed, 17 insertions(+)
diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h index d1cc0571798b..5c6152e61cad 100644 --- a/arch/arm64/include/asm/cputype.h +++ b/arch/arm64/include/asm/cputype.h @@ -282,6 +282,7 @@ struct midr_range { #define MIDR_REV_RANGE(m, v, r_min, r_max) MIDR_RANGE(m, v, r_min, v, r_max) #define MIDR_REV(m, v, r) MIDR_RANGE(m, v, r, v, r) #define MIDR_ALL_VERSIONS(m) MIDR_RANGE(m, 0, 0, 0xf, 0xf) +#define MIDR_MIN_VERSION(m, v, r) MIDR_RANGE(m, v, r, 0xf, 0xf)
static inline bool midr_is_cpu_model_range(u32 midr, u32 model, u32 rv_min, u32 rv_max) diff --git a/arch/arm64/kernel/proton-pack.c b/arch/arm64/kernel/proton-pack.c index b198dde79e59..3d00d4c22d58 100644 --- a/arch/arm64/kernel/proton-pack.c +++ b/arch/arm64/kernel/proton-pack.c @@ -962,8 +962,24 @@ static bool has_spectre_bhb_fw_mitigation(void)
static bool supports_ecbhb(int scope) { + static const struct midr_range spectre_ecbhb_list[] = { + MIDR_MIN_VERSION(MIDR_NEOVERSE_V2, 0, 2), + MIDR_MIN_VERSION(MIDR_CORTEX_X3, 1, 1), + MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N3), + MIDR_MIN_VERSION(MIDR_CORTEX_A720, 0, 1), + {}, + }; u64 mmfr1;
+ /* + * Prior to commit e8cde32f111f ("arm64/cpufeatures/kvm: Add ARMv8.9 + * FEAT_ECBHB bits in ID_AA64MMFR1 register"), KVM masked FEAT_ECBHB + * on implementations that actually have the feature. That sucks; infer + * presence of FEAT_ECBHB based on MIDR. + */ + if (is_midr_in_range_list(spectre_ecbhb_list)) + return true; + if (scope == SCOPE_LOCAL_CPU) mmfr1 = read_sysreg_s(SYS_ID_AA64MMFR1_EL1); else
base-commit: b4432656b36e5cc1d50a1f2dc15357543add530e
On Thu, May 22, 2025 at 01:41:48PM -0700, Oliver Upton wrote:
Prior to commit e8cde32f111f ("arm64/cpufeatures/kvm: Add ARMv8.9 FEAT_ECBHB bits in ID_AA64MMFR1 register") KVM was erroneously masking FEAT_ECBHB from VMs, giving the perception that safe implementations are actually vulnerable to Spectre-BHB. And, after commit e403e8538359 ("arm64: errata: Assume that unknown CPUs _are_ vulnerable to Spectre BHB") guests are enabling the loop mitigation.
This broken virtual hardware is going to be around for some time, so do the ugly thing and check for revisions of Neoverse-V2 [1], Cortex-X3 [2], Cortex-A720 [3], and Neoverse-N3 [4] that are documented to have FEAT_ECBHB.
Cc: stable@vger.kernel.org Link: https://developer.arm.com/documentation/102375/0002 Link: https://developer.arm.com/documentation/101593/0102 Link: https://developer.arm.com/documentation/102530/0002 Link: https://developer.arm.com/documentation/107997/0001 Signed-off-by: Oliver Upton oliver.upton@linux.dev
I thoroughly hate this but the alternative of nuking these busted VMs isn't exactly popular...
arch/arm64/include/asm/cputype.h | 1 + arch/arm64/kernel/proton-pack.c | 16 ++++++++++++++++ 2 files changed, 17 insertions(+)
diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h index d1cc0571798b..5c6152e61cad 100644 --- a/arch/arm64/include/asm/cputype.h +++ b/arch/arm64/include/asm/cputype.h @@ -282,6 +282,7 @@ struct midr_range { #define MIDR_REV_RANGE(m, v, r_min, r_max) MIDR_RANGE(m, v, r_min, v, r_max) #define MIDR_REV(m, v, r) MIDR_RANGE(m, v, r, v, r) #define MIDR_ALL_VERSIONS(m) MIDR_RANGE(m, 0, 0, 0xf, 0xf) +#define MIDR_MIN_VERSION(m, v, r) MIDR_RANGE(m, v, r, 0xf, 0xf) static inline bool midr_is_cpu_model_range(u32 midr, u32 model, u32 rv_min, u32 rv_max) diff --git a/arch/arm64/kernel/proton-pack.c b/arch/arm64/kernel/proton-pack.c index b198dde79e59..3d00d4c22d58 100644 --- a/arch/arm64/kernel/proton-pack.c +++ b/arch/arm64/kernel/proton-pack.c @@ -962,8 +962,24 @@ static bool has_spectre_bhb_fw_mitigation(void) static bool supports_ecbhb(int scope) {
- static const struct midr_range spectre_ecbhb_list[] = {
MIDR_MIN_VERSION(MIDR_NEOVERSE_V2, 0, 2),
MIDR_MIN_VERSION(MIDR_CORTEX_X3, 1, 1),
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N3),
MIDR_MIN_VERSION(MIDR_CORTEX_A720, 0, 1),
{},
- }; u64 mmfr1;
- /*
* Prior to commit e8cde32f111f ("arm64/cpufeatures/kvm: Add ARMv8.9
* FEAT_ECBHB bits in ID_AA64MMFR1 register"), KVM masked FEAT_ECBHB
* on implementations that actually have the feature. That sucks; infer
* presence of FEAT_ECBHB based on MIDR.
*/
- if (is_midr_in_range_list(spectre_ecbhb_list))
return true;
I really don't think we want to go down this route.
If finer grained control of the spectre mitigations is needed, I think extending the existing command-line options is probably the best bet rather then inferring behaviours based on the MIDR.
Will
On Mon, Jun 02, 2025 at 01:08:31PM +0100, Will Deacon wrote:
On Thu, May 22, 2025 at 01:41:48PM -0700, Oliver Upton wrote:
- /*
* Prior to commit e8cde32f111f ("arm64/cpufeatures/kvm: Add ARMv8.9
* FEAT_ECBHB bits in ID_AA64MMFR1 register"), KVM masked FEAT_ECBHB
* on implementations that actually have the feature. That sucks; infer
* presence of FEAT_ECBHB based on MIDR.
*/
- if (is_midr_in_range_list(spectre_ecbhb_list))
return true;
I really don't think we want to go down this route.
Like I said, not a fan of doing this but...
If finer grained control of the spectre mitigations is needed, I think extending the existing command-line options is probably the best bet rather then inferring behaviours based on the MIDR.
Looks like all of the Neoverse-V2 based VMs available for rent are unintentionally hiding FEAT_ECBHB despite hardware support. I wouldn't expect CSPs to go and change this field after creating a VM, so that's a lot of hardware we're giving a poor experience on.
I just don't think a command-line switch is going to have any practical impact on the situation.
Thanks, Oliver
linux-stable-mirror@lists.linaro.org