diff options
author | Zhuojia Shen <chaosdefinition@hotmail.com> | 2023-06-06 10:19:40 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2023-06-06 10:19:40 +0100 |
commit | f9ac778898cb28307e0f91421aba34d43c34b679 (patch) | |
tree | bb19b404245559a155a6269198417c6dd633250b | |
parent | c81e4ab370e858550852b052f689a0a721b879d4 (diff) | |
download | qemu-f9ac778898cb28307e0f91421aba34d43c34b679.zip qemu-f9ac778898cb28307e0f91421aba34d43c34b679.tar.gz qemu-f9ac778898cb28307e0f91421aba34d43c34b679.tar.bz2 |
target/arm: trap DCC access in user mode emulation
Accessing EL0-accessible Debug Communication Channel (DCC) registers in
user mode emulation is currently enabled. However, it does not match
Linux behavior as Linux sets MDSCR_EL1.TDCC on startup to disable EL0
access to DCC (see __cpu_setup() in arch/arm64/mm/proc.S).
This patch fixes access_tdcc() to check MDSCR_EL1.TDCC for EL0 and sets
MDSCR_EL1.TDCC for user mode emulation to match Linux.
Signed-off-by: Zhuojia Shen <chaosdefinition@hotmail.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: DS7PR12MB630905198DD8E69F6817544CAC4EA@DS7PR12MB6309.namprd12.prod.outlook.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r-- | target/arm/cpu.c | 2 | ||||
-rw-r--r-- | target/arm/debug_helper.c | 5 |
2 files changed, 7 insertions, 0 deletions
diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 5182ed0..4d5bb57 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -289,6 +289,8 @@ static void arm_cpu_reset_hold(Object *obj) * This is not yet exposed from the Linux kernel in any way. */ env->cp15.sctlr_el[1] |= SCTLR_TSCXT; + /* Disable access to Debug Communication Channel (DCC). */ + env->cp15.mdscr_el1 |= 1 << 12; #else /* Reset into the highest available EL */ if (arm_feature(env, ARM_FEATURE_EL3)) { diff --git a/target/arm/debug_helper.c b/target/arm/debug_helper.c index d41cc64..8362462 100644 --- a/target/arm/debug_helper.c +++ b/target/arm/debug_helper.c @@ -842,12 +842,14 @@ static CPAccessResult access_tda(CPUARMState *env, const ARMCPRegInfo *ri, * is implemented then these are controlled by MDCR_EL2.TDCC for * EL2 and MDCR_EL3.TDCC for EL3. They are also controlled by * the general debug access trap bits MDCR_EL2.TDA and MDCR_EL3.TDA. + * For EL0, they are also controlled by MDSCR_EL1.TDCC. */ static CPAccessResult access_tdcc(CPUARMState *env, const ARMCPRegInfo *ri, bool isread) { int el = arm_current_el(env); uint64_t mdcr_el2 = arm_mdcr_el2_eff(env); + bool mdscr_el1_tdcc = extract32(env->cp15.mdscr_el1, 12, 1); bool mdcr_el2_tda = (mdcr_el2 & MDCR_TDA) || (mdcr_el2 & MDCR_TDE) || (arm_hcr_el2_eff(env) & HCR_TGE); bool mdcr_el2_tdcc = cpu_isar_feature(aa64_fgt, env_archcpu(env)) && @@ -855,6 +857,9 @@ static CPAccessResult access_tdcc(CPUARMState *env, const ARMCPRegInfo *ri, bool mdcr_el3_tdcc = cpu_isar_feature(aa64_fgt, env_archcpu(env)) && (env->cp15.mdcr_el3 & MDCR_TDCC); + if (el < 1 && mdscr_el1_tdcc) { + return CP_ACCESS_TRAP; + } if (el < 2 && (mdcr_el2_tda || mdcr_el2_tdcc)) { return CP_ACCESS_TRAP_EL2; } |