[RFC PATCH] KVM: arm64: Override Microsoft Azure Cobalt 100 MIDR value with ARM Neoverse N2

Easwar Hariharan eahariha at linux.microsoft.com
Tue Feb 6 11:58:16 PST 2024


Several workload optimizations and errata depend on validating that the
optimization or errata are applicable to the particular CPU by checking
the MIDR_EL1 system register value. With the Microsoft implementer ID
for Azure Cobalt 100, the value doesn't match and ~20-25% performance
regression is seen in these workloads. Override the Azure Cobalt 100
value and replace it with the default ARM Neoverse N2 value that Azure
Cobalt 100 is based on.

Signed-off-by: Easwar Hariharan <eahariha at linux.microsoft.com>
---
 arch/arm64/include/asm/cputype.h   | 3 ++-
 arch/arm64/include/asm/el2_setup.h | 5 +++++
 arch/arm64/kvm/sys_regs.c          | 9 ++++++++-
 3 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index 7c7493cb571f..0450c6c32377 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -262,7 +262,8 @@ is_midr_in_range_list(u32 midr, struct midr_range const *ranges)
  */
 static inline u32 __attribute_const__ read_cpuid_id(void)
 {
-	return read_cpuid(MIDR_EL1);
+	return (read_cpuid(MIDR_EL1) == 0x6D0FD490 ? 0x410FD490 :
+			read_cpuid(MIDR_EL1));
 }
 
 static inline u64 __attribute_const__ read_cpuid_mpidr(void)
diff --git a/arch/arm64/include/asm/el2_setup.h b/arch/arm64/include/asm/el2_setup.h
index b7afaa026842..502a14e54a31 100644
--- a/arch/arm64/include/asm/el2_setup.h
+++ b/arch/arm64/include/asm/el2_setup.h
@@ -138,6 +138,11 @@
 .macro __init_el2_nvhe_idregs
 	mrs	x0, midr_el1
 	mrs	x1, mpidr_el1
+	ldr	x2, =0x6D0FD490
+	cmp	x0, x2
+	bne	.Loverride_cobalt100_\@
+	ldr	x0, =0x410FD490
+.Loverride_cobalt100_\@:
 	msr	vpidr_el2, x0
 	msr	vmpidr_el2, x1
 .endm
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 30253bd19917..8ea9c7fdabdb 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -3574,7 +3574,14 @@ id_to_sys_reg_desc(struct kvm_vcpu *vcpu, u64 id,
 		return ((struct sys_reg_desc *)r)->val;			\
 	}
 
-FUNCTION_INVARIANT(midr_el1)
+static u64 get_midr_el1(struct kvm_vcpu *v, const struct sys_reg_desc *r)
+{
+	((struct sys_reg_desc *)r)->val = read_sysreg(midr_el1);
+	if (((struct sys_reg_desc *)r)->val == 0x6D0FD490)
+		((struct sys_reg_desc *)r)->val == 0x410FD490;
+	return ((struct sys_reg_desc *)r)->val;
+}
+
 FUNCTION_INVARIANT(revidr_el1)
 FUNCTION_INVARIANT(aidr_el1)
 
-- 
2.34.1




More information about the linux-arm-kernel mailing list