[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 22/27] target-arm: Add debug check for mismatched cpr
From: |
Peter Maydell |
Subject: |
[Qemu-devel] [PULL 22/27] target-arm: Add debug check for mismatched cpreg resets |
Date: |
Thu, 13 Aug 2015 11:44:42 +0100 |
It's easy to accidentally define two cpregs which both try
to reset the same underlying state field (for instance a
clash between an AArch64 EL3 definition and an AArch32
banked register definition). if the two definitions disagree
about the reset value then the result is dependent on which
one happened to be reached last in the hashtable enumeration.
Add a consistency check to detect and assert in these cases:
after reset, we run a second pass where we check that the
reset operation doesn't change the value of the register.
Signed-off-by: Peter Maydell <address@hidden>
Reviewed-by: Edgar E. Iglesias <address@hidden>
Message-id: address@hidden
---
target-arm/cpu.c | 23 +++++++++++++++++++++++
target-arm/cpu.h | 3 +++
target-arm/helper.c | 2 +-
3 files changed, 27 insertions(+), 1 deletion(-)
diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index 3525348..3c84f72 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -79,6 +79,27 @@ static void cp_reg_reset(gpointer key, gpointer value,
gpointer opaque)
}
}
+static void cp_reg_check_reset(gpointer key, gpointer value, gpointer opaque)
+{
+ /* Purely an assertion check: we've already done reset once,
+ * so now check that running the reset for the cpreg doesn't
+ * change its value. This traps bugs where two different cpregs
+ * both try to reset the same state field but to different values.
+ */
+ ARMCPRegInfo *ri = value;
+ ARMCPU *cpu = opaque;
+ uint64_t oldvalue, newvalue;
+
+ if (ri->type & (ARM_CP_SPECIAL | ARM_CP_ALIAS | ARM_CP_NO_RAW)) {
+ return;
+ }
+
+ oldvalue = read_raw_cp_reg(&cpu->env, ri);
+ cp_reg_reset(key, value, opaque);
+ newvalue = read_raw_cp_reg(&cpu->env, ri);
+ assert(oldvalue == newvalue);
+}
+
/* CPUClass::reset() */
static void arm_cpu_reset(CPUState *s)
{
@@ -90,6 +111,8 @@ static void arm_cpu_reset(CPUState *s)
memset(env, 0, offsetof(CPUARMState, features));
g_hash_table_foreach(cpu->cp_regs, cp_reg_reset, cpu);
+ g_hash_table_foreach(cpu->cp_regs, cp_reg_check_reset, cpu);
+
env->vfp.xregs[ARM_VFP_FPSID] = cpu->reset_fpsid;
env->vfp.xregs[ARM_VFP_MVFR0] = cpu->mvfr0;
env->vfp.xregs[ARM_VFP_MVFR1] = cpu->mvfr1;
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 7346c5f..ebca342 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -1448,6 +1448,9 @@ static inline bool cp_access_ok(int current_el,
return (ri->access >> ((current_el * 2) + isread)) & 1;
}
+/* Raw read of a coprocessor register (as needed for migration, etc) */
+uint64_t read_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri);
+
/**
* write_list_to_cpustate
* @cpu: ARMCPU
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 4a7dd24..49ce612 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -144,7 +144,7 @@ static void *raw_ptr(CPUARMState *env, const ARMCPRegInfo
*ri)
return (char *)env + ri->fieldoffset;
}
-static uint64_t read_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri)
+uint64_t read_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri)
{
/* Raw read of a coprocessor register (as needed for migration, etc). */
if (ri->type & ARM_CP_CONST) {
--
1.9.1
- [Qemu-devel] [PULL 00/27] target-arm queue, Peter Maydell, 2015/08/13
- [Qemu-devel] [PULL 18/27] i.MX: Fix Coding style for GPT emulator, Peter Maydell, 2015/08/13
- [Qemu-devel] [PULL 01/27] target-arm: Add CNTVOFF_EL2, Peter Maydell, 2015/08/13
- [Qemu-devel] [PULL 16/27] i.MX: Fix Coding style for EPIT emulator, Peter Maydell, 2015/08/13
- [Qemu-devel] [PULL 22/27] target-arm: Add debug check for mismatched cpreg resets,
Peter Maydell <=
- [Qemu-devel] [PULL 23/27] target-arm: Add the AArch64 view of the Secure physical timer, Peter Maydell, 2015/08/13
- [Qemu-devel] [PULL 12/27] i.MX: Fix Coding style for AVIC emulator., Peter Maydell, 2015/08/13
- [Qemu-devel] [PULL 15/27] i.MX: Split EPIT emulator in a header file and a source file, Peter Maydell, 2015/08/13
- [Qemu-devel] [PULL 17/27] i.MX: Split GPT emulator in a header file and a source file, Peter Maydell, 2015/08/13
- [Qemu-devel] [PULL 24/27] target-arm: Add AArch32 banked register access to secure physical timer, Peter Maydell, 2015/08/13
- [Qemu-devel] [PULL 10/27] i.MX:Fix Coding style for UART emulator., Peter Maydell, 2015/08/13
- [Qemu-devel] [PULL 20/27] hw/arm/gic: Kill code duplication, Peter Maydell, 2015/08/13
- [Qemu-devel] [PULL 06/27] hw/arm/virt: Replace magic IRQ constants with macros, Peter Maydell, 2015/08/13
- [Qemu-devel] [PULL 19/27] Merge memory_region_init_reservation() into memory_region_init_io(), Peter Maydell, 2015/08/13
- [Qemu-devel] [PULL 02/27] target-arm: Add CNTHCTL_EL2, Peter Maydell, 2015/08/13