diff mbox series

target/arm: trap DCC access in user mode emulation

Message ID DS7PR12MB630905198DD8E69F6817544CAC4EA@DS7PR12MB6309.namprd12.prod.outlook.com (mailing list archive)
State New, archived
Headers show
Series target/arm: trap DCC access in user mode emulation | expand

Commit Message

Zhuojia Shen June 2, 2023, 9:43 p.m. UTC
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>
---
 target/arm/cpu.c          | 2 ++
 target/arm/debug_helper.c | 5 +++++
 2 files changed, 7 insertions(+)

Comments

Richard Henderson June 3, 2023, 4:52 a.m. UTC | #1
On 6/2/23 14:43, Zhuojia Shen wrote:
> 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>

It would be nice to define the fields of MDSCR properly but either way,

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

r~
Peter Maydell June 5, 2023, 4:02 p.m. UTC | #2
On Sat, 3 Jun 2023 at 05:52, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> On 6/2/23 14:43, Zhuojia Shen wrote:
> > 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>
>
> It would be nice to define the fields of MDSCR properly but either way,
>
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>



Applied to target-arm.next, thanks.

-- PMM
diff mbox series

Patch

diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 5182ed0c91..4d5bb57f07 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 d41cc643b1..8362462a07 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;
     }