target/arm: Fix register definitions for VMIDR and VMPIDR

The register definitions for VMIDR and VMPIDR have separate
reginfo structs for the AArch32 and AArch64 registers. However
the 32-bit versions are wrong:
* they use offsetof instead of offsetoflow32 to mark where
the 32-bit value lives in the uint64_t CPU state field
* they don't mark themselves as ARM_CP_ALIAS

In particular this means that if you try to use an Arm guest CPU
which enables EL2 on a big-endian host it will assert at reset:
target/arm/cpu.c:114: cp_reg_check_reset: Assertion `oldvalue == newvalue' failed.

because the reset of the 32-bit register writes to the top
half of the uint64_t.

Correct the errors in the structures.

Backports commit 36476562d57a3b64bbe86db26e63677dd21907c5 from qemu
This commit is contained in:
Peter Maydell 2018-03-08 12:26:01 -05:00 committed by Lioncash
parent 283abedc68
commit f4df29ca4f
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7

View file

@ -4405,13 +4405,13 @@ void register_cp_regs_for_features(ARMCPU *cpu)
if (arm_feature(env, ARM_FEATURE_EL2)) {
uint64_t vmpidr_def = mpidr_read_val(env);
ARMCPRegInfo vpidr_regs[] = {
{ "VPIDR", 15,0,0, 0,4,0, ARM_CP_STATE_AA32, 0,
PL2_RW, 0, NULL, cpu->midr, offsetof(CPUARMState, cp15.vpidr_el2), {0, 0},
{ "VPIDR", 15,0,0, 0,4,0, ARM_CP_STATE_AA32, ARM_CP_ALIAS,
PL2_RW, 0, NULL, cpu->midr, offsetoflow32(CPUARMState, cp15.vpidr_el2), {0, 0},
access_el3_aa32ns },
{ "VPIDR_EL2", 0,0,0, 3,4,0, ARM_CP_STATE_AA64, 0,
PL2_RW, 0, NULL, cpu->midr, offsetof(CPUARMState, cp15.vpidr_el2) },
{ "VMPIDR", 15,0,0, 0,4,5, ARM_CP_STATE_AA32, 0,
PL2_RW, 0, NULL, vmpidr_def, offsetof(CPUARMState, cp15.vmpidr_el2), {0, 0},
{ "VMPIDR", 15,0,0, 0,4,5, ARM_CP_STATE_AA32, ARM_CP_ALIAS,
PL2_RW, 0, NULL, vmpidr_def, offsetoflow32(CPUARMState, cp15.vmpidr_el2), {0, 0},
access_el3_aa32ns },
{ "VMPIDR_EL2", 0,0,0, 3,4,5, ARM_CP_STATE_AA64, 0,
PL2_RW, 0, NULL, vmpidr_def, offsetof(CPUARMState, cp15.vmpidr_el2) },