Not only are the sve-related tb_flags fields unused when SVE is
disabled, but not all of the cpu registers are initialized properly
for computing same. This can corrupt other fields by oring in -1.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/arm/helper.c | 45 ++++++++++++++++++++++++---------------------
1 file changed, 24 insertions(+), 21 deletions(-)
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 088f452716..64b1564594 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -12587,36 +12587,39 @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
uint32_t flags;
if (is_a64(env)) {
- int sve_el = sve_exception_el(env);
- uint32_t zcr_len;
-
*pc = env->pc;
flags = ARM_TBFLAG_AARCH64_STATE_MASK;
/* Get control bits for tagged addresses */
flags |= (arm_regime_tbi0(env, mmu_idx) << ARM_TBFLAG_TBI0_SHIFT);
flags |= (arm_regime_tbi1(env, mmu_idx) << ARM_TBFLAG_TBI1_SHIFT);
- flags |= sve_el << ARM_TBFLAG_SVEEXC_EL_SHIFT;
- /* If SVE is disabled, but FP is enabled,
- then the effective len is 0. */
- if (sve_el != 0 && fp_el == 0) {
- zcr_len = 0;
- } else {
- int current_el = arm_current_el(env);
- ARMCPU *cpu = arm_env_get_cpu(env);
+ if (arm_feature(env, ARM_FEATURE_SVE)) {
+ int sve_el = sve_exception_el(env);
+ uint32_t zcr_len;
- zcr_len = cpu->sve_max_vq - 1;
- if (current_el <= 1) {
- zcr_len = MIN(zcr_len, 0xf & (uint32_t)env->vfp.zcr_el[1]);
- }
- if (current_el < 2 && arm_feature(env, ARM_FEATURE_EL2)) {
- zcr_len = MIN(zcr_len, 0xf & (uint32_t)env->vfp.zcr_el[2]);
- }
- if (current_el < 3 && arm_feature(env, ARM_FEATURE_EL3)) {
- zcr_len = MIN(zcr_len, 0xf & (uint32_t)env->vfp.zcr_el[3]);
+ /* If SVE is disabled, but FP is enabled,
+ * then the effective len is 0.
+ */
+ if (sve_el != 0 && fp_el == 0) {
+ zcr_len = 0;
+ } else {
+ int current_el = arm_current_el(env);
+ ARMCPU *cpu = arm_env_get_cpu(env);
+
+ zcr_len = cpu->sve_max_vq - 1;
+ if (current_el <= 1) {
+ zcr_len = MIN(zcr_len, 0xf & (uint32_t)env->vfp.zcr_el[1]);
+ }
+ if (current_el < 2 && arm_feature(env, ARM_FEATURE_EL2)) {
+ zcr_len = MIN(zcr_len, 0xf & (uint32_t)env->vfp.zcr_el[2]);
+ }
+ if (current_el < 3 && arm_feature(env, ARM_FEATURE_EL3)) {
+ zcr_len = MIN(zcr_len, 0xf & (uint32_t)env->vfp.zcr_el[3]);
+ }
}
+ flags |= sve_el << ARM_TBFLAG_SVEEXC_EL_SHIFT;
+ flags |= zcr_len << ARM_TBFLAG_ZCR_LEN_SHIFT;
}
- flags |= zcr_len << ARM_TBFLAG_ZCR_LEN_SHIFT;
} else {
*pc = env->regs[15];
flags = (env->thumb << ARM_TBFLAG_THUMB_SHIFT)
--
2.17.1
On 24 August 2018 at 15:14, Richard Henderson <richard.henderson@linaro.org> wrote: > Not only are the sve-related tb_flags fields unused when SVE is > disabled, but not all of the cpu registers are initialized properly > for computing same. This can corrupt other fields by oring in -1. > > Signed-off-by: Richard Henderson <richard.henderson@linaro.org> > --- Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Your version is better than mine as it conditionalises the sve_el flags field too. thanks -- PMM
On 24 August 2018 at 15:45, Peter Maydell <peter.maydell@linaro.org> wrote: > On 24 August 2018 at 15:14, Richard Henderson > <richard.henderson@linaro.org> wrote: >> Not only are the sve-related tb_flags fields unused when SVE is >> disabled, but not all of the cpu registers are initialized properly >> for computing same. This can corrupt other fields by oring in -1. >> >> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> >> --- > > Reviewed-by: Peter Maydell <peter.maydell@linaro.org> ...and now applied to target-arm.next. (I fixed up the subject line to use the right function name: _state, not _flags.) thanks -- PMM
© 2016 - 2025 Red Hat, Inc.