* [PATCH v3 for-11.2 01/10] target/arm/cpu-sysregs.h.inc: Sort by name alphabetical order
2026-10-30 7:28 [PATCH v3 for-11.2 00/10] kvm/arm: Some refactoring for custom KVM host model Eric Auger
@ 2026-10-30 7:28 ` Eric Auger
2026-10-30 7:28 ` [PATCH v3 for-11.2 02/10] target/arm: Move REVIDR into isar.idregs[] storage Eric Auger
` (8 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Eric Auger @ 2026-10-30 7:28 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, peter.maydell,
shaju.abraham, khushit.shah, richard.henderson, pbonzini,
skolothumtho, philmd, 7746591750, maobibo, harshpb, amachhiw,
daniel.barboza, milesg, farman, cohuck, alireza.sanaee
Cc: armbru, mbawa
Sort by register name alphabetical order. This will allow to
easily diff with the future content, automatically generated.
No functional change intended.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
Reviewed-by: Shameer Kolothum <skolothumtho@nvidia.com>
Reviewed-by: Khushit Shah <khushit.shah@nutanix.com>
---
v5 -> v6:
- v5 version conflicted because ID_AA64FPFR0_EL1 has been
added
v4 -> v5:
- remove spurious CCSIDR definition
---
target/arm/cpu-sysregs.h.inc | 46 ++++++++++++++++++------------------
1 file changed, 23 insertions(+), 23 deletions(-)
diff --git a/target/arm/cpu-sysregs.h.inc b/target/arm/cpu-sysregs.h.inc
index d9e058a57e..b5c7970971 100644
--- a/target/arm/cpu-sysregs.h.inc
+++ b/target/arm/cpu-sysregs.h.inc
@@ -1,13 +1,13 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
-DEF(ID_AA64PFR0_EL1, 3, 0, 0, 4, 0)
-DEF(ID_AA64PFR1_EL1, 3, 0, 0, 4, 1)
-DEF(ID_AA64PFR2_EL1, 3, 0, 0, 4, 2)
-DEF(ID_AA64SMFR0_EL1, 3, 0, 0, 4, 5)
-DEF(ID_AA64FPFR0_EL1, 3, 0, 0, 4, 7)
-DEF(ID_AA64DFR0_EL1, 3, 0, 0, 5, 0)
-DEF(ID_AA64DFR1_EL1, 3, 0, 0, 5, 1)
+DEF_MUX(CCSIDR_EL1, 3, 1, 0, 0, 0, 16)
+DEF(CLIDR_EL1, 3, 1, 0, 0, 1)
+DEF(CTR_EL0, 3, 3, 0, 0, 1)
+DEF(DCZID_EL0, 3, 3, 0, 0, 7)
DEF(ID_AA64AFR0_EL1, 3, 0, 0, 5, 4)
DEF(ID_AA64AFR1_EL1, 3, 0, 0, 5, 5)
+DEF(ID_AA64DFR0_EL1, 3, 0, 0, 5, 0)
+DEF(ID_AA64DFR1_EL1, 3, 0, 0, 5, 1)
+DEF(ID_AA64FPFR0_EL1, 3, 0, 0, 4, 7)
DEF(ID_AA64ISAR0_EL1, 3, 0, 0, 6, 0)
DEF(ID_AA64ISAR1_EL1, 3, 0, 0, 6, 1)
DEF(ID_AA64ISAR2_EL1, 3, 0, 0, 6, 2)
@@ -17,30 +17,30 @@ DEF(ID_AA64MMFR1_EL1, 3, 0, 0, 7, 1)
DEF(ID_AA64MMFR2_EL1, 3, 0, 0, 7, 2)
DEF(ID_AA64MMFR3_EL1, 3, 0, 0, 7, 3)
DEF(ID_AA64MMFR4_EL1, 3, 0, 0, 7, 4)
-DEF(ID_PFR0_EL1, 3, 0, 0, 1, 0)
-DEF(ID_PFR1_EL1, 3, 0, 0, 1, 1)
-DEF(ID_DFR0_EL1, 3, 0, 0, 1, 2)
+DEF(ID_AA64PFR0_EL1, 3, 0, 0, 4, 0)
+DEF(ID_AA64PFR1_EL1, 3, 0, 0, 4, 1)
+DEF(ID_AA64PFR2_EL1, 3, 0, 0, 4, 2)
+DEF(ID_AA64SMFR0_EL1, 3, 0, 0, 4, 5)
+DEF(ID_AA64ZFR0_EL1, 3, 0, 0, 4, 4)
DEF(ID_AFR0_EL1, 3, 0, 0, 1, 3)
-DEF(ID_MMFR0_EL1, 3, 0, 0, 1, 4)
-DEF(ID_MMFR1_EL1, 3, 0, 0, 1, 5)
-DEF(ID_MMFR2_EL1, 3, 0, 0, 1, 6)
-DEF(ID_MMFR3_EL1, 3, 0, 0, 1, 7)
+DEF(ID_DFR0_EL1, 3, 0, 0, 1, 2)
+DEF(ID_DFR1_EL1, 3, 0, 0, 3, 5)
DEF(ID_ISAR0_EL1, 3, 0, 0, 2, 0)
DEF(ID_ISAR1_EL1, 3, 0, 0, 2, 1)
DEF(ID_ISAR2_EL1, 3, 0, 0, 2, 2)
DEF(ID_ISAR3_EL1, 3, 0, 0, 2, 3)
DEF(ID_ISAR4_EL1, 3, 0, 0, 2, 4)
DEF(ID_ISAR5_EL1, 3, 0, 0, 2, 5)
-DEF(ID_MMFR4_EL1, 3, 0, 0, 2, 6)
DEF(ID_ISAR6_EL1, 3, 0, 0, 2, 7)
+DEF(ID_MMFR0_EL1, 3, 0, 0, 1, 4)
+DEF(ID_MMFR1_EL1, 3, 0, 0, 1, 5)
+DEF(ID_MMFR2_EL1, 3, 0, 0, 1, 6)
+DEF(ID_MMFR3_EL1, 3, 0, 0, 1, 7)
+DEF(ID_MMFR4_EL1, 3, 0, 0, 2, 6)
+DEF(ID_MMFR5_EL1, 3, 0, 0, 3, 6)
+DEF(ID_PFR0_EL1, 3, 0, 0, 1, 0)
+DEF(ID_PFR1_EL1, 3, 0, 0, 1, 1)
+DEF(ID_PFR2_EL1, 3, 0, 0, 3, 4)
DEF(MVFR0_EL1, 3, 0, 0, 3, 0)
DEF(MVFR1_EL1, 3, 0, 0, 3, 1)
DEF(MVFR2_EL1, 3, 0, 0, 3, 2)
-DEF(ID_PFR2_EL1, 3, 0, 0, 3, 4)
-DEF(ID_DFR1_EL1, 3, 0, 0, 3, 5)
-DEF(ID_MMFR5_EL1, 3, 0, 0, 3, 6)
-DEF_MUX(CCSIDR_EL1, 3, 1, 0, 0, 0, 16)
-DEF(CLIDR_EL1, 3, 1, 0, 0, 1)
-DEF(ID_AA64ZFR0_EL1, 3, 0, 0, 4, 4)
-DEF(CTR_EL0, 3, 3, 0, 0, 1)
-DEF(DCZID_EL0, 3, 3, 0, 0, 7)
--
2.53.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH v3 for-11.2 02/10] target/arm: Move REVIDR into isar.idregs[] storage
2026-10-30 7:28 [PATCH v3 for-11.2 00/10] kvm/arm: Some refactoring for custom KVM host model Eric Auger
2026-10-30 7:28 ` [PATCH v3 for-11.2 01/10] target/arm/cpu-sysregs.h.inc: Sort by name alphabetical order Eric Auger
@ 2026-10-30 7:28 ` Eric Auger
2026-10-30 7:28 ` [PATCH v3 for-11.2 03/10] target/arm: Move MIDR " Eric Auger
` (7 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Eric Auger @ 2026-10-30 7:28 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, peter.maydell,
shaju.abraham, khushit.shah, richard.henderson, pbonzini,
skolothumtho, philmd, 7746591750, maobibo, harshpb, amachhiw,
daniel.barboza, milesg, farman, cohuck, alireza.sanaee
Cc: armbru, mbawa
Move REVIDR into the isar.idregs[] array as other ID registers.
This will allow to overwrite it as others.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Suggested-by: Khushit Shah <khushit.shah@nutanix.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Sebastian Ott <sebott@redhat.com>
Reviewed-by: Khushit Shah <khushit.shah@nutanix.com>
---
target/arm/cpu.h | 1 -
target/arm/cpu-sysregs.h.inc | 1 +
hw/intc/armv7m_nvic.c | 2 +-
target/arm/cpu-max.c | 2 +-
target/arm/cpu64.c | 2 +-
target/arm/helper.c | 2 +-
target/arm/tcg/cpu-v7m.c | 4 ++--
target/arm/tcg/cpu32.c | 4 ++--
target/arm/tcg/cpu64.c | 20 ++++++++++----------
9 files changed, 19 insertions(+), 19 deletions(-)
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index add993ef10..c811369e63 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1126,7 +1126,6 @@ struct ArchCPU {
uint64_t idregs[NUM_ID_IDX];
} isar;
uint64_t midr;
- uint32_t revidr;
uint32_t reset_fpsid;
uint64_t ctr;
uint32_t reset_sctlr;
diff --git a/target/arm/cpu-sysregs.h.inc b/target/arm/cpu-sysregs.h.inc
index b5c7970971..580d88d1f4 100644
--- a/target/arm/cpu-sysregs.h.inc
+++ b/target/arm/cpu-sysregs.h.inc
@@ -44,3 +44,4 @@ DEF(ID_PFR2_EL1, 3, 0, 0, 3, 4)
DEF(MVFR0_EL1, 3, 0, 0, 3, 0)
DEF(MVFR1_EL1, 3, 0, 0, 3, 1)
DEF(MVFR2_EL1, 3, 0, 0, 3, 2)
+DEF(REVIDR_EL1, 3, 0, 0, 0, 6)
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index 6bc392b0e3..1f56fff046 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -1051,7 +1051,7 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
if (!arm_feature(&cpu->env, ARM_FEATURE_V8_1M)) {
goto bad_offset;
}
- return cpu->revidr;
+ return GET_IDREG(isar, REVIDR);
case 0xd00: /* CPUID Base. */
return cpu->midr;
case 0xd04: /* Interrupt Control State (ICSR) */
diff --git a/target/arm/cpu-max.c b/target/arm/cpu-max.c
index 2ed1cfef9b..b4e57a167d 100644
--- a/target/arm/cpu-max.c
+++ b/target/arm/cpu-max.c
@@ -37,7 +37,7 @@ void aarch64_aa32_a57_init(ARMCPU *cpu, bool aarch64_enabled)
cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A57;
}
cpu->midr = 0x411fd070;
- cpu->revidr = 0x00000000;
+ SET_IDREG(isar, REVIDR, 0);
cpu->reset_fpsid = 0x41034070;
cpu->isar.mvfr0 = 0x10110222;
cpu->isar.mvfr1 = 0x12111111;
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index dcd0d698b3..80c9c9e5b3 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -717,7 +717,7 @@ static void aarch64_a53_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_PMU);
cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A53;
cpu->midr = 0x410fd034;
- cpu->revidr = 0x00000100;
+ SET_IDREG(isar, REVIDR, 0x00000100);
cpu->reset_fpsid = 0x41034070;
cpu->isar.mvfr0 = 0x10110222;
cpu->isar.mvfr1 = 0x12111111;
diff --git a/target/arm/helper.c b/target/arm/helper.c
index b540705e63..8c78370626 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -7453,7 +7453,7 @@ void register_cp_regs_for_features(ARMCPU *cpu)
.access = PL1_R,
.accessfn = access_tid1,
.fgt = FGT_REVIDR_EL1,
- .type = ARM_CP_CONST, .resetvalue = cpu->revidr },
+ .type = ARM_CP_CONST, .resetvalue = GET_IDREG(&cpu->isar, REVIDR) },
};
ARMCPRegInfo id_v8_midr_alias_cp_reginfo = {
.name = "MIDR", .type = ARM_CP_ALIAS | ARM_CP_CONST | ARM_CP_NO_GDB,
diff --git a/target/arm/tcg/cpu-v7m.c b/target/arm/tcg/cpu-v7m.c
index 1093c6cbf6..9a5512aa55 100644
--- a/target/arm/tcg/cpu-v7m.c
+++ b/target/arm/tcg/cpu-v7m.c
@@ -211,7 +211,7 @@ static void cortex_m55_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_M_SECURITY);
set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
cpu->midr = 0x410fd221; /* r0p1 */
- cpu->revidr = 0;
+ SET_IDREG(isar, REVIDR, 0);
cpu->pmsav7_dregion = 16;
cpu->sau_sregion = 8;
/* These are the MVFR* values for the FPU + full MVE configuration */
@@ -249,7 +249,7 @@ static void cortex_m85_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_M_SECURITY);
set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
cpu->midr = 0x411fd231; /* r1p1 */
- cpu->revidr = 0;
+ SET_IDREG(isar, REVIDR, 0);
cpu->pmsav7_dregion = 16;
cpu->sau_sregion = 8;
/* These are the MVFR* values for the FPU + full MVE configuration */
diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c
index f95051458d..c02b737fc0 100644
--- a/target/arm/tcg/cpu32.c
+++ b/target/arm/tcg/cpu32.c
@@ -456,7 +456,7 @@ static void cortex_a15_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_PMU);
/* r4p0 cpu, not requiring expensive tlb flush errata */
cpu->midr = 0x414fc0f0;
- cpu->revidr = 0x0;
+ SET_IDREG(isar, REVIDR, 0);
cpu->reset_fpsid = 0x410430f0;
cpu->isar.mvfr0 = 0x10110222;
cpu->isar.mvfr1 = 0x11111111;
@@ -647,7 +647,7 @@ static void cortex_r52_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
set_feature(&cpu->env, ARM_FEATURE_AUXCR);
cpu->midr = 0x411fd133; /* r1p3 */
- cpu->revidr = 0x00000000;
+ SET_IDREG(isar, REVIDR, 0);
cpu->reset_fpsid = 0x41034023;
cpu->isar.mvfr0 = 0x10110222;
cpu->isar.mvfr1 = 0x12111111;
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
index c92e331e73..7af29978c6 100644
--- a/target/arm/tcg/cpu64.c
+++ b/target/arm/tcg/cpu64.c
@@ -48,7 +48,7 @@ static void aarch64_a35_initfn(Object *obj)
/* From B2.2 AArch64 identification registers. */
cpu->midr = 0x411fd040;
- cpu->revidr = 0;
+ SET_IDREG(isar, REVIDR, 0);
cpu->ctr = 0x84448004;
SET_IDREG(isar, ID_PFR0, 0x00000131);
SET_IDREG(isar, ID_PFR1, 0x00011011);
@@ -248,7 +248,7 @@ static void aarch64_a55_initfn(Object *obj)
SET_IDREG(isar, ID_PFR1, 0x00011011);
SET_IDREG(isar, ID_PFR2, 0x00000011);
cpu->midr = 0x412FD050; /* r2p0 */
- cpu->revidr = 0;
+ SET_IDREG(isar, REVIDR, 0);
/* From B2.23 CCSIDR_EL1 */
/* 32KB L1 dcache */
@@ -292,7 +292,7 @@ static void aarch64_a72_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_EL3);
set_feature(&cpu->env, ARM_FEATURE_PMU);
cpu->midr = 0x410fd083;
- cpu->revidr = 0x00000000;
+ SET_IDREG(isar, REVIDR, 0);
cpu->reset_fpsid = 0x41034080;
cpu->isar.mvfr0 = 0x10110222;
cpu->isar.mvfr1 = 0x12111111;
@@ -383,7 +383,7 @@ static void aarch64_a76_initfn(Object *obj)
SET_IDREG(isar, ID_PFR1, 0x00010000); /* GIC filled in later */
SET_IDREG(isar, ID_PFR2, 0x00000011);
cpu->midr = 0x414fd0b1; /* r4p1 */
- cpu->revidr = 0;
+ SET_IDREG(isar, REVIDR, 0);
/* From B2.18 CCSIDR_EL1 */
/* 64KB L1 dcache */
@@ -456,7 +456,7 @@ static void aarch64_a78ae_initfn(Object *obj)
SET_IDREG(isar, ID_PFR1, 0x00010000); /* GIC filled in later */
SET_IDREG(isar, ID_PFR2, 0x00000011);
cpu->midr = 0x410fd423; /* r0p3 */
- cpu->revidr = 0;
+ SET_IDREG(isar, REVIDR, 0);
/* From 3.2.33 CCSIDR_EL1 */
/* 64KB L1 dcache */
@@ -501,7 +501,7 @@ static void aarch64_a64fx_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_EL3);
set_feature(&cpu->env, ARM_FEATURE_PMU);
cpu->midr = 0x461f0010;
- cpu->revidr = 0x00000000;
+ SET_IDREG(isar, REVIDR, 0);
cpu->ctr = 0x86668006;
cpu->reset_sctlr = 0x30000180;
SET_IDREG(isar, ID_AA64PFR0, 0x0000000101111111); /* No RAS Extensions */
@@ -707,7 +707,7 @@ static void aarch64_neoverse_n1_initfn(Object *obj)
SET_IDREG(isar, ID_PFR1, 0x00010000); /* GIC filled in later */
SET_IDREG(isar, ID_PFR2, 0x00000011);
cpu->midr = 0x414fd0c1; /* r4p1 */
- cpu->revidr = 0;
+ SET_IDREG(isar, REVIDR, 0);
/* From B2.23 CCSIDR_EL1 */
/* 64KB L1 dcache */
@@ -787,7 +787,7 @@ static void aarch64_neoverse_v1_initfn(Object *obj)
SET_IDREG(isar, ID_PFR1, 0x00010000); /* GIC filled in later */
SET_IDREG(isar, ID_PFR2, 0x00000011);
cpu->midr = 0x411FD402; /* r1p2 */
- cpu->revidr = 0;
+ SET_IDREG(isar, REVIDR, 0);
/*
* The Neoverse-V1 r1p2 TRM lists 32-bit format CCSIDR_EL1 values,
@@ -984,7 +984,7 @@ static void aarch64_a710_initfn(Object *obj)
/* Ordered by Section B.4: AArch64 registers */
cpu->midr = 0x412FD471; /* r2p1 */
- cpu->revidr = 0;
+ SET_IDREG(isar, REVIDR, 0);
SET_IDREG(isar, ID_PFR0, 0x21110131);
SET_IDREG(isar, ID_PFR1, 0x00010000); /* GIC filled in later */
SET_IDREG(isar, ID_DFR0, 0x16011099);
@@ -1087,7 +1087,7 @@ static void aarch64_neoverse_n2_initfn(Object *obj)
/* Ordered by Section B.5: AArch64 ID registers */
cpu->midr = 0x410FD493; /* r0p3 */
- cpu->revidr = 0;
+ SET_IDREG(isar, REVIDR, 0);
SET_IDREG(isar, ID_PFR0, 0x21110131);
SET_IDREG(isar, ID_PFR1, 0x00010000); /* GIC filled in later */
SET_IDREG(isar, ID_DFR0, 0x16011099);
--
2.53.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH v3 for-11.2 03/10] target/arm: Move MIDR into isar.idregs[] storage
2026-10-30 7:28 [PATCH v3 for-11.2 00/10] kvm/arm: Some refactoring for custom KVM host model Eric Auger
2026-10-30 7:28 ` [PATCH v3 for-11.2 01/10] target/arm/cpu-sysregs.h.inc: Sort by name alphabetical order Eric Auger
2026-10-30 7:28 ` [PATCH v3 for-11.2 02/10] target/arm: Move REVIDR into isar.idregs[] storage Eric Auger
@ 2026-10-30 7:28 ` Eric Auger
2026-10-30 7:28 ` [PATCH v3 for-11.2 04/10] target/arm: Enforce MPIDR " Eric Auger
` (6 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Eric Auger @ 2026-10-30 7:28 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, peter.maydell,
shaju.abraham, khushit.shah, richard.henderson, pbonzini,
skolothumtho, philmd, 7746591750, maobibo, harshpb, amachhiw,
daniel.barboza, milesg, farman, cohuck, alireza.sanaee
Cc: armbru, mbawa
Move MIDR into the isar.idregs[] array as other ID registers.
This will allow to overwrite it as others.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Suggested-by: Khushit Shah <khushit.shah@nutanix.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Sebastian Ott <sebott@redhat.com>
Reviewed-by: Khushit Shah <khushit.shah@nutanix.com>
----
Fix conversion oversight in ./linux-user/arm/target_proc.h
---
linux-user/arm/target_proc.h | 13 +++++++------
target/arm/cpu.h | 1 -
target/arm/cpu-sysregs.h.inc | 1 +
hw/intc/armv7m_nvic.c | 2 +-
target/arm/cpu-max.c | 2 +-
target/arm/cpu.c | 2 +-
target/arm/cpu64.c | 2 +-
target/arm/helper.c | 13 +++++++------
target/arm/hvf/hvf.c | 4 ++--
target/arm/tcg/cpu-v7m.c | 14 +++++++-------
target/arm/tcg/cpu32.c | 33 +++++++++++++++++----------------
target/arm/tcg/cpu64.c | 22 +++++++++++-----------
target/arm/whpx/whpx-all.c | 4 ++--
13 files changed, 58 insertions(+), 55 deletions(-)
diff --git a/linux-user/arm/target_proc.h b/linux-user/arm/target_proc.h
index a28d7231cd..13c33d44d5 100644
--- a/linux-user/arm/target_proc.h
+++ b/linux-user/arm/target_proc.h
@@ -14,6 +14,7 @@ static int open_cpuinfo(CPUArchState *cpu_env, int fd)
int arch, midr_rev, midr_part, midr_var, midr_impl;
target_ulong elf_hwcap = get_elf_hwcap(env_cpu(cpu_env));
target_ulong elf_hwcap2 = get_elf_hwcap2(env_cpu(cpu_env));
+ uint64_t midr = GET_IDREG(&cpu->isar, MIDR);
const char *elf_name;
int num_cpus, len_part, len_var;
@@ -25,10 +26,10 @@ static int open_cpuinfo(CPUArchState *cpu_env, int fd)
arch = 8;
elf_name = "v8" END_SUFFIX;
- midr_rev = FIELD_EX32(cpu->midr, MIDR_EL1, REVISION);
- midr_part = FIELD_EX32(cpu->midr, MIDR_EL1, PARTNUM);
- midr_var = FIELD_EX32(cpu->midr, MIDR_EL1, VARIANT);
- midr_impl = FIELD_EX32(cpu->midr, MIDR_EL1, IMPLEMENTER);
+ midr_rev = FIELD_EX32(midr, MIDR_EL1, REVISION);
+ midr_part = FIELD_EX32(midr, MIDR_EL1, PARTNUM);
+ midr_var = FIELD_EX32(midr, MIDR_EL1, VARIANT);
+ midr_impl = FIELD_EX32(midr, MIDR_EL1, IMPLEMENTER);
len_part = 3;
len_var = 1;
@@ -37,7 +38,7 @@ static int open_cpuinfo(CPUArchState *cpu_env, int fd)
if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
if (arm_feature(&cpu->env, ARM_FEATURE_V7)) {
arch = 7;
- midr_var = (cpu->midr >> 16) & 0x7f;
+ midr_var = (midr >> 16) & 0x7f;
len_var = 2;
if (arm_feature(&cpu->env, ARM_FEATURE_M)) {
elf_name = "armv7m" END_SUFFIX;
@@ -45,7 +46,7 @@ static int open_cpuinfo(CPUArchState *cpu_env, int fd)
elf_name = "armv7" END_SUFFIX;
}
} else {
- midr_part = cpu->midr >> 4;
+ midr_part = midr >> 4;
len_part = 7;
if (arm_feature(&cpu->env, ARM_FEATURE_V6)) {
arch = 6;
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index c811369e63..e6b4000127 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1125,7 +1125,6 @@ struct ArchCPU {
uint64_t reset_pmcr_el0;
uint64_t idregs[NUM_ID_IDX];
} isar;
- uint64_t midr;
uint32_t reset_fpsid;
uint64_t ctr;
uint32_t reset_sctlr;
diff --git a/target/arm/cpu-sysregs.h.inc b/target/arm/cpu-sysregs.h.inc
index 580d88d1f4..709dc8fc97 100644
--- a/target/arm/cpu-sysregs.h.inc
+++ b/target/arm/cpu-sysregs.h.inc
@@ -41,6 +41,7 @@ DEF(ID_MMFR5_EL1, 3, 0, 0, 3, 6)
DEF(ID_PFR0_EL1, 3, 0, 0, 1, 0)
DEF(ID_PFR1_EL1, 3, 0, 0, 1, 1)
DEF(ID_PFR2_EL1, 3, 0, 0, 3, 4)
+DEF(MIDR_EL1, 3, 0, 0, 0, 0)
DEF(MVFR0_EL1, 3, 0, 0, 3, 0)
DEF(MVFR1_EL1, 3, 0, 0, 3, 1)
DEF(MVFR2_EL1, 3, 0, 0, 3, 2)
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index 1f56fff046..1f7209f6b6 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -1053,7 +1053,7 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
}
return GET_IDREG(isar, REVIDR);
case 0xd00: /* CPUID Base. */
- return cpu->midr;
+ return GET_IDREG(isar, MIDR);
case 0xd04: /* Interrupt Control State (ICSR) */
/* VECTACTIVE */
val = cpu->env.v7m.exception;
diff --git a/target/arm/cpu-max.c b/target/arm/cpu-max.c
index b4e57a167d..c47db5251d 100644
--- a/target/arm/cpu-max.c
+++ b/target/arm/cpu-max.c
@@ -36,7 +36,7 @@ void aarch64_aa32_a57_init(ARMCPU *cpu, bool aarch64_enabled)
if (kvm_enabled()) {
cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A57;
}
- cpu->midr = 0x411fd070;
+ SET_IDREG(isar, MIDR, 0x411fd070);
SET_IDREG(isar, REVIDR, 0);
cpu->reset_fpsid = 0x41034070;
cpu->isar.mvfr0 = 0x10110222;
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 510fc9eeb3..e337462a7e 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -2497,7 +2497,7 @@ static ObjectClass *arm_cpu_class_by_name(const char *cpu_model)
}
static const Property arm_cpu_properties[] = {
- DEFINE_PROP_UINT64("midr", ARMCPU, midr, 0),
+ DEFINE_PROP_UINT64("midr", ARMCPU, isar.idregs[MIDR_EL1_IDX], 0),
DEFINE_PROP_UINT64("mp-affinity", ARMCPU,
mp_affinity, ARM64_AFFINITY_INVALID),
DEFINE_PROP_INT32("node-id", ARMCPU, node_id, CPU_UNSET_NUMA_NODE_ID),
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 80c9c9e5b3..64103df0a7 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -716,7 +716,7 @@ static void aarch64_a53_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_EL3);
set_feature(&cpu->env, ARM_FEATURE_PMU);
cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A53;
- cpu->midr = 0x410fd034;
+ SET_IDREG(isar, MIDR, 0x410fd034);
SET_IDREG(isar, REVIDR, 0x00000100);
cpu->reset_fpsid = 0x41034070;
cpu->isar.mvfr0 = 0x10110222;
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 8c78370626..afaac33f2a 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -7191,12 +7191,12 @@ void register_cp_regs_for_features(ARMCPU *cpu)
{ .name = "VPIDR", .state = ARM_CP_STATE_AA32,
.cp = 15, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 0,
.access = PL2_RW, .accessfn = access_el3_aa32ns,
- .resetvalue = cpu->midr,
+ .resetvalue = GET_IDREG(&cpu->isar, MIDR),
.type = ARM_CP_ALIAS | ARM_CP_EL3_NO_EL2_C_NZ,
.fieldoffset = offsetoflow32(CPUARMState, cp15.vpidr_el2) },
{ .name = "VPIDR_EL2", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 0,
- .access = PL2_RW, .resetvalue = cpu->midr,
+ .access = PL2_RW, .resetvalue = GET_IDREG(&cpu->isar, MIDR),
.type = ARM_CP_EL3_NO_EL2_C_NZ,
.nv2_redirect_offset = 0x88,
.fieldoffset = offsetof(CPUARMState, cp15.vpidr_el2) },
@@ -7415,7 +7415,7 @@ void register_cp_regs_for_features(ARMCPU *cpu)
*/
{ .name = "MIDR",
.cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = CP_ANY,
- .access = PL1_R, .resetvalue = cpu->midr,
+ .access = PL1_R, .resetvalue = GET_IDREG(&cpu->isar, MIDR),
.writefn = arm_cp_write_ignore, .raw_writefn = raw_write,
.readfn = midr_read,
.fieldoffset = offsetof(CPUARMState, cp15.c0_cpuid),
@@ -7440,14 +7440,15 @@ void register_cp_regs_for_features(ARMCPU *cpu)
ARMCPRegInfo id_v8_midr_cp_reginfo[] = {
{ .name = "MIDR_EL1", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 0, .opc2 = 0,
- .access = PL1_R, .type = ARM_CP_NO_RAW, .resetvalue = cpu->midr,
+ .access = PL1_R, .type = ARM_CP_NO_RAW,
+ .resetvalue = GET_IDREG(&cpu->isar, MIDR),
.fgt = FGT_MIDR_EL1,
.fieldoffset = offsetof(CPUARMState, cp15.c0_cpuid),
.readfn = midr_read },
/* crn = 0 op1 = 0 crm = 0 op2 = 7 : AArch32 aliases of MIDR */
{ .name = "MIDR", .type = ARM_CP_ALIAS | ARM_CP_CONST,
.cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 7,
- .access = PL1_R, .resetvalue = cpu->midr },
+ .access = PL1_R, .resetvalue = GET_IDREG(&cpu->isar, MIDR) },
{ .name = "REVIDR_EL1", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 0, .opc2 = 6,
.access = PL1_R,
@@ -7458,7 +7459,7 @@ void register_cp_regs_for_features(ARMCPU *cpu)
ARMCPRegInfo id_v8_midr_alias_cp_reginfo = {
.name = "MIDR", .type = ARM_CP_ALIAS | ARM_CP_CONST | ARM_CP_NO_GDB,
.cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 4,
- .access = PL1_R, .resetvalue = cpu->midr
+ .access = PL1_R, .resetvalue = GET_IDREG(&cpu->isar, MIDR)
};
ARMCPRegInfo id_cp_reginfo[] = {
/* These are common to v8 and pre-v8 */
diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
index b00a7e1a84..f9f3d22014 100644
--- a/target/arm/hvf/hvf.c
+++ b/target/arm/hvf/hvf.c
@@ -1295,7 +1295,7 @@ void hvf_arm_set_cpu_features_from_host(ARMCPU *cpu)
cpu->dtb_compatible = arm_host_cpu_features.dtb_compatible;
cpu->isar = arm_host_cpu_features.isar;
cpu->env.features = arm_host_cpu_features.features;
- cpu->midr = arm_host_cpu_features.midr;
+ SET_IDREG(&cpu->isar, MIDR, arm_host_cpu_features.midr);
cpu->reset_sctlr = arm_host_cpu_features.reset_sctlr;
cpu->sme_vq.supported = arm_host_cpu_features.sme_vq_supported;
}
@@ -1472,7 +1472,7 @@ int hvf_arch_init_vcpu(CPUState *cpu)
/* Set CP_NO_RAW system registers on init */
ret = hv_vcpu_set_sys_reg(cpu->accel->fd, HV_SYS_REG_MIDR_EL1,
- arm_cpu->midr);
+ GET_IDREG(&arm_cpu->isar, MIDR));
assert_hvf_ok(ret);
ret = hv_vcpu_set_sys_reg(cpu->accel->fd, HV_SYS_REG_MPIDR_EL1,
diff --git a/target/arm/tcg/cpu-v7m.c b/target/arm/tcg/cpu-v7m.c
index 9a5512aa55..3da2a2a5f7 100644
--- a/target/arm/tcg/cpu-v7m.c
+++ b/target/arm/tcg/cpu-v7m.c
@@ -49,7 +49,7 @@ static void cortex_m0_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_V6);
set_feature(&cpu->env, ARM_FEATURE_M);
- cpu->midr = 0x410cc200;
+ SET_IDREG(isar, MIDR, 0x410cc200);
/*
* These ID register values are not guest visible, because
@@ -83,7 +83,7 @@ static void cortex_m3_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_V7);
set_feature(&cpu->env, ARM_FEATURE_M);
set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
- cpu->midr = 0x410fc231;
+ SET_IDREG(isar, MIDR, 0x410fc231);
cpu->pmsav7_dregion = 8;
SET_IDREG(isar, ID_PFR0, 0x00000030);
SET_IDREG(isar, ID_PFR1, 0x00000200);
@@ -111,7 +111,7 @@ static void cortex_m4_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_M);
set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
- cpu->midr = 0x410fc240; /* r0p0 */
+ SET_IDREG(isar, MIDR, 0x410fc240); /* r0p0 */
cpu->pmsav7_dregion = 8;
cpu->isar.mvfr0 = 0x10110021;
cpu->isar.mvfr1 = 0x11000011;
@@ -142,7 +142,7 @@ static void cortex_m7_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_M);
set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
- cpu->midr = 0x411fc272; /* r1p2 */
+ SET_IDREG(isar, MIDR, 0x411fc272); /* r1p2 */
cpu->pmsav7_dregion = 8;
cpu->isar.mvfr0 = 0x10110221;
cpu->isar.mvfr1 = 0x12000011;
@@ -174,7 +174,7 @@ static void cortex_m33_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
set_feature(&cpu->env, ARM_FEATURE_M_SECURITY);
set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
- cpu->midr = 0x410fd213; /* r0p3 */
+ SET_IDREG(isar, MIDR, 0x410fd213); /* r0p3 */
cpu->pmsav7_dregion = 16;
cpu->sau_sregion = 8;
cpu->isar.mvfr0 = 0x10110021;
@@ -210,7 +210,7 @@ static void cortex_m55_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
set_feature(&cpu->env, ARM_FEATURE_M_SECURITY);
set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
- cpu->midr = 0x410fd221; /* r0p1 */
+ SET_IDREG(isar, MIDR, 0x410fd221); /* r0p1 */
SET_IDREG(isar, REVIDR, 0);
cpu->pmsav7_dregion = 16;
cpu->sau_sregion = 8;
@@ -248,7 +248,7 @@ static void cortex_m85_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
set_feature(&cpu->env, ARM_FEATURE_M_SECURITY);
set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
- cpu->midr = 0x411fd231; /* r1p1 */
+ SET_IDREG(isar, MIDR, 0x411fd231); /* r1p1 */
SET_IDREG(isar, REVIDR, 0);
cpu->pmsav7_dregion = 16;
cpu->sau_sregion = 8;
diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c
index c02b737fc0..faeeeff4ea 100644
--- a/target/arm/tcg/cpu32.c
+++ b/target/arm/tcg/cpu32.c
@@ -27,7 +27,8 @@ static void arm926_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_V5);
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
set_feature(&cpu->env, ARM_FEATURE_CACHE_TEST_CLEAN);
- cpu->midr = 0x41069265;
+ SET_IDREG(&cpu->isar, MIDR, 0x41069265);
+
cpu->reset_fpsid = 0x41011090;
cpu->ctr = 0x1dd20d2;
cpu->reset_sctlr = 0x00050078;
@@ -54,7 +55,7 @@ static void arm946_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_V5);
set_feature(&cpu->env, ARM_FEATURE_PMSA);
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
- cpu->midr = 0x41059461;
+ SET_IDREG(&cpu->isar, MIDR, 0x41059461);
cpu->ctr = 0x0f004006;
cpu->reset_sctlr = 0x00000078;
}
@@ -68,7 +69,7 @@ static void arm1026_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_AUXCR);
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
set_feature(&cpu->env, ARM_FEATURE_CACHE_TEST_CLEAN);
- cpu->midr = 0x4106a262;
+ SET_IDREG(&cpu->isar, MIDR, 0x4106a262);
cpu->reset_fpsid = 0x410110a0;
cpu->ctr = 0x1dd20d2;
cpu->reset_sctlr = 0x00050078;
@@ -117,7 +118,7 @@ static void arm1136_r2_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
set_feature(&cpu->env, ARM_FEATURE_CACHE_DIRTY_REG);
set_feature(&cpu->env, ARM_FEATURE_CACHE_BLOCK_OPS);
- cpu->midr = 0x4107b362;
+ SET_IDREG(isar, MIDR, 0x4107b362);
cpu->reset_fpsid = 0x410120b4;
cpu->isar.mvfr0 = 0x11111111;
cpu->isar.mvfr1 = 0x00000000;
@@ -149,7 +150,7 @@ static void arm1136_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
set_feature(&cpu->env, ARM_FEATURE_CACHE_DIRTY_REG);
set_feature(&cpu->env, ARM_FEATURE_CACHE_BLOCK_OPS);
- cpu->midr = 0x4117b363;
+ SET_IDREG(isar, MIDR, 0x4117b363);
cpu->reset_fpsid = 0x410120b4;
cpu->isar.mvfr0 = 0x11111111;
cpu->isar.mvfr1 = 0x00000000;
@@ -182,7 +183,7 @@ static void arm1176_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_CACHE_DIRTY_REG);
set_feature(&cpu->env, ARM_FEATURE_CACHE_BLOCK_OPS);
set_feature(&cpu->env, ARM_FEATURE_EL3);
- cpu->midr = 0x410fb767;
+ SET_IDREG(isar, MIDR, 0x410fb767);
cpu->reset_fpsid = 0x410120b5;
cpu->isar.mvfr0 = 0x11111111;
cpu->isar.mvfr1 = 0x00000000;
@@ -213,7 +214,7 @@ static void arm11mpcore_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_VAPA);
set_feature(&cpu->env, ARM_FEATURE_MPIDR);
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
- cpu->midr = 0x410fb022;
+ SET_IDREG(isar, MIDR, 0x410fb022);
cpu->reset_fpsid = 0x410120b4;
cpu->isar.mvfr0 = 0x11111111;
cpu->isar.mvfr1 = 0x00000000;
@@ -257,7 +258,7 @@ static void cortex_a8_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
set_feature(&cpu->env, ARM_FEATURE_EL3);
set_feature(&cpu->env, ARM_FEATURE_PMU);
- cpu->midr = 0x410fc080;
+ SET_IDREG(isar, MIDR, 0x410fc080);
cpu->reset_fpsid = 0x410330c0;
cpu->isar.mvfr0 = 0x11110222;
cpu->isar.mvfr1 = 0x00011111;
@@ -335,7 +336,7 @@ static void cortex_a9_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_V7MP);
set_feature(&cpu->env, ARM_FEATURE_CBAR);
set_feature(&cpu->env, ARM_FEATURE_D32DIS);
- cpu->midr = 0x410fc090;
+ SET_IDREG(isar, MIDR, 0x410fc090);
cpu->reset_fpsid = 0x41033090;
cpu->isar.mvfr0 = 0x11110222;
cpu->isar.mvfr1 = 0x01111111;
@@ -403,7 +404,7 @@ static void cortex_a7_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_EL3);
set_feature(&cpu->env, ARM_FEATURE_PMU);
set_feature(&cpu->env, ARM_FEATURE_D32DIS);
- cpu->midr = 0x410fc075;
+ SET_IDREG(isar, MIDR, 0x410fc075);
cpu->reset_fpsid = 0x41023075;
cpu->isar.mvfr0 = 0x10110222;
cpu->isar.mvfr1 = 0x11111111;
@@ -455,7 +456,7 @@ static void cortex_a15_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_EL3);
set_feature(&cpu->env, ARM_FEATURE_PMU);
/* r4p0 cpu, not requiring expensive tlb flush errata */
- cpu->midr = 0x414fc0f0;
+ SET_IDREG(isar, MIDR, 0x414fc0f0);
SET_IDREG(isar, REVIDR, 0);
cpu->reset_fpsid = 0x410430f0;
cpu->isar.mvfr0 = 0x10110222;
@@ -505,7 +506,7 @@ static void cortex_r5_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_V7MP);
set_feature(&cpu->env, ARM_FEATURE_PMSA);
set_feature(&cpu->env, ARM_FEATURE_PMU);
- cpu->midr = 0x411fc153; /* r1p3 */
+ SET_IDREG(isar, MIDR, 0x411fc153); /* r1p3 */
SET_IDREG(isar, ID_PFR0, 0x0131);
SET_IDREG(isar, ID_PFR1, 0x001);
SET_IDREG(isar, ID_DFR0, 0x010400);
@@ -646,7 +647,7 @@ static void cortex_r52_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ);
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
set_feature(&cpu->env, ARM_FEATURE_AUXCR);
- cpu->midr = 0x411fd133; /* r1p3 */
+ SET_IDREG(isar, MIDR, 0x411fd133); /* r1p3 */
SET_IDREG(isar, REVIDR, 0);
cpu->reset_fpsid = 0x41034023;
cpu->isar.mvfr0 = 0x10110222;
@@ -694,7 +695,7 @@ static void ti925t_initfn(Object *obj)
ARMCPU *cpu = ARM_CPU(obj);
set_feature(&cpu->env, ARM_FEATURE_V4T);
set_feature(&cpu->env, ARM_FEATURE_OMAPCP);
- cpu->midr = ARM_CPUID_TI925T;
+ SET_IDREG(&cpu->isar, MIDR, ARM_CPUID_TI925T);
cpu->ctr = 0x5109149;
cpu->reset_sctlr = 0x00000070;
}
@@ -706,7 +707,7 @@ static void sa1100_initfn(Object *obj)
cpu->dtb_compatible = "intel,sa1100";
set_feature(&cpu->env, ARM_FEATURE_STRONGARM);
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
- cpu->midr = 0x4401A11B;
+ SET_IDREG(&cpu->isar, MIDR, 0x4401A11B);
cpu->reset_sctlr = 0x00000070;
}
@@ -715,7 +716,7 @@ static void sa1110_initfn(Object *obj)
ARMCPU *cpu = ARM_CPU(obj);
set_feature(&cpu->env, ARM_FEATURE_STRONGARM);
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
- cpu->midr = 0x6901B119;
+ SET_IDREG(&cpu->isar, MIDR, 0x6901B119);
cpu->reset_sctlr = 0x00000070;
}
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
index 7af29978c6..60c701e5d7 100644
--- a/target/arm/tcg/cpu64.c
+++ b/target/arm/tcg/cpu64.c
@@ -47,7 +47,7 @@ static void aarch64_a35_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_PMU);
/* From B2.2 AArch64 identification registers. */
- cpu->midr = 0x411fd040;
+ SET_IDREG(isar, MIDR, 0x411fd040);
SET_IDREG(isar, REVIDR, 0);
cpu->ctr = 0x84448004;
SET_IDREG(isar, ID_PFR0, 0x00000131);
@@ -247,7 +247,7 @@ static void aarch64_a55_initfn(Object *obj)
SET_IDREG(isar, ID_PFR0, 0x10010131);
SET_IDREG(isar, ID_PFR1, 0x00011011);
SET_IDREG(isar, ID_PFR2, 0x00000011);
- cpu->midr = 0x412FD050; /* r2p0 */
+ SET_IDREG(isar, MIDR, 0x412FD050); /* r2p0 */
SET_IDREG(isar, REVIDR, 0);
/* From B2.23 CCSIDR_EL1 */
@@ -291,7 +291,7 @@ static void aarch64_a72_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_EL2);
set_feature(&cpu->env, ARM_FEATURE_EL3);
set_feature(&cpu->env, ARM_FEATURE_PMU);
- cpu->midr = 0x410fd083;
+ SET_IDREG(isar, MIDR, 0x410fd083);
SET_IDREG(isar, REVIDR, 0);
cpu->reset_fpsid = 0x41034080;
cpu->isar.mvfr0 = 0x10110222;
@@ -382,7 +382,7 @@ static void aarch64_a76_initfn(Object *obj)
SET_IDREG(isar, ID_PFR0, 0x10010131);
SET_IDREG(isar, ID_PFR1, 0x00010000); /* GIC filled in later */
SET_IDREG(isar, ID_PFR2, 0x00000011);
- cpu->midr = 0x414fd0b1; /* r4p1 */
+ SET_IDREG(isar, MIDR, 0x414fd0b1); /* r4p1 */
SET_IDREG(isar, REVIDR, 0);
/* From B2.18 CCSIDR_EL1 */
@@ -455,7 +455,7 @@ static void aarch64_a78ae_initfn(Object *obj)
SET_IDREG(isar, ID_PFR0, 0x10010131);
SET_IDREG(isar, ID_PFR1, 0x00010000); /* GIC filled in later */
SET_IDREG(isar, ID_PFR2, 0x00000011);
- cpu->midr = 0x410fd423; /* r0p3 */
+ SET_IDREG(isar, MIDR, 0x410fd423); /* r0p3 */
SET_IDREG(isar, REVIDR, 0);
/* From 3.2.33 CCSIDR_EL1 */
@@ -500,7 +500,7 @@ static void aarch64_a64fx_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_EL2);
set_feature(&cpu->env, ARM_FEATURE_EL3);
set_feature(&cpu->env, ARM_FEATURE_PMU);
- cpu->midr = 0x461f0010;
+ SET_IDREG(isar, MIDR, 0x461f0010);
SET_IDREG(isar, REVIDR, 0);
cpu->ctr = 0x86668006;
cpu->reset_sctlr = 0x30000180;
@@ -706,7 +706,7 @@ static void aarch64_neoverse_n1_initfn(Object *obj)
SET_IDREG(isar, ID_PFR0, 0x10010131);
SET_IDREG(isar, ID_PFR1, 0x00010000); /* GIC filled in later */
SET_IDREG(isar, ID_PFR2, 0x00000011);
- cpu->midr = 0x414fd0c1; /* r4p1 */
+ SET_IDREG(isar, MIDR, 0x414fd0c1); /* r4p1 */
SET_IDREG(isar, REVIDR, 0);
/* From B2.23 CCSIDR_EL1 */
@@ -786,7 +786,7 @@ static void aarch64_neoverse_v1_initfn(Object *obj)
SET_IDREG(isar, ID_PFR0, 0x21110131);
SET_IDREG(isar, ID_PFR1, 0x00010000); /* GIC filled in later */
SET_IDREG(isar, ID_PFR2, 0x00000011);
- cpu->midr = 0x411FD402; /* r1p2 */
+ SET_IDREG(isar, MIDR, 0x411FD402); /* r1p2 */
SET_IDREG(isar, REVIDR, 0);
/*
@@ -983,7 +983,7 @@ static void aarch64_a710_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_PMU);
/* Ordered by Section B.4: AArch64 registers */
- cpu->midr = 0x412FD471; /* r2p1 */
+ SET_IDREG(isar, MIDR, 0x412FD471); /* r2p1 */
SET_IDREG(isar, REVIDR, 0);
SET_IDREG(isar, ID_PFR0, 0x21110131);
SET_IDREG(isar, ID_PFR1, 0x00010000); /* GIC filled in later */
@@ -1086,7 +1086,7 @@ static void aarch64_neoverse_n2_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_PMU);
/* Ordered by Section B.5: AArch64 ID registers */
- cpu->midr = 0x410FD493; /* r0p3 */
+ SET_IDREG(isar, MIDR, 0x410FD493); /* r0p3 */
SET_IDREG(isar, REVIDR, 0);
SET_IDREG(isar, ID_PFR0, 0x21110131);
SET_IDREG(isar, ID_PFR1, 0x00010000); /* GIC filled in later */
@@ -1214,7 +1214,7 @@ void aarch64_max_v8_tcg_initfn(Object *obj)
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;
+ SET_IDREG(isar, MIDR, t);
/*
* We're going to set FEAT_S2FWB, which mandates that CLIDR_EL1.{LoUU,LoUIS}
diff --git a/target/arm/whpx/whpx-all.c b/target/arm/whpx/whpx-all.c
index 46f0b9524e..18009d6c8d 100644
--- a/target/arm/whpx/whpx-all.c
+++ b/target/arm/whpx/whpx-all.c
@@ -775,7 +775,7 @@ void whpx_arm_set_cpu_features_from_host(ARMCPU *cpu)
cpu->dtb_compatible = arm_host_cpu_features.dtb_compatible;
cpu->isar = arm_host_cpu_features.isar;
cpu->env.features = arm_host_cpu_features.features;
- cpu->midr = arm_host_cpu_features.midr;
+ SET_IDREG(&cpu->isar, MIDR, arm_host_cpu_features.midr);
cpu->reset_sctlr = arm_host_cpu_features.reset_sctlr;
}
@@ -836,7 +836,7 @@ int whpx_init_vcpu(CPUState *cpu)
assert(write_cpustate_to_list(arm_cpu, false));
/* Set CP_NO_RAW system registers on init */
- val.Reg64 = arm_cpu->midr;
+ val.Reg64 = GET_IDREG(&arm_cpu->isar, MIDR);
whpx_set_reg(cpu, WHvArm64RegisterMidrEl1,
val);
--
2.53.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH v3 for-11.2 04/10] target/arm: Enforce MPIDR into isar.idregs[] storage
2026-10-30 7:28 [PATCH v3 for-11.2 00/10] kvm/arm: Some refactoring for custom KVM host model Eric Auger
` (2 preceding siblings ...)
2026-10-30 7:28 ` [PATCH v3 for-11.2 03/10] target/arm: Move MIDR " Eric Auger
@ 2026-10-30 7:28 ` Eric Auger
2026-10-30 7:28 ` [PATCH v3 for-11.2 05/10] target/arm/kvm: Pass an error handle to kvm_arm_init_cpreg_list Eric Auger
` (5 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Eric Auger @ 2026-10-30 7:28 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, peter.maydell,
shaju.abraham, khushit.shah, richard.henderson, pbonzini,
skolothumtho, philmd, 7746591750, maobibo, harshpb, amachhiw,
daniel.barboza, milesg, farman, cohuck, alireza.sanaee
Cc: armbru, mbawa
At the moment MPIDR_EL1 has no real storage. Instead cpu
mp_affinity field stores the Aff0-Aff2 bits only and the
ID register is reconstructed when needed. There is also
an mp-affinity property used for TCG only.
Keep the mp-affinity property and its associated storage
while making sure the MPIDR_EL1 full register is stored
in cpu->isar.idregs[] as other ID registers.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Suggested-by: Khushit Shah <khushit.shah@nutanix.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Sebastian Ott <sebott@redhat.com>
Reviewed-by: Khushit Shah <khushit.shah@nutanix.com>
---
target/arm/cpu.h | 8 +++++++-
target/arm/cpu-sysregs.h.inc | 1 +
target/arm/cpu.c | 17 +++++++++++++++++
target/arm/helper.c | 14 +-------------
target/arm/hvf/hvf.c | 2 +-
target/arm/kvm.c | 1 +
target/arm/whpx/whpx-all.c | 2 +-
7 files changed, 29 insertions(+), 16 deletions(-)
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index e6b4000127..5c5f551dac 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1130,7 +1130,13 @@ struct ArchCPU {
uint32_t reset_sctlr;
uint64_t pmceid0;
uint64_t pmceid1;
- uint64_t mp_affinity; /* MP ID without feature bits */
+ /*
+ * MP ID without feature bits, ie. Aff0..Aff3 only
+ * used to store the corresponding property value for TCG vcpus.
+ * The MPIDR_EL1 value (affinity + feature bits) is stored in a
+ * consistent manner in isar.idregs[MPIDR_EL1_IDX].
+ */
+ uint64_t mp_affinity;
uint64_t reset_cbar;
uint32_t reset_auxcr;
bool reset_hivecs;
diff --git a/target/arm/cpu-sysregs.h.inc b/target/arm/cpu-sysregs.h.inc
index 709dc8fc97..f148f6f565 100644
--- a/target/arm/cpu-sysregs.h.inc
+++ b/target/arm/cpu-sysregs.h.inc
@@ -42,6 +42,7 @@ DEF(ID_PFR0_EL1, 3, 0, 0, 1, 0)
DEF(ID_PFR1_EL1, 3, 0, 0, 1, 1)
DEF(ID_PFR2_EL1, 3, 0, 0, 3, 4)
DEF(MIDR_EL1, 3, 0, 0, 0, 0)
+DEF(MPIDR_EL1, 3, 0, 0, 0, 5)
DEF(MVFR0_EL1, 3, 0, 0, 3, 0)
DEF(MVFR1_EL1, 3, 0, 0, 3, 1)
DEF(MVFR2_EL1, 3, 0, 0, 3, 2)
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index e337462a7e..aba45b66f8 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -2170,6 +2170,23 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
ARM_DEFAULT_CPUS_PER_CLUSTER);
}
+ /* Consistently update MPIDR_EL1 in isar.idregs[] by adding feature bits */
+ {
+ uint64_t mpidr = cpu->mp_affinity;
+
+ if (arm_feature(env, ARM_FEATURE_V7MP)) {
+ mpidr |= (1U << 31);
+ /*
+ * Uniprocessor (non-coherent) cores that still implement the MP
+ * extensions set U (bit 30), e.g. Cortex-R5.
+ */
+ if (cpu->mp_is_up) {
+ mpidr |= (1u << 30);
+ }
+ }
+ SET_IDREG(&cpu->isar, MPIDR, mpidr);
+ }
+
if (cpu->reset_hivecs) {
cpu->reset_sctlr |= (1 << 13);
}
diff --git a/target/arm/helper.c b/target/arm/helper.c
index afaac33f2a..f413b15eb7 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -3180,20 +3180,8 @@ static uint64_t midr_read(CPUARMState *env, const ARMCPRegInfo *ri)
static uint64_t mpidr_read_val(CPUARMState *env)
{
ARMCPU *cpu = env_archcpu(env);
- uint64_t mpidr = cpu->mp_affinity;
- if (arm_feature(env, ARM_FEATURE_V7MP)) {
- mpidr |= (1U << 31);
- /*
- * Cores which are uniprocessor (non-coherent)
- * but still implement the MP extensions set
- * bit 30. (For instance, Cortex-R5).
- */
- if (cpu->mp_is_up) {
- mpidr |= (1u << 30);
- }
- }
- return mpidr;
+ return GET_IDREG(&cpu->isar, MPIDR);
}
static uint64_t mpidr_read(CPUARMState *env, const ARMCPRegInfo *ri)
diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
index f9f3d22014..4b947e9ba5 100644
--- a/target/arm/hvf/hvf.c
+++ b/target/arm/hvf/hvf.c
@@ -1476,7 +1476,7 @@ int hvf_arch_init_vcpu(CPUState *cpu)
assert_hvf_ok(ret);
ret = hv_vcpu_set_sys_reg(cpu->accel->fd, HV_SYS_REG_MPIDR_EL1,
- arm_cpu->mp_affinity);
+ GET_IDREG(&arm_cpu->isar, MPIDR));
assert_hvf_ok(ret);
pfr = GET_IDREG(&arm_cpu->isar, ID_AA64PFR0);
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index de09d63d2e..724bc08edf 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -2103,6 +2103,7 @@ int kvm_arch_init_vcpu(CPUState *cs)
if (ret) {
return ret;
}
+ SET_IDREG(&cpu->isar, MPIDR, mpidr);
cpu->mp_affinity = mpidr & ARM64_AFFINITY_MASK;
return kvm_arm_init_cpreg_list(cpu);
diff --git a/target/arm/whpx/whpx-all.c b/target/arm/whpx/whpx-all.c
index 18009d6c8d..024d18df04 100644
--- a/target/arm/whpx/whpx-all.c
+++ b/target/arm/whpx/whpx-all.c
@@ -842,7 +842,7 @@ int whpx_init_vcpu(CPUState *cpu)
clean_whv_register_value(&val);
- val.Reg64 = deposit64(arm_cpu->mp_affinity, 31, 1, 1 /* RES1 */);
+ val.Reg64 = GET_IDREG(&arm_cpu->isar, MPIDR);
whpx_set_reg(cpu, WHvArm64RegisterMpidrEl1, val);
clamp_id_aa64mmfr0_parange_to_ipa_size(&arm_cpu->isar);
--
2.53.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH v3 for-11.2 05/10] target/arm/kvm: Pass an error handle to kvm_arm_init_cpreg_list
2026-10-30 7:28 [PATCH v3 for-11.2 00/10] kvm/arm: Some refactoring for custom KVM host model Eric Auger
` (3 preceding siblings ...)
2026-10-30 7:28 ` [PATCH v3 for-11.2 04/10] target/arm: Enforce MPIDR " Eric Auger
@ 2026-10-30 7:28 ` Eric Auger
2026-10-30 7:28 ` [PATCH v3 for-11.2 06/10] target/kvm: Pass an Error handle to kvm_arch_init_vcpu Eric Auger
` (4 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Eric Auger @ 2026-10-30 7:28 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, peter.maydell,
shaju.abraham, khushit.shah, richard.henderson, pbonzini,
skolothumtho, philmd, 7746591750, maobibo, harshpb, amachhiw,
daniel.barboza, milesg, farman, cohuck, alireza.sanaee
Cc: armbru, mbawa
Pass an error handle to kvm_arm_init_cpreg_list(). A Subsequent patch
will do the same with kvm_arch_init_vcpu().
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Gustavo Romero <gromero@redhat.com>
Reviewed-by: Sebastian Ott <sebott@redhat.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
---
target/arm/kvm.c | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index 724bc08edf..76b3996d3b 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -865,6 +865,7 @@ static bool kvm_arm_reg_syncs_via_cpreg_list(uint64_t regidx)
/**
* kvm_arm_init_cpreg_list:
* @cpu: ARMCPU
+ * @errp: Error handle
*
* Initialize the ARMCPU cpreg list according to the kernel's
* definition of what CPU registers it knows about (and throw away
@@ -872,7 +873,7 @@ static bool kvm_arm_reg_syncs_via_cpreg_list(uint64_t regidx)
*
* Returns: 0 if success, else < 0 error code
*/
-static int kvm_arm_init_cpreg_list(ARMCPU *cpu)
+static int kvm_arm_init_cpreg_list(ARMCPU *cpu, Error **errp)
{
struct kvm_reg_list rl;
struct kvm_reg_list *rlp;
@@ -882,12 +883,17 @@ static int kvm_arm_init_cpreg_list(ARMCPU *cpu)
rl.n = 0;
ret = kvm_vcpu_ioctl(cs, KVM_GET_REG_LIST, &rl);
if (ret != -E2BIG) {
+ if (ret < 0) {
+ error_setg_errno(errp, -ret,
+ "failed to get KVM register list size");
+ }
return ret;
}
rlp = g_malloc(sizeof(struct kvm_reg_list) + rl.n * sizeof(uint64_t));
rlp->n = rl.n;
ret = kvm_vcpu_ioctl(cs, KVM_GET_REG_LIST, rlp);
if (ret) {
+ error_setg_errno(errp, -ret, "failed to get KVM register list");
goto out;
}
/* Sort the list we get back from the kernel, since cpreg_tuples
@@ -904,7 +910,7 @@ static int kvm_arm_init_cpreg_list(ARMCPU *cpu)
case KVM_REG_SIZE_U64:
break;
default:
- fprintf(stderr, "Can't handle size of register in kernel list\n");
+ error_setg(errp, "Can't handle size of register in kernel list");
ret = -EINVAL;
goto out;
}
@@ -930,7 +936,7 @@ static int kvm_arm_init_cpreg_list(ARMCPU *cpu)
/* Shouldn't happen unless kernel is inconsistent about
* what registers exist.
*/
- fprintf(stderr, "Initial read of kernel register state failed\n");
+ error_setg(errp, "Initial read of kernel register state failed");
ret = -EINVAL;
goto out;
}
@@ -2008,6 +2014,7 @@ int kvm_arch_init_vcpu(CPUState *cs)
uint64_t mpidr;
ARMCPU *cpu = ARM_CPU(cs);
CPUARMState *env = &cpu->env;
+ Error *local_err = NULL;
uint64_t psciver;
if (cpu->kvm_target == QEMU_KVM_ARM_TARGET_NONE) {
@@ -2106,7 +2113,11 @@ int kvm_arch_init_vcpu(CPUState *cs)
SET_IDREG(&cpu->isar, MPIDR, mpidr);
cpu->mp_affinity = mpidr & ARM64_AFFINITY_MASK;
- return kvm_arm_init_cpreg_list(cpu);
+ ret = kvm_arm_init_cpreg_list(cpu, &local_err);
+ if (ret < 0) {
+ error_report_err(local_err);
+ }
+ return ret;
}
int kvm_arch_destroy_vcpu(CPUState *cs)
--
2.53.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH v3 for-11.2 06/10] target/kvm: Pass an Error handle to kvm_arch_init_vcpu
2026-10-30 7:28 [PATCH v3 for-11.2 00/10] kvm/arm: Some refactoring for custom KVM host model Eric Auger
` (4 preceding siblings ...)
2026-10-30 7:28 ` [PATCH v3 for-11.2 05/10] target/arm/kvm: Pass an error handle to kvm_arm_init_cpreg_list Eric Auger
@ 2026-10-30 7:28 ` Eric Auger
2026-10-30 7:28 ` [PATCH v3 for-11.2 07/10] target/arm/kvm: Introduce kvm_arm_vcpu_prepare_init_features helper Eric Auger
` (3 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Eric Auger @ 2026-10-30 7:28 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, peter.maydell,
shaju.abraham, khushit.shah, richard.henderson, pbonzini,
skolothumtho, philmd, 7746591750, maobibo, harshpb, amachhiw,
daniel.barboza, milesg, farman, cohuck, alireza.sanaee
Cc: armbru, mbawa
The 2 callers of kvm_arch_init_vcpu(), namely kvm_rebind_vcpus()
and kvm_init_vcpu() are passed an Error handle. So it is a pity
not using it in kvm_arch_init_vcpu(). Also, in the future, the
error handle could be passed to other functions called inside.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Gustavo Romero <gromero@redhat.com>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
Reviewed-by: Sebastian Ott <sebott@redhat.com>
Reviewed-by: Mohammadfaiz Bawa <mbawa@redhat.com>
---
v1 -> v2:
- fixed comma in target/ppc/kvm.c
---
include/system/kvm.h | 2 +-
accel/kvm/kvm-all.c | 15 +++++++--------
target/arm/kvm.c | 26 +++++++++++++-------------
target/i386/kvm/kvm.c | 22 ++++++++++++----------
target/loongarch/kvm/kvm.c | 27 +++++++++------------------
target/ppc/kvm.c | 10 +++++++---
target/riscv/kvm/kvm-cpu.c | 6 +++++-
target/s390x/kvm/kvm.c | 2 +-
8 files changed, 55 insertions(+), 55 deletions(-)
diff --git a/include/system/kvm.h b/include/system/kvm.h
index d29624034c..26d55cc699 100644
--- a/include/system/kvm.h
+++ b/include/system/kvm.h
@@ -358,7 +358,7 @@ int kvm_arch_get_default_type(MachineState *ms);
int kvm_arch_init(MachineState *ms, KVMState *s);
int kvm_arch_pre_create_vcpu(CPUState *cpu, Error **errp);
-int kvm_arch_init_vcpu(CPUState *cpu);
+int kvm_arch_init_vcpu(CPUState *cpu, Error **errp);
int kvm_arch_destroy_vcpu(CPUState *cpu);
#ifdef TARGET_KVM_HAVE_RESET_PARKED_VCPU
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index db8fba53f3..ddc82f9775 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -504,11 +504,11 @@ static int kvm_rebind_vcpus(Error **errp)
}
}
- ret = kvm_arch_init_vcpu(cpu);
+ ret = kvm_arch_init_vcpu(cpu, errp);
if (ret < 0) {
- error_setg_errno(errp, -ret,
- "kvm_init_vcpu: kvm_arch_init_vcpu failed (%lu)",
- vcpu_id);
+ error_prepend(errp,
+ "kvm_init_vcpu: kvm_arch_init_vcpu failed (%lu)",
+ vcpu_id);
}
close(cpu->kvm_vcpu_stats_fd);
@@ -751,11 +751,10 @@ int kvm_init_vcpu(CPUState *cpu, Error **errp)
}
}
- ret = kvm_arch_init_vcpu(cpu);
+ ret = kvm_arch_init_vcpu(cpu, errp);
if (ret < 0) {
- error_setg_errno(errp, -ret,
- "kvm_init_vcpu: kvm_arch_init_vcpu failed (%lu)",
- kvm_arch_vcpu_id(cpu));
+ error_prepend(errp, "kvm_init_vcpu: kvm_arch_init_vcpu failed (%lu)",
+ kvm_arch_vcpu_id(cpu));
}
cpu->kvm_vcpu_stats_fd = kvm_vcpu_ioctl(cpu, KVM_GET_STATS_FD, NULL);
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index 76b3996d3b..86a4d2a6b1 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -2008,17 +2008,16 @@ int kvm_arch_pre_create_vcpu(CPUState *cpu, Error **errp)
return 0;
}
-int kvm_arch_init_vcpu(CPUState *cs)
+int kvm_arch_init_vcpu(CPUState *cs, Error **errp)
{
int ret;
uint64_t mpidr;
ARMCPU *cpu = ARM_CPU(cs);
CPUARMState *env = &cpu->env;
- Error *local_err = NULL;
uint64_t psciver;
if (cpu->kvm_target == QEMU_KVM_ARM_TARGET_NONE) {
- error_report("KVM is not supported for this guest CPU type");
+ error_setg(errp, "KVM is not supported for this guest CPU type");
return -EINVAL;
}
@@ -2064,16 +2063,19 @@ int kvm_arch_init_vcpu(CPUState *cs)
/* Do KVM_ARM_VCPU_INIT ioctl */
ret = kvm_arm_vcpu_init(cpu);
if (ret) {
+ error_setg_errno(errp, -ret, "failed kvm_arm_vcpu_init");
return ret;
}
if (cpu_isar_feature(aa64_sve, cpu)) {
ret = kvm_arm_sve_set_vls(cpu);
if (ret) {
+ error_setg_errno(errp, -ret, "failed kvm_arm_sve_set_vls");
return ret;
}
ret = kvm_arm_vcpu_finalize(cpu, KVM_ARM_VCPU_SVE);
if (ret) {
+ error_setg_errno(errp, -ret, "failed kvm_arm_vcpu_finalize");
return ret;
}
}
@@ -2082,11 +2084,12 @@ int kvm_arch_init_vcpu(CPUState *cs)
psciver = cpu->psci_version;
ret = kvm_set_one_reg(cs, KVM_REG_ARM_PSCI_VERSION, &psciver);
if (ret) {
- error_report("KVM in this kernel does not support PSCI version %d.%d",
- (int) PSCI_VERSION_MAJOR(psciver),
- (int) PSCI_VERSION_MINOR(psciver));
- error_printf("Consider setting the kvm-psci-version property on the "
- "migration source.\n");
+ error_setg_errno(errp, -ret,
+ "KVM in this kernel does not support PSCI version %d.%d",
+ (int) PSCI_VERSION_MAJOR(psciver),
+ (int) PSCI_VERSION_MINOR(psciver));
+ error_append_hint(errp, "Consider setting the kvm-psci-version property "
+ "on the migration source.\n");
return ret;
}
}
@@ -2108,16 +2111,13 @@ int kvm_arch_init_vcpu(CPUState *cs)
*/
ret = kvm_get_one_reg(cs, ARM64_SYS_REG(ARM_CPU_ID_MPIDR), &mpidr);
if (ret) {
+ error_setg_errno(errp, -ret, "failed retrieving MPIDR value");
return ret;
}
SET_IDREG(&cpu->isar, MPIDR, mpidr);
cpu->mp_affinity = mpidr & ARM64_AFFINITY_MASK;
- ret = kvm_arm_init_cpreg_list(cpu, &local_err);
- if (ret < 0) {
- error_report_err(local_err);
- }
- return ret;
+ return kvm_arm_init_cpreg_list(cpu, errp);
}
int kvm_arch_destroy_vcpu(CPUState *cs)
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index da922f72d7..474322b073 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -2218,7 +2218,7 @@ static void kvm_init_pmu_info(struct kvm_cpuid2 *cpuid, X86CPU *cpu)
}
}
-int kvm_arch_init_vcpu(CPUState *cs)
+int kvm_arch_init_vcpu(CPUState *cs, Error **errp)
{
struct {
struct kvm_cpuid2 cpuid;
@@ -2240,12 +2240,12 @@ int kvm_arch_init_vcpu(CPUState *cs)
int kvm_base = KVM_CPUID_SIGNATURE;
int max_nested_state_len;
int r;
- Error *local_err = NULL;
if (current_machine->cgs) {
r = x86_confidential_guest_check_features(
X86_CONFIDENTIAL_GUEST(current_machine->cgs), cs);
if (r < 0) {
+ error_setg(errp, "failed x86_confidential_guest_check_features (%d)", r);
return r;
}
}
@@ -2258,6 +2258,7 @@ int kvm_arch_init_vcpu(CPUState *cs)
r = kvm_arch_set_tsc_khz(cs);
if (r < 0) {
+ error_setg(errp, "failed setting tsc_khz (%d)", r);
return r;
}
@@ -2285,14 +2286,14 @@ int kvm_arch_init_vcpu(CPUState *cs)
* can still proceed and check/expand Hyper-V enlightenments here so legacy
* behavior is preserved.
*/
- if (!kvm_hyperv_expand_features(cpu, &local_err)) {
- error_report_err(local_err);
+ if (!kvm_hyperv_expand_features(cpu, errp)) {
return -ENOSYS;
}
if (hyperv_enabled(cpu)) {
r = hyperv_init_vcpu(cpu);
if (r) {
+ error_setg_errno(errp, -r, "failed hyperv_init_vcpu");
return r;
}
@@ -2371,6 +2372,7 @@ int kvm_arch_init_vcpu(CPUState *cs)
r = kvm_xen_init_vcpu(cs);
if (r) {
+ error_setg_errno(errp, -r, "failed kvm_xen_init_vcpu");
return r;
}
@@ -2419,12 +2421,12 @@ int kvm_arch_init_vcpu(CPUState *cs)
ret = kvm_get_mce_cap_supported(cs->kvm_state, &mcg_cap, &banks);
if (ret < 0) {
- fprintf(stderr, "kvm_get_mce_cap_supported: %s", strerror(-ret));
+ error_setg_errno(errp, -ret, "failed kvm_get_mce_cap_supported");
return ret;
}
if (banks < (env->mcg_cap & MCG_CAP_BANKS_MASK)) {
- error_report("kvm: Unsupported MCE bank count (QEMU = %d, KVM = %d)",
+ error_setg(errp, "kvm: Unsupported MCE bank count (QEMU = %d, KVM = %d)",
(int)(env->mcg_cap & MCG_CAP_BANKS_MASK), banks);
return -ENOTSUP;
}
@@ -2432,7 +2434,7 @@ int kvm_arch_init_vcpu(CPUState *cs)
unsupported_caps = env->mcg_cap & ~(mcg_cap | MCG_CAP_BANKS_MASK);
if (unsupported_caps) {
if (unsupported_caps & MCG_LMCE_P) {
- error_report("kvm: LMCE not supported");
+ error_setg(errp, "kvm: LMCE not supported");
return -ENOTSUP;
}
warn_report("Unsupported MCG_CAP bits: 0x%" PRIx64,
@@ -2442,7 +2444,7 @@ int kvm_arch_init_vcpu(CPUState *cs)
env->mcg_cap &= mcg_cap | MCG_CAP_BANKS_MASK;
ret = kvm_vcpu_ioctl(cs, KVM_X86_SETUP_MCE, &env->mcg_cap);
if (ret < 0) {
- fprintf(stderr, "KVM_X86_SETUP_MCE: %s", strerror(-ret));
+ error_setg_errno(errp, -ret, "failed KVM_X86_SETUP_MCE");
return ret;
}
}
@@ -2470,9 +2472,8 @@ int kvm_arch_init_vcpu(CPUState *cs)
error_setg(&invtsc_mig_blocker,
"State blocked by non-migratable CPU device"
" (invtsc flag)");
- r = migrate_add_blocker(&invtsc_mig_blocker, &local_err);
+ r = migrate_add_blocker(&invtsc_mig_blocker, errp);
if (r < 0) {
- error_report_err(local_err);
return r;
}
}
@@ -2501,6 +2502,7 @@ int kvm_arch_init_vcpu(CPUState *cs)
cpuid_data.cpuid.padding = 0;
r = kvm_vcpu_ioctl(cs, KVM_SET_CPUID2, &cpuid_data);
if (r) {
+ error_setg_errno(errp, -r, "failed KVM_SET_CPUID2");
goto fail;
}
kvm_init_xsave(env);
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
index 7ca95181a1..db39267375 100644
--- a/target/loongarch/kvm/kvm.c
+++ b/target/loongarch/kvm/kvm.c
@@ -1320,11 +1320,10 @@ int kvm_arch_pre_create_vcpu(CPUState *cpu, Error **errp)
return 0;
}
-int kvm_arch_init_vcpu(CPUState *cs)
+int kvm_arch_init_vcpu(CPUState *cs, Error **errp)
{
uint64_t val;
int ret;
- Error *local_err = NULL;
LoongArchCPU *cpu = LOONGARCH_CPU(cs);
cpu->vmsentry = qemu_add_vm_change_state_handler(
@@ -1334,51 +1333,43 @@ int kvm_arch_init_vcpu(CPUState *cs)
brk_insn = val;
}
- ret = kvm_cpu_check_lsx(cs, &local_err);
+ ret = kvm_cpu_check_lsx(cs, errp);
if (ret < 0) {
- error_report_err(local_err);
return ret;
}
- ret = kvm_cpu_check_lasx(cs, &local_err);
+ ret = kvm_cpu_check_lasx(cs, errp);
if (ret < 0) {
- error_report_err(local_err);
return ret;
}
- ret = kvm_cpu_check_lbt(cs, &local_err);
+ ret = kvm_cpu_check_lbt(cs, errp);
if (ret < 0) {
- error_report_err(local_err);
return ret;
}
- ret = kvm_cpu_check_pmu(cs, &local_err);
+ ret = kvm_cpu_check_pmu(cs, errp);
if (ret < 0) {
- error_report_err(local_err);
return ret;
}
- ret = kvm_cpu_check_pv_features(cs, &local_err);
+ ret = kvm_cpu_check_pv_features(cs, errp);
if (ret < 0) {
- error_report_err(local_err);
return ret;
}
- ret = kvm_cpu_check_ptw(cs, &local_err);
+ ret = kvm_cpu_check_ptw(cs, errp);
if (ret < 0) {
- error_report_err(local_err);
return ret;
}
- ret = kvm_cpu_check_msgint(cs, &local_err);
+ ret = kvm_cpu_check_msgint(cs, errp);
if (ret < 0) {
- error_report_err(local_err);
return ret;
}
- ret = kvm_cpu_check_misc_v1_1(cs, &local_err);
+ ret = kvm_cpu_check_misc_v1_1(cs, errp);
if (ret < 0) {
- error_report_err(local_err);
return ret;
}
diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
index 8e89a6c665..cd19f7a6fd 100644
--- a/target/ppc/kvm.c
+++ b/target/ppc/kvm.c
@@ -484,7 +484,7 @@ int kvm_arch_pre_create_vcpu(CPUState *cpu, Error **errp)
return 0;
}
-int kvm_arch_init_vcpu(CPUState *cs)
+int kvm_arch_init_vcpu(CPUState *cs, Error **errp)
{
PowerPCCPU *cpu = POWERPC_CPU(cs);
CPUPPCState *cenv = &cpu->env;
@@ -493,9 +493,10 @@ int kvm_arch_init_vcpu(CPUState *cs)
/* Synchronize sregs with kvm */
ret = kvm_arch_sync_sregs(cpu);
if (ret) {
+ error_setg_errno(errp, -ret, "Register sync failed");
if (ret == -EINVAL) {
- error_report("Register sync failed... If you're using kvm-hv.ko,"
- " only \"-cpu host\" is possible");
+ error_append_hint(errp, "If you're using kvm-hv.ko,"
+ " only \"-cpu host\" is possible\n");
}
return ret;
}
@@ -504,6 +505,9 @@ int kvm_arch_init_vcpu(CPUState *cs)
case POWERPC_MMU_BOOKE206:
/* This target supports access to KVM's guest TLB */
ret = kvm_booke206_tlb_init(cpu);
+ if (ret < 0) {
+ error_setg_errno(errp, -ret, "failed kvm_booke206_tlb_init");
+ }
break;
case POWERPC_MMU_2_07:
if (!cap_htm && !kvmppc_is_pr(cs->kvm_state)) {
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
index 5a82a63b82..523b515f2a 100644
--- a/target/riscv/kvm/kvm-cpu.c
+++ b/target/riscv/kvm/kvm-cpu.c
@@ -1605,7 +1605,7 @@ int kvm_arch_pre_create_vcpu(CPUState *cpu, Error **errp)
return 0;
}
-int kvm_arch_init_vcpu(CPUState *cs)
+int kvm_arch_init_vcpu(CPUState *cs, Error **errp)
{
int ret = 0;
RISCVCPU *cpu = RISCV_CPU(cs);
@@ -1615,6 +1615,7 @@ int kvm_arch_init_vcpu(CPUState *cs)
if (!object_dynamic_cast(OBJECT(cpu), TYPE_RISCV_CPU_HOST)) {
ret = kvm_vcpu_set_machine_ids(cpu, cs);
if (ret != 0) {
+ error_setg_errno(errp, -ret, "failed setting machine id");
return ret;
}
}
@@ -1623,6 +1624,9 @@ int kvm_arch_init_vcpu(CPUState *cs)
kvm_riscv_update_cpu_cfg_isa_ext(cpu, cs);
ret = kvm_vcpu_enable_sbi_dbcn(cpu, cs);
+ if (ret < 0) {
+ error_setg_errno(errp, -ret, "failed kvm_vcpu_enable_sbi_dbcn");
+ }
return ret;
}
diff --git a/target/s390x/kvm/kvm.c b/target/s390x/kvm/kvm.c
index dc67e84886..76dd1e67c0 100644
--- a/target/s390x/kvm/kvm.c
+++ b/target/s390x/kvm/kvm.c
@@ -403,7 +403,7 @@ int kvm_arch_pre_create_vcpu(CPUState *cpu, Error **errp)
return 0;
}
-int kvm_arch_init_vcpu(CPUState *cs)
+int kvm_arch_init_vcpu(CPUState *cs, Error **errp)
{
unsigned int max_cpus = MACHINE(qdev_get_machine())->smp.max_cpus;
S390CPU *cpu = S390_CPU(cs);
--
2.53.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH v3 for-11.2 07/10] target/arm/kvm: Introduce kvm_arm_vcpu_prepare_init_features helper
2026-10-30 7:28 [PATCH v3 for-11.2 00/10] kvm/arm: Some refactoring for custom KVM host model Eric Auger
` (5 preceding siblings ...)
2026-10-30 7:28 ` [PATCH v3 for-11.2 06/10] target/kvm: Pass an Error handle to kvm_arch_init_vcpu Eric Auger
@ 2026-10-30 7:28 ` Eric Auger
2026-10-30 7:28 ` [PATCH v3 for-11.2 08/10] hw/arm/virt: Make sure virt_get_caches() keeps on reading CLIDR_EL1 as 0 Eric Auger
` (2 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Eric Auger @ 2026-10-30 7:28 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, peter.maydell,
shaju.abraham, khushit.shah, richard.henderson, pbonzini,
skolothumtho, philmd, 7746591750, maobibo, harshpb, amachhiw,
daniel.barboza, milesg, farman, cohuck, alireza.sanaee
Cc: armbru, mbawa
Factorize the code that initializes the kvm init features from the
cpu settings in a helper. Use it in kvm_arch_init_vcpu(). Soon it will
be used by another function.
The only change in the code relates to the check of kvm_state. The
future caller won't have the VM created when calling the helper and
for this caller it is OK ignoring PSCI version setting.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Gustavo Romero <gromero@redhat.com>
Reviewed-by: Sebastian Ott <sebott@redhat.com>
Reviewed-by: Mohammadfaiz Bawa <mbawa@redhat.com>
---
target/arm/kvm.c | 50 ++++++++++++++++++++++++++++--------------------
1 file changed, 29 insertions(+), 21 deletions(-)
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index 86a4d2a6b1..b4b20c5dc2 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -2008,34 +2008,18 @@ int kvm_arch_pre_create_vcpu(CPUState *cpu, Error **errp)
return 0;
}
-int kvm_arch_init_vcpu(CPUState *cs, Error **errp)
+/* Determine init features for this CPU */
+static void kvm_arm_vcpu_prepare_init_features(ARMCPU *cpu)
{
- int ret;
- uint64_t mpidr;
- ARMCPU *cpu = ARM_CPU(cs);
+ CPUState *cs = CPU(cpu);
CPUARMState *env = &cpu->env;
- uint64_t psciver;
- if (cpu->kvm_target == QEMU_KVM_ARM_TARGET_NONE) {
- error_setg(errp, "KVM is not supported for this guest CPU type");
- return -EINVAL;
- }
-
- if (cpu->kvm_target == QEMU_KVM_ARM_TARGET_CORTEX_A53 ||
- cpu->kvm_target == QEMU_KVM_ARM_TARGET_CORTEX_A57) {
- warn_report_once("Using the cortex-a53 and cortex-a57 CPU types "
- "with KVM is deprecated. Use the max or host CPU "
- "types instead.");
- }
-
- qemu_add_vm_change_state_handler(kvm_arm_vm_state_change, cpu);
-
- /* Determine init features for this CPU */
memset(cpu->kvm_init_features, 0, sizeof(cpu->kvm_init_features));
+
if (cs->start_powered_off) {
cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_POWER_OFF;
}
- if (cpu->psci_version != QEMU_PSCI_VERSION_0_1 &&
+ if (cpu->psci_version != QEMU_PSCI_VERSION_0_1 && cs->kvm_state &&
kvm_check_extension(cs->kvm_state, KVM_CAP_ARM_PSCI_0_2)) {
/*
* Versions >= v0.2 are backward compatible with v0.2
@@ -2059,6 +2043,30 @@ int kvm_arch_init_vcpu(CPUState *cs, Error **errp)
if (cpu->has_el2 && kvm_arm_el2_supported()) {
cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_HAS_EL2;
}
+}
+
+int kvm_arch_init_vcpu(CPUState *cs, Error **errp)
+{
+ int ret;
+ uint64_t mpidr;
+ ARMCPU *cpu = ARM_CPU(cs);
+ uint64_t psciver;
+
+ if (cpu->kvm_target == QEMU_KVM_ARM_TARGET_NONE) {
+ error_setg(errp, "KVM is not supported for this guest CPU type");
+ return -EINVAL;
+ }
+
+ if (cpu->kvm_target == QEMU_KVM_ARM_TARGET_CORTEX_A53 ||
+ cpu->kvm_target == QEMU_KVM_ARM_TARGET_CORTEX_A57) {
+ warn_report_once("Using the cortex-a53 and cortex-a57 CPU types "
+ "with KVM is deprecated. Use the max or host CPU "
+ "types instead.");
+ }
+
+ qemu_add_vm_change_state_handler(kvm_arm_vm_state_change, cpu);
+
+ kvm_arm_vcpu_prepare_init_features(cpu);
/* Do KVM_ARM_VCPU_INIT ioctl */
ret = kvm_arm_vcpu_init(cpu);
--
2.53.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH v3 for-11.2 08/10] hw/arm/virt: Make sure virt_get_caches() keeps on reading CLIDR_EL1 as 0
2026-10-30 7:28 [PATCH v3 for-11.2 00/10] kvm/arm: Some refactoring for custom KVM host model Eric Auger
` (6 preceding siblings ...)
2026-10-30 7:28 ` [PATCH v3 for-11.2 07/10] target/arm/kvm: Introduce kvm_arm_vcpu_prepare_init_features helper Eric Auger
@ 2026-10-30 7:28 ` Eric Auger
2026-10-30 7:28 ` [PATCH v3 for-11.2 09/10] target/arm: Directly store cpu probe failure error Eric Auger
2026-10-30 7:28 ` [PATCH v3 for-11.2 10/10] target/arm/kvm: Pass an error handle to kvm_arm_create_scratch_host_vcpu Eric Auger
9 siblings, 0 replies; 13+ messages in thread
From: Eric Auger @ 2026-10-30 7:28 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, peter.maydell,
shaju.abraham, khushit.shah, richard.henderson, pbonzini,
skolothumtho, philmd, 7746591750, maobibo, harshpb, amachhiw,
daniel.barboza, milesg, farman, cohuck, alireza.sanaee
Cc: armbru, mbawa
In KVM mode, virt_get_caches() currently gets a zero value for the
CLIDR_EL1 register. This is due to the fact CLIDR is never read from
host. This is a bug.
Soon we will initialize all writable isar.idreg[] from host and this
includes CLIDR_EL1. However, we cannot directly fix the initialization,
first because it would change the way caches are exposed to guest in
DT/ACPI descriptions and because some host values would be rejected
by the current QEMU code, especially in the case host has a unified
L1 cache which is currently not supported and triggers the following
error: "Unified type is not implemented at level 1" error.
So this issue will be fixed separately.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Khushit Shah <khushit.shah@nutanix.com>
Reviewed-by: Gustavo Romero <gromero@redhat.com>
Reviewed-by: Mohammadfaiz Bawa <mbawa@redhat.com>
---
v1 -> v2:
- fix the commit msg and improved comment (Gustavo)
---
hw/arm/virt.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 0d56197dac..a80c60f3fa 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -338,6 +338,21 @@ unsigned int virt_get_caches(const VirtMachineState *vms, CPUCoreCaches *caches)
ARMISARegisters *isar = &armcpu->isar;
uint32_t clidr = GET_IDREG(isar, CLIDR);
+ /*
+ * Commit f669de70011 ("hw/arm/virt: add cache hierarchy to device tree")
+ * read the CLIDR value from the isar array. However, in KVM mode, we failed
+ * to initialize that register value from host and the resulting bug is that
+ * we have always read 0.
+ *
+ * Soon we will initialize all writable isar.idreg[] from host, including
+ * CLIDR_EL1 but we will need to handle compat properly and also extend the
+ * support to unified L1 cache. For now do not pretend we have something
+ * different from 0.
+ */
+ if (kvm_enabled()) {
+ clidr = 0;
+ }
+
for (int cache_level = 1; cache_level <= CLIDR_CTYPE_MAX_CACHE_LEVEL;
cache_level++) {
uint8_t ctype =
--
2.53.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH v3 for-11.2 09/10] target/arm: Directly store cpu probe failure error
2026-10-30 7:28 [PATCH v3 for-11.2 00/10] kvm/arm: Some refactoring for custom KVM host model Eric Auger
` (7 preceding siblings ...)
2026-10-30 7:28 ` [PATCH v3 for-11.2 08/10] hw/arm/virt: Make sure virt_get_caches() keeps on reading CLIDR_EL1 as 0 Eric Auger
@ 2026-10-30 7:28 ` Eric Auger
2026-10-30 10:33 ` Peter Maydell
2026-10-30 7:28 ` [PATCH v3 for-11.2 10/10] target/arm/kvm: Pass an error handle to kvm_arm_create_scratch_host_vcpu Eric Auger
9 siblings, 1 reply; 13+ messages in thread
From: Eric Auger @ 2026-10-30 7:28 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, peter.maydell,
shaju.abraham, khushit.shah, richard.henderson, pbonzini,
skolothumtho, philmd, 7746591750, maobibo, harshpb, amachhiw,
daniel.barboza, milesg, farman, cohuck, alireza.sanaee
Cc: armbru, mbawa
In case *_arm_host_cpu_features() fails, we currently
record that state in cpu->host_cpu_probe_failed to later
report the error on realize().
Replace the boolean by an error handle to allow
more precise error reports.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
---
target/arm/cpu.h | 5 +++--
target/arm/cpu.c | 9 +++++----
target/arm/hvf/hvf.c | 3 ++-
target/arm/kvm.c | 24 +++++++++++-------------
target/arm/whpx/whpx-all.c | 3 ++-
5 files changed, 23 insertions(+), 21 deletions(-)
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 5c5f551dac..dae79539b5 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1075,10 +1075,11 @@ struct ArchCPU {
/* Uniprocessor system with MP extensions */
bool mp_is_up;
- /* True if we tried kvm_arm_host_cpu_features() during CPU instance_init
+ /*
+ * Set if we tried *_set_cpu_features_from_host() during CPU instance_init
* and the probe failed (so we need to report the error in realize)
*/
- bool host_cpu_probe_failed;
+ Error *host_cpu_probe_err;
/* QOM property to indicate we should use the back-compat CNTFRQ default */
bool backcompat_cntfrq;
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index aba45b66f8..67d48ebc07 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -1838,12 +1838,13 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
* then it's possible that might have failed in the initfn, but
* this is the first point where we can report it.
*/
- if (cpu->host_cpu_probe_failed) {
+ if (cpu->host_cpu_probe_err) {
if (!kvm_enabled() && !hvf_enabled() && !whpx_enabled()) {
- error_setg(errp, "The 'host' CPU type can only be used with KVM, HVF or WHPX");
- } else {
- error_setg(errp, "Failed to retrieve host CPU features");
+ error_append_hint(&cpu->host_cpu_probe_err,
+ "The 'host' CPU type can only be used with KVM, HVF or WHPX\n");
}
+ error_propagate(errp, cpu->host_cpu_probe_err);
+ cpu->host_cpu_probe_err = NULL;
return;
}
diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
index 4b947e9ba5..2f2a46644d 100644
--- a/target/arm/hvf/hvf.c
+++ b/target/arm/hvf/hvf.c
@@ -1287,7 +1287,8 @@ void hvf_arm_set_cpu_features_from_host(ARMCPU *cpu)
* We can't report this error yet, so flag that we need to
* in arm_cpu_realizefn().
*/
- cpu->host_cpu_probe_failed = true;
+ error_setg(&cpu->host_cpu_probe_err,
+ "failed to retrieve host CPU features");
return;
}
}
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index b4b20c5dc2..fc9551411e 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -312,7 +312,7 @@ static uint32_t kvm_arm_sve_get_vls(int fd)
return vls[0] & MAKE_64BIT_MASK(0, ARM_MAX_VQ);
}
-static void kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
+static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
{
/* Identify the feature bits corresponding to the host CPU, and
* fill out the ARMHostCPUClass fields accordingly. To do this
@@ -330,7 +330,7 @@ static void kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
ahcf->dtb_compatible = "arm,armv8";
if (!kvm_enabled()) {
- return;
+ return false;
}
/*
@@ -372,7 +372,7 @@ static void kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
}
if (!kvm_arm_create_scratch_host_vcpu(fdarray, &init)) {
- return;
+ return false;
}
int fd = fdarray[2];
@@ -502,7 +502,7 @@ static void kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
kvm_arm_destroy_scratch_host_vcpu(fdarray);
if (err < 0) {
- return;
+ return false;
}
/*
@@ -521,27 +521,25 @@ static void kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
ahcf->target = init.target;
ahcf->features = features;
+ return true;
}
void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
{
CPUARMState *env = &cpu->env;
+ static bool probe_ok;
if (!arm_host_cpu_features.dtb_compatible) {
- kvm_arm_get_host_cpu_features(&arm_host_cpu_features);
+ probe_ok = kvm_arm_get_host_cpu_features(&arm_host_cpu_features);
}
- cpu->kvm_target = arm_host_cpu_features.target;
-
- if (cpu->kvm_target == QEMU_KVM_ARM_TARGET_NONE) {
- /*
- * We can't report this error yet, so flag that we need to
- * in arm_cpu_realizefn().
- */
- cpu->host_cpu_probe_failed = true;
+ if (!probe_ok) {
+ error_setg(&cpu->host_cpu_probe_err,
+ "failed to retrieve host CPU features");
return;
}
+ cpu->kvm_target = arm_host_cpu_features.target;
cpu->dtb_compatible = arm_host_cpu_features.dtb_compatible;
cpu->isar = arm_host_cpu_features.isar;
cpu->sve_vq.supported = arm_host_cpu_features.sve_vq_supported;
diff --git a/target/arm/whpx/whpx-all.c b/target/arm/whpx/whpx-all.c
index 024d18df04..ded42c980b 100644
--- a/target/arm/whpx/whpx-all.c
+++ b/target/arm/whpx/whpx-all.c
@@ -767,7 +767,8 @@ void whpx_arm_set_cpu_features_from_host(ARMCPU *cpu)
* We can't report this error yet, so flag that we need to
* in arm_cpu_realizefn().
*/
- cpu->host_cpu_probe_failed = true;
+ error_setg(&cpu->host_cpu_probe_err,
+ "failed to retrieve host CPU features");
return;
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* Re: [PATCH v3 for-11.2 09/10] target/arm: Directly store cpu probe failure error
2026-10-30 7:28 ` [PATCH v3 for-11.2 09/10] target/arm: Directly store cpu probe failure error Eric Auger
@ 2026-10-30 10:33 ` Peter Maydell
0 siblings, 0 replies; 13+ messages in thread
From: Peter Maydell @ 2026-10-30 10:33 UTC (permalink / raw)
To: Eric Auger
Cc: eric.auger.pro, qemu-devel, qemu-arm, shaju.abraham, khushit.shah,
richard.henderson, pbonzini, skolothumtho, philmd, 7746591750,
maobibo, harshpb, amachhiw, daniel.barboza, milesg, farman,
cohuck, alireza.sanaee, armbru, mbawa
On Fri, 30 Oct 2026 at 07:31, Eric Auger <eric.auger@redhat.com> wrote:
>
> In case *_arm_host_cpu_features() fails, we currently
> record that state in cpu->host_cpu_probe_failed to later
> report the error on realize().
>
> Replace the boolean by an error handle to allow
> more precise error reports.
>
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> Suggested-by: Peter Maydell <peter.maydell@linaro.org>
> ---
> target/arm/cpu.h | 5 +++--
> target/arm/cpu.c | 9 +++++----
> target/arm/hvf/hvf.c | 3 ++-
> target/arm/kvm.c | 24 +++++++++++-------------
> target/arm/whpx/whpx-all.c | 3 ++-
> 5 files changed, 23 insertions(+), 21 deletions(-)
>
> diff --git a/target/arm/cpu.h b/target/arm/cpu.h
> index 5c5f551dac..dae79539b5 100644
> --- a/target/arm/cpu.h
> +++ b/target/arm/cpu.h
> @@ -1075,10 +1075,11 @@ struct ArchCPU {
> /* Uniprocessor system with MP extensions */
> bool mp_is_up;
>
> - /* True if we tried kvm_arm_host_cpu_features() during CPU instance_init
> + /*
> + * Set if we tried *_set_cpu_features_from_host() during CPU instance_init
> * and the probe failed (so we need to report the error in realize)
> */
> - bool host_cpu_probe_failed;
> + Error *host_cpu_probe_err;
>
> /* QOM property to indicate we should use the back-compat CNTFRQ default */
> bool backcompat_cntfrq;
> diff --git a/target/arm/cpu.c b/target/arm/cpu.c
> index aba45b66f8..67d48ebc07 100644
> --- a/target/arm/cpu.c
> +++ b/target/arm/cpu.c
> @@ -1838,12 +1838,13 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
> * then it's possible that might have failed in the initfn, but
> * this is the first point where we can report it.
> */
> - if (cpu->host_cpu_probe_failed) {
> + if (cpu->host_cpu_probe_err) {
> if (!kvm_enabled() && !hvf_enabled() && !whpx_enabled()) {
> - error_setg(errp, "The 'host' CPU type can only be used with KVM, HVF or WHPX");
> - } else {
> - error_setg(errp, "Failed to retrieve host CPU features");
> + error_append_hint(&cpu->host_cpu_probe_err,
> + "The 'host' CPU type can only be used with KVM, HVF or WHPX\n");
I don't think we should be doing this as error_append_hint(). If
the accelerator isn't one that supports 'host' then "host
can only be used with KVM, HVF or WHPX" is the entire and
correct thing to report to the user, and whatever specifically
might have been the trigger for us to notice this is irrelevant.
> }
> + error_propagate(errp, cpu->host_cpu_probe_err);
> + cpu->host_cpu_probe_err = NULL;
> return;
> }
Don't we also need to free the Error in finalize, to catch the case
where we did "instance_init -> finalize" and don't get here ?
> diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
> index 4b947e9ba5..2f2a46644d 100644
> --- a/target/arm/hvf/hvf.c
> +++ b/target/arm/hvf/hvf.c
> @@ -1287,7 +1287,8 @@ void hvf_arm_set_cpu_features_from_host(ARMCPU *cpu)
> * We can't report this error yet, so flag that we need to
> * in arm_cpu_realizefn().
> */
> - cpu->host_cpu_probe_failed = true;
> + error_setg(&cpu->host_cpu_probe_err,
> + "failed to retrieve host CPU features");
> return;
> }
> }
> diff --git a/target/arm/kvm.c b/target/arm/kvm.c
> index b4b20c5dc2..fc9551411e 100644
> --- a/target/arm/kvm.c
> +++ b/target/arm/kvm.c
> @@ -312,7 +312,7 @@ static uint32_t kvm_arm_sve_get_vls(int fd)
> return vls[0] & MAKE_64BIT_MASK(0, ARM_MAX_VQ);
> }
>
> -static void kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
> +static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
> {
> /* Identify the feature bits corresponding to the host CPU, and
> * fill out the ARMHostCPUClass fields accordingly. To do this
> @@ -330,7 +330,7 @@ static void kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
> ahcf->dtb_compatible = "arm,armv8";
>
> if (!kvm_enabled()) {
> - return;
> + return false;
> }
>
> /*
> @@ -372,7 +372,7 @@ static void kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
> }
>
> if (!kvm_arm_create_scratch_host_vcpu(fdarray, &init)) {
> - return;
> + return false;
> }
>
> int fd = fdarray[2];
> @@ -502,7 +502,7 @@ static void kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
> kvm_arm_destroy_scratch_host_vcpu(fdarray);
>
> if (err < 0) {
> - return;
> + return false;
> }
>
> /*
> @@ -521,27 +521,25 @@ static void kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
>
> ahcf->target = init.target;
> ahcf->features = features;
> + return true;
> }
I don't think you need to change the return type of this function
and introduce a static probe_ok variable in the caller. The
thing that tells you that the probe succeeded is that it set
ahcf->target to something other than QEMU_KVM_ARM_TARGET_NONE,
which it only does right at the very end when it has definitely
succeeded.
(It is a bit obscure that the contract between kvm_arm_get_host_cpu_features()
and its caller is "ahcf->dtb_compatible NULL means we haven't tried a
probe yet; ahcf->kvm_target still TARGET_NONE after probe means the
probe failed". We could probably add a comment about this, but that's
separate from what this patch is doing.)
> void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
> {
> CPUARMState *env = &cpu->env;
> + static bool probe_ok;
>
> if (!arm_host_cpu_features.dtb_compatible) {
> - kvm_arm_get_host_cpu_features(&arm_host_cpu_features);
> + probe_ok = kvm_arm_get_host_cpu_features(&arm_host_cpu_features);
> }
>
> - cpu->kvm_target = arm_host_cpu_features.target;
> -
> - if (cpu->kvm_target == QEMU_KVM_ARM_TARGET_NONE) {
> - /*
> - * We can't report this error yet, so flag that we need to
> - * in arm_cpu_realizefn().
> - */
> - cpu->host_cpu_probe_failed = true;
> + if (!probe_ok) {
> + error_setg(&cpu->host_cpu_probe_err,
> + "failed to retrieve host CPU features");
> return;
> }
>
> + cpu->kvm_target = arm_host_cpu_features.target;
> cpu->dtb_compatible = arm_host_cpu_features.dtb_compatible;
> cpu->isar = arm_host_cpu_features.isar;
> cpu->sve_vq.supported = arm_host_cpu_features.sve_vq_supported;
-- PMM
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v3 for-11.2 10/10] target/arm/kvm: Pass an error handle to kvm_arm_create_scratch_host_vcpu
2026-10-30 7:28 [PATCH v3 for-11.2 00/10] kvm/arm: Some refactoring for custom KVM host model Eric Auger
` (8 preceding siblings ...)
2026-10-30 7:28 ` [PATCH v3 for-11.2 09/10] target/arm: Directly store cpu probe failure error Eric Auger
@ 2026-10-30 7:28 ` Eric Auger
2026-10-30 10:37 ` Peter Maydell
9 siblings, 1 reply; 13+ messages in thread
From: Eric Auger @ 2026-10-30 7:28 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, peter.maydell,
shaju.abraham, khushit.shah, richard.henderson, pbonzini,
skolothumtho, philmd, 7746591750, maobibo, harshpb, amachhiw,
daniel.barboza, milesg, farman, cohuck, alireza.sanaee
Cc: armbru, mbawa
This allows to report a precise error message if any error occurs.
In arm_gic_cap_kvm_probe() call path we just pass a NULL error handle
because we don't care about the failure, reverting to emulated
versions.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
---
target/arm/kvm_arm.h | 3 ++-
target/arm/kvm.c | 27 ++++++++++++++++++---------
2 files changed, 20 insertions(+), 10 deletions(-)
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
index e7c40fb003..9c7e7f654a 100644
--- a/target/arm/kvm_arm.h
+++ b/target/arm/kvm_arm.h
@@ -105,6 +105,7 @@ struct kvm_vcpu_init;
* @init: filled in with the necessary values for creating a host
* vcpu. If NULL is provided, will not init the vCPU (though the cpufd
* will still be set up).
+ * @errp: Error handle
*
* Create a scratch vcpu in its own VM of the type preferred by the host
* kernel (as would be used for '-cpu host'), for purposes of probing it
@@ -114,7 +115,7 @@ struct kvm_vcpu_init;
* false on failure (and fdarray and init are not valid).
*/
bool kvm_arm_create_scratch_host_vcpu(int *fdarray,
- struct kvm_vcpu_init *init);
+ struct kvm_vcpu_init *init, Error **errp);
/**
* kvm_arm_destroy_scratch_host_vcpu:
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index fc9551411e..c6ba2cb29a 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -104,13 +104,14 @@ static int kvm_arm_vcpu_finalize(ARMCPU *cpu, int feature)
}
bool kvm_arm_create_scratch_host_vcpu(int *fdarray,
- struct kvm_vcpu_init *init)
+ struct kvm_vcpu_init *init, Error **errp)
{
int ret = 0, kvmfd = -1, vmfd = -1, cpufd = -1;
int max_vm_pa_size;
kvmfd = qemu_open_old("/dev/kvm", O_RDWR);
if (kvmfd < 0) {
+ error_setg_errno(errp, errno, "Failed to open /dev/kvm");
goto err;
}
max_vm_pa_size = ioctl(kvmfd, KVM_CHECK_EXTENSION, KVM_CAP_ARM_VM_IPA_SIZE);
@@ -121,6 +122,7 @@ bool kvm_arm_create_scratch_host_vcpu(int *fdarray,
vmfd = ioctl(kvmfd, KVM_CREATE_VM, max_vm_pa_size);
} while (vmfd == -1 && errno == EINTR);
if (vmfd < 0) {
+ error_setg_errno(errp, errno, "Failed to create the scratch VM");
goto err;
}
@@ -140,6 +142,7 @@ bool kvm_arm_create_scratch_host_vcpu(int *fdarray,
cpufd = ioctl(vmfd, KVM_CREATE_VCPU, 0);
if (cpufd < 0) {
+ error_setg_errno(errp, errno, "Failed to create the scratch VCPU");
goto err;
}
@@ -153,12 +156,16 @@ bool kvm_arm_create_scratch_host_vcpu(int *fdarray,
ret = ioctl(vmfd, KVM_ARM_PREFERRED_TARGET, &preferred);
if (ret < 0) {
+ error_setg_errno(errp, errno,
+ "Failed to get the preferred KVM target");
goto err;
}
init->target = preferred.target;
}
ret = ioctl(cpufd, KVM_ARM_VCPU_INIT, init);
if (ret < 0) {
+ error_setg_errno(errp, errno,
+ "Failed to initialize the scratch VCPU");
goto err;
}
@@ -312,7 +319,8 @@ static uint32_t kvm_arm_sve_get_vls(int fd)
return vls[0] & MAKE_64BIT_MASK(0, ARM_MAX_VQ);
}
-static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
+static bool
+kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf, Error **errp)
{
/* Identify the feature bits corresponding to the host CPU, and
* fill out the ARMHostCPUClass fields accordingly. To do this
@@ -330,6 +338,7 @@ static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
ahcf->dtb_compatible = "arm,armv8";
if (!kvm_enabled()) {
+ error_setg(errp, "KVM is not enabled");
return false;
}
@@ -371,7 +380,7 @@ static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
features |= 1ULL << ARM_FEATURE_PMU;
}
- if (!kvm_arm_create_scratch_host_vcpu(fdarray, &init)) {
+ if (!kvm_arm_create_scratch_host_vcpu(fdarray, &init, errp)) {
return false;
}
@@ -502,6 +511,7 @@ static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
kvm_arm_destroy_scratch_host_vcpu(fdarray);
if (err < 0) {
+ error_setg(errp, "Failed to read some host CPU ID registers");
return false;
}
@@ -527,15 +537,14 @@ static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
{
CPUARMState *env = &cpu->env;
- static bool probe_ok;
+ static Error *probe_err;
if (!arm_host_cpu_features.dtb_compatible) {
- probe_ok = kvm_arm_get_host_cpu_features(&arm_host_cpu_features);
+ kvm_arm_get_host_cpu_features(&arm_host_cpu_features, &probe_err);
}
- if (!probe_ok) {
- error_setg(&cpu->host_cpu_probe_err,
- "failed to retrieve host CPU features");
+ if (probe_err) {
+ cpu->host_cpu_probe_err = error_copy(probe_err);
return;
}
@@ -2671,7 +2680,7 @@ void arm_gic_cap_kvm_probe(GICCapability *v2, GICCapability *v3)
{
int fdarray[3];
- if (!kvm_arm_create_scratch_host_vcpu(fdarray, NULL)) {
+ if (!kvm_arm_create_scratch_host_vcpu(fdarray, NULL, NULL)) {
return;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* Re: [PATCH v3 for-11.2 10/10] target/arm/kvm: Pass an error handle to kvm_arm_create_scratch_host_vcpu
2026-10-30 7:28 ` [PATCH v3 for-11.2 10/10] target/arm/kvm: Pass an error handle to kvm_arm_create_scratch_host_vcpu Eric Auger
@ 2026-10-30 10:37 ` Peter Maydell
0 siblings, 0 replies; 13+ messages in thread
From: Peter Maydell @ 2026-10-30 10:37 UTC (permalink / raw)
To: Eric Auger
Cc: eric.auger.pro, qemu-devel, qemu-arm, shaju.abraham, khushit.shah,
richard.henderson, pbonzini, skolothumtho, philmd, 7746591750,
maobibo, harshpb, amachhiw, daniel.barboza, milesg, farman,
cohuck, alireza.sanaee, armbru, mbawa
On Fri, 30 Oct 2026 at 07:31, Eric Auger <eric.auger@redhat.com> wrote:
>
> This allows to report a precise error message if any error occurs.
>
> In arm_gic_cap_kvm_probe() call path we just pass a NULL error handle
> because we don't care about the failure, reverting to emulated
> versions.
>
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> @@ -527,15 +537,14 @@ static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
> void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
> {
> CPUARMState *env = &cpu->env;
> - static bool probe_ok;
> + static Error *probe_err;
I'm not a fan of this static variable. I'd prefer if we put the Error*
into the ARMHostCPUFeatures struct.
-- PMM
^ permalink raw reply [flat|nested] 13+ messages in thread