diff mbox series

[4/7] target/arm: Fix big-endian host handling of VTCR

Message ID 20220714132303.1287193-5-peter.maydell@linaro.org
State Superseded
Headers show
Series target/arm: Handle VTCR_EL2 bits shared between S and NS EL2 | expand

Commit Message

Peter Maydell July 14, 2022, 1:23 p.m. UTC
We have a bug in our handling of accesses to the AArch32 VTCR
register on big-endian hosts: we were not adjusting the part of the
uint64_t field within TCR that the generated code would access.  That
can be done with offsetoflow32(), by using an ARM_CP_STATE_BOTH cpreg
struct, or by defining a full set of read/write/reset functions --
the various other TCR cpreg structs used one or another of those
strategies, but for VTCR we did not, so on a big-endian host VTCR
accesses would touch the wrong half of the register.

Use offsetoflow32() in the VTCR register struct.  This works even
though the field in the CPU struct is currently a struct TCR, because
the first field in that struct is the uint64_t raw_tcr.

None of the other TCR registers have this bug -- either they are
AArch64 only, or else they define resetfn, writefn, etc, and
expect to be passed the full struct pointer.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
Actually I'm not 100% sure that TTBCR is handled correctly for
big-endian hosts. But it's going to go away shortly anyway.
---
 target/arm/helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Comments

Richard Henderson July 14, 2022, 11:19 p.m. UTC | #1
On 7/14/22 18:53, Peter Maydell wrote:
> We have a bug in our handling of accesses to the AArch32 VTCR
> register on big-endian hosts: we were not adjusting the part of the
> uint64_t field within TCR that the generated code would access.  That
> can be done with offsetoflow32(), by using an ARM_CP_STATE_BOTH cpreg
> struct, or by defining a full set of read/write/reset functions --
> the various other TCR cpreg structs used one or another of those
> strategies, but for VTCR we did not, so on a big-endian host VTCR
> accesses would touch the wrong half of the register.
> 
> Use offsetoflow32() in the VTCR register struct.  This works even
> though the field in the CPU struct is currently a struct TCR, because
> the first field in that struct is the uint64_t raw_tcr.
> 
> None of the other TCR registers have this bug -- either they are
> AArch64 only, or else they define resetfn, writefn, etc, and
> expect to be passed the full struct pointer.
> 
> Signed-off-by: Peter Maydell<peter.maydell@linaro.org>
> ---

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>

r~
diff mbox series

Patch

diff --git a/target/arm/helper.c b/target/arm/helper.c
index 3d4317c4c85..7eee2007a0e 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -5409,7 +5409,7 @@  static const ARMCPRegInfo el2_cp_reginfo[] = {
       .cp = 15, .opc1 = 4, .crn = 2, .crm = 1, .opc2 = 2,
       .type = ARM_CP_ALIAS,
       .access = PL2_RW, .accessfn = access_el3_aa32ns,
-      .fieldoffset = offsetof(CPUARMState, cp15.vtcr_el2) },
+      .fieldoffset = offsetoflow32(CPUARMState, cp15.vtcr_el2) },
     { .name = "VTCR_EL2", .state = ARM_CP_STATE_AA64,
       .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 1, .opc2 = 2,
       .access = PL2_RW,