提交 e79b445d 编写于 作者: R Richard Henderson 提交者: Peter Maydell

target/arm: Fix cpu_get_tb_cpu_state() for non-SVE CPUs

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,
which might result in QEMU crashing.

This bug was not present in 3.0, but this patch is cc'd to
stable because adf92eab where the bug was
introduced was marked for stable.

Fixes: adf92eab
Cc: qemu-stable@nongnu.org (3.0.1)
Signed-off-by: NRichard Henderson <richard.henderson@linaro.org>
Reviewed-by: NPeter Maydell <peter.maydell@linaro.org>
Signed-off-by: NPeter Maydell <peter.maydell@linaro.org>
上级 506e4a00
...@@ -12587,36 +12587,39 @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc, ...@@ -12587,36 +12587,39 @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
uint32_t flags; uint32_t flags;
if (is_a64(env)) { if (is_a64(env)) {
int sve_el = sve_exception_el(env);
uint32_t zcr_len;
*pc = env->pc; *pc = env->pc;
flags = ARM_TBFLAG_AARCH64_STATE_MASK; flags = ARM_TBFLAG_AARCH64_STATE_MASK;
/* Get control bits for tagged addresses */ /* Get control bits for tagged addresses */
flags |= (arm_regime_tbi0(env, mmu_idx) << ARM_TBFLAG_TBI0_SHIFT); flags |= (arm_regime_tbi0(env, mmu_idx) << ARM_TBFLAG_TBI0_SHIFT);
flags |= (arm_regime_tbi1(env, mmu_idx) << ARM_TBFLAG_TBI1_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, if (arm_feature(env, ARM_FEATURE_SVE)) {
then the effective len is 0. */ int sve_el = sve_exception_el(env);
if (sve_el != 0 && fp_el == 0) { uint32_t zcr_len;
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 SVE is disabled, but FP is enabled,
if (current_el <= 1) { * then the effective len is 0.
zcr_len = MIN(zcr_len, 0xf & (uint32_t)env->vfp.zcr_el[1]); */
} if (sve_el != 0 && fp_el == 0) {
if (current_el < 2 && arm_feature(env, ARM_FEATURE_EL2)) { zcr_len = 0;
zcr_len = MIN(zcr_len, 0xf & (uint32_t)env->vfp.zcr_el[2]); } else {
} int current_el = arm_current_el(env);
if (current_el < 3 && arm_feature(env, ARM_FEATURE_EL3)) { ARMCPU *cpu = arm_env_get_cpu(env);
zcr_len = MIN(zcr_len, 0xf & (uint32_t)env->vfp.zcr_el[3]);
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 { } else {
*pc = env->regs[15]; *pc = env->regs[15];
flags = (env->thumb << ARM_TBFLAG_THUMB_SHIFT) flags = (env->thumb << ARM_TBFLAG_THUMB_SHIFT)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册