target/arm: Honour VTCR_EL2 bits in Secure EL2

In regime_tcr() we return the appropriate TCR register for the
translation regime.  For Secure EL2, we return the VSTCR_EL2 value,
but in this translation regime some fields that control behaviour are
in VTCR_EL2.  When this code was originally written (as the comment
notes), QEMU didn't care about any of those fields, but we have since
added support for features such as LPA2 which do need the values from
those fields.

Synthesize a TCR value by merging in the relevant VTCR_EL2 fields to
the VSTCR_EL2 value.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1103
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20220714132303.1287193-8-peter.maydell@linaro.org
This commit is contained in:
Peter Maydell 2022-07-14 14:23:03 +01:00
parent cb4a0a3444
commit f04383e749
2 changed files with 38 additions and 3 deletions

View File

@ -1412,6 +1412,25 @@ FIELD(CPTR_EL3, TCPAC, 31, 1)
#define TTBCR_SH1 (1U << 28) #define TTBCR_SH1 (1U << 28)
#define TTBCR_EAE (1U << 31) #define TTBCR_EAE (1U << 31)
FIELD(VTCR, T0SZ, 0, 6)
FIELD(VTCR, SL0, 6, 2)
FIELD(VTCR, IRGN0, 8, 2)
FIELD(VTCR, ORGN0, 10, 2)
FIELD(VTCR, SH0, 12, 2)
FIELD(VTCR, TG0, 14, 2)
FIELD(VTCR, PS, 16, 3)
FIELD(VTCR, VS, 19, 1)
FIELD(VTCR, HA, 21, 1)
FIELD(VTCR, HD, 22, 1)
FIELD(VTCR, HWU59, 25, 1)
FIELD(VTCR, HWU60, 26, 1)
FIELD(VTCR, HWU61, 27, 1)
FIELD(VTCR, HWU62, 28, 1)
FIELD(VTCR, NSW, 29, 1)
FIELD(VTCR, NSA, 30, 1)
FIELD(VTCR, DS, 32, 1)
FIELD(VTCR, SL2, 33, 1)
/* Bit definitions for ARMv8 SPSR (PSTATE) format. /* Bit definitions for ARMv8 SPSR (PSTATE) format.
* Only these are valid when in AArch64 mode; in * Only these are valid when in AArch64 mode; in
* AArch32 mode SPSRs are basically CPSR-format. * AArch32 mode SPSRs are basically CPSR-format.

View File

@ -777,6 +777,16 @@ static inline uint64_t regime_sctlr(CPUARMState *env, ARMMMUIdx mmu_idx)
return env->cp15.sctlr_el[regime_el(env, mmu_idx)]; return env->cp15.sctlr_el[regime_el(env, mmu_idx)];
} }
/*
* These are the fields in VTCR_EL2 which affect both the Secure stage 2
* and the Non-Secure stage 2 translation regimes (and hence which are
* not present in VSTCR_EL2).
*/
#define VTCR_SHARED_FIELD_MASK \
(R_VTCR_IRGN0_MASK | R_VTCR_ORGN0_MASK | R_VTCR_SH0_MASK | \
R_VTCR_PS_MASK | R_VTCR_VS_MASK | R_VTCR_HA_MASK | R_VTCR_HD_MASK | \
R_VTCR_DS_MASK)
/* Return the value of the TCR controlling this translation regime */ /* Return the value of the TCR controlling this translation regime */
static inline uint64_t regime_tcr(CPUARMState *env, ARMMMUIdx mmu_idx) static inline uint64_t regime_tcr(CPUARMState *env, ARMMMUIdx mmu_idx)
{ {
@ -785,10 +795,16 @@ static inline uint64_t regime_tcr(CPUARMState *env, ARMMMUIdx mmu_idx)
} }
if (mmu_idx == ARMMMUIdx_Stage2_S) { if (mmu_idx == ARMMMUIdx_Stage2_S) {
/* /*
* Note: Secure stage 2 nominally shares fields from VTCR_EL2, but * Secure stage 2 shares fields from VTCR_EL2. We merge those
* those are not currently used by QEMU, so just return VSTCR_EL2. * in with the VSTCR_EL2 value to synthesize a single VTCR_EL2 format
* value so the callers don't need to special case this.
*
* If a future architecture change defines bits in VSTCR_EL2 that
* overlap with these VTCR_EL2 fields we may need to revisit this.
*/ */
return env->cp15.vstcr_el2; uint64_t v = env->cp15.vstcr_el2 & ~VTCR_SHARED_FIELD_MASK;
v |= env->cp15.vtcr_el2 & VTCR_SHARED_FIELD_MASK;
return v;
} }
return env->cp15.tcr_el[regime_el(env, mmu_idx)]; return env->cp15.tcr_el[regime_el(env, mmu_idx)];
} }