From 0d6ed39333f6534a9909ea37d390982153e713e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Mon, 18 Nov 2019 16:39:09 -0500 Subject: [PATCH] target/arm: generate a custom MIDR for -cpu max While most features are now detected by probing the ID_* registers kernels can (and do) use MIDR_EL1 for working out of they have to apply errata. This can trip up warnings in the kernel as it tries to work out if it should apply workarounds to features that don't actually exist in the reported CPU type. Avoid this problem by synthesising our own MIDR value. Backports commit 2bd5f41c00686a1f847a60824d0375f3df2c26bf from qemu --- qemu/target/arm/cpu.h | 6 ++++++ qemu/target/arm/cpu64.c | 19 +++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/qemu/target/arm/cpu.h b/qemu/target/arm/cpu.h index 533b8aa8..87b0b401 100644 --- a/qemu/target/arm/cpu.h +++ b/qemu/target/arm/cpu.h @@ -1552,6 +1552,12 @@ FIELD(V7M_FPCCR, ASPEN, 31, 1) /* * System register ID fields. */ +FIELD(MIDR_EL1, REVISION, 0, 4) +FIELD(MIDR_EL1, PARTNUM, 4, 12) +FIELD(MIDR_EL1, ARCHITECTURE, 16, 4) +FIELD(MIDR_EL1, VARIANT, 20, 4) +FIELD(MIDR_EL1, IMPLEMENTER, 24, 8) + FIELD(ID_ISAR0, SWAP, 0, 4) FIELD(ID_ISAR0, BITCOUNT, 4, 4) FIELD(ID_ISAR0, BITFIELD, 8, 4) diff --git a/qemu/target/arm/cpu64.c b/qemu/target/arm/cpu64.c index c01269b2..bf9ca9e0 100644 --- a/qemu/target/arm/cpu64.c +++ b/qemu/target/arm/cpu64.c @@ -255,6 +255,25 @@ static void aarch64_max_initfn(struct uc_struct *uc, Object *obj, void *opaque) aarch64_a57_initfn(uc, obj, opaque); + /* + * Reset MIDR so the guest doesn't mistake our 'max' CPU type for a real + * one and try to apply errata workarounds or use impdef features we + * don't provide. + * An IMPLEMENTER field of 0 means "reserved for software use"; + * ARCHITECTURE must be 0xf indicating "v7 or later, check ID registers + * to see which features are present"; + * the VARIANT, PARTNUM and REVISION fields are all implementation + * defined and we choose to define PARTNUM just in case guest + * code needs to distinguish this QEMU CPU from other software + * implementations, though this shouldn't be needed. + */ + t = FIELD_DP64(0, MIDR_EL1, IMPLEMENTER, 0); + t = FIELD_DP64(t, MIDR_EL1, ARCHITECTURE, 0xf); + t = FIELD_DP64(t, MIDR_EL1, PARTNUM, 'Q'); + t = FIELD_DP64(t, MIDR_EL1, VARIANT, 0); + t = FIELD_DP64(t, MIDR_EL1, REVISION, 0); + cpu->midr = t; + t = cpu->isar.id_aa64isar0; t = FIELD_DP64(t, ID_AA64ISAR0, AES, 2); /* AES + PMULL */ t = FIELD_DP64(t, ID_AA64ISAR0, SHA1, 1);