All of lore.kernel.org
 help / color / mirror / Atom feed
From: Rebecca Cran <rebecca@nuviainc.com>
To: qemu-devel@nongnu.org
Cc: Peter Maydell <peter.maydell@linaro.org>,
	Rebecca Cran <rebecca@nuviainc.com>
Subject: [PATCH 1/2] target/arm: add support for FEAT_DIT, Data Independent Timing
Date: Thu, 10 Dec 2020 22:13:58 -0700	[thread overview]
Message-ID: <20201211051359.3231-2-rebecca@nuviainc.com> (raw)
In-Reply-To: <20201211051359.3231-1-rebecca@nuviainc.com>

Add support for FEAT_DIT. DIT (Data Independent Timing) is a required
feature for ARMv8.4. Since virtual machine execution is largely
nondeterministic, it's implemented as a NOP.

Signed-off-by: Rebecca Cran <rebecca@nuviainc.com>
---
 target/arm/cpu.h           | 20 +++++++++++++-
 target/arm/helper.c        | 28 +++++++++++++++++++-
 target/arm/internals.h     |  6 +++++
 target/arm/translate-a64.c | 14 ++++++++++
 4 files changed, 66 insertions(+), 2 deletions(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 4c9cbfbd9975..862be662cef7 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -269,6 +269,7 @@ typedef struct CPUARMState {
     uint32_t NF; /* N is bit 31. All other bits are undefined.  */
     uint32_t ZF; /* Z set if zero.  */
     uint32_t QF; /* 0 or 1 */
+    uint32_t DIT; /* 0 or 1 */
     uint32_t GE; /* cpsr[19:16] */
     uint32_t thumb; /* cpsr[5]. 0 = arm mode, 1 = thumb mode. */
     uint32_t condexec_bits; /* IT bits.  cpsr[15:10,26:25].  */
@@ -1233,6 +1234,7 @@ void pmu_init(ARMCPU *cpu);
 #define CPSR_IT_2_7 (0xfc00U)
 #define CPSR_GE (0xfU << 16)
 #define CPSR_IL (1U << 20)
+#define CPSR_DIT (1U << 21)
 #define CPSR_PAN (1U << 22)
 #define CPSR_J (1U << 24)
 #define CPSR_IT_0_1 (3U << 25)
@@ -1266,6 +1268,7 @@ void pmu_init(ARMCPU *cpu);
 #define XPSR_Z CPSR_Z
 #define XPSR_N CPSR_N
 #define XPSR_NZCV CPSR_NZCV
+#define XPSR_DIT CPSR_DIT
 #define XPSR_IT CPSR_IT
 
 #define TTBCR_N      (7U << 0) /* TTBCR.EAE==0 */
@@ -1300,6 +1303,7 @@ void pmu_init(ARMCPU *cpu);
 #define PSTATE_SS (1U << 21)
 #define PSTATE_PAN (1U << 22)
 #define PSTATE_UAO (1U << 23)
+#define PSTATE_DIT (1U << 24)
 #define PSTATE_TCO (1U << 25)
 #define PSTATE_V (1U << 28)
 #define PSTATE_C (1U << 29)
@@ -1374,7 +1378,8 @@ static inline uint32_t xpsr_read(CPUARMState *env)
     ZF = (env->ZF == 0);
     return (env->NF & 0x80000000) | (ZF << 30)
         | (env->CF << 29) | ((env->VF & 0x80000000) >> 3) | (env->QF << 27)
-        | (env->thumb << 24) | ((env->condexec_bits & 3) << 25)
+        | (env->thumb << 24) | (env->DIT << 21)
+        | ((env->condexec_bits & 3) << 25)
         | ((env->condexec_bits & 0xfc) << 8)
         | (env->GE << 16)
         | env->v7m.exception;
@@ -1389,6 +1394,9 @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
         env->CF = (val >> 29) & 1;
         env->VF = (val << 3) & 0x80000000;
     }
+    if (mask & XPSR_DIT) {
+        env->DIT = ((val & XPSR_DIT) != 0);
+    }
     if (mask & XPSR_Q) {
         env->QF = ((val & XPSR_Q) != 0);
     }
@@ -3823,6 +3831,11 @@ static inline bool isar_feature_aa32_tts2uxn(const ARMISARegisters *id)
     return FIELD_EX32(id->id_mmfr4, ID_MMFR4, XNX) != 0;
 }
 
+static inline bool isar_feature_aa32_dit(const ARMISARegisters *id)
+{
+    return FIELD_EX32(id->id_pfr0, ID_PFR0, DIT) != 0;
+}
+
 /*
  * 64-bit feature tests via id registers.
  */
@@ -4050,6 +4063,11 @@ static inline bool isar_feature_aa64_tts2uxn(const ARMISARegisters *id)
     return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, XNX) != 0;
 }
 
+static inline bool isar_feature_aa64_dit(const ARMISARegisters *id)
+{
+    return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, DIT) != 0;
+}
+
 /*
  * Feature tests for "does this exist in either 32-bit or 64-bit?"
  */
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 7b8bcd69030f..eb4979baceff 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -4390,6 +4390,24 @@ static const ARMCPRegInfo uao_reginfo = {
     .readfn = aa64_uao_read, .writefn = aa64_uao_write
 };
 
+static uint64_t aa64_dit_read(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+    return env->pstate & PSTATE_DIT;
+}
+
+static void aa64_dit_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                           uint64_t value)
+{
+    env->pstate = (env->pstate & ~PSTATE_DIT) | (value & PSTATE_DIT);
+}
+
+static const ARMCPRegInfo dit_reginfo = {
+    .name = "DIT", .state = ARM_CP_STATE_AA64,
+    .opc0 = 3, .opc1 = 3, .crn = 4, .crm = 2, .opc2 = 5,
+    .type = ARM_CP_NO_RAW, .access = PL0_RW,
+    .readfn = aa64_dit_read, .writefn = aa64_dit_write
+};
+
 static CPAccessResult aa64_cacheop_poc_access(CPUARMState *env,
                                               const ARMCPRegInfo *ri,
                                               bool isread)
@@ -8133,6 +8151,10 @@ void register_cp_regs_for_features(ARMCPU *cpu)
         define_one_arm_cp_reg(cpu, &uao_reginfo);
     }
 
+    if (cpu_isar_feature(aa64_dit, cpu)) {
+        define_one_arm_cp_reg(cpu, &dit_reginfo);
+    }
+
     if (arm_feature(env, ARM_FEATURE_EL2) && cpu_isar_feature(aa64_vh, cpu)) {
         define_arm_cp_regs(cpu, vhe_reginfo);
     }
@@ -8740,7 +8762,8 @@ uint32_t cpsr_read(CPUARMState *env)
     ZF = (env->ZF == 0);
     return env->uncached_cpsr | (env->NF & 0x80000000) | (ZF << 30) |
         (env->CF << 29) | ((env->VF & 0x80000000) >> 3) | (env->QF << 27)
-        | (env->thumb << 5) | ((env->condexec_bits & 3) << 25)
+        | (env->DIT << 21) | (env->thumb << 5)
+        | ((env->condexec_bits & 3) << 25)
         | ((env->condexec_bits & 0xfc) << 8)
         | (env->GE << 16) | (env->daif & CPSR_AIF);
 }
@@ -8756,6 +8779,9 @@ void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask,
         env->CF = (val >> 29) & 1;
         env->VF = (val << 3) & 0x80000000;
     }
+    if (mask & CPSR_DIT) {
+        env->DIT = ((val & CPSR_DIT) != 0);
+    }
     if (mask & CPSR_Q)
         env->QF = ((val & CPSR_Q) != 0);
     if (mask & CPSR_T)
diff --git a/target/arm/internals.h b/target/arm/internals.h
index 5460678756d3..00ecfc174c80 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -1186,6 +1186,9 @@ static inline uint32_t aarch32_cpsr_valid_mask(uint64_t features,
     if (isar_feature_aa32_pan(id)) {
         valid |= CPSR_PAN;
     }
+    if (isar_feature_aa32_dit(id)) {
+        valid |= CPSR_DIT;
+    }
 
     return valid;
 }
@@ -1204,6 +1207,9 @@ static inline uint32_t aarch64_pstate_valid_mask(const ARMISARegisters *id)
     if (isar_feature_aa64_uao(id)) {
         valid |= PSTATE_UAO;
     }
+    if (isar_feature_aa64_dit(id)) {
+        valid |= PSTATE_DIT;
+    }
     if (isar_feature_aa64_mte(id)) {
         valid |= PSTATE_TCO;
     }
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 2e3fdfdf6ba8..0cafba6188c6 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -1696,6 +1696,20 @@ static void handle_msr_i(DisasContext *s, uint32_t insn,
         tcg_temp_free_i32(t1);
         break;
 
+    case 0x1a: /* DIT */
+        if (!dc_isar_feature(aa64_dit, s)) {
+            goto do_unallocated;
+        }
+        if (crm & 1) {
+            set_pstate_bits(PSTATE_DIT);
+        } else {
+            clear_pstate_bits(PSTATE_DIT);
+        }
+        t1 = tcg_const_i32(s->current_el);
+        gen_helper_rebuild_hflags_a64(cpu_env, t1);
+        tcg_temp_free_i32(t1);
+        break;
+
     case 0x1e: /* DAIFSet */
         t1 = tcg_const_i32(crm);
         gen_helper_msr_i_daifset(cpu_env, t1);
-- 
2.26.2



  reply	other threads:[~2020-12-11  5:17 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-12-11  5:13 [PATCH 0/2] target/arm: Add support for DIT (Data Independent Timing) Rebecca Cran
2020-12-11  5:13 ` Rebecca Cran [this message]
2020-12-11 14:08   ` [PATCH 1/2] target/arm: add support for FEAT_DIT, Data Independent Timing Richard Henderson
2020-12-11 19:33     ` Rebecca Cran
2020-12-11 19:51       ` Richard Henderson
2020-12-11 21:37         ` Peter Maydell
2020-12-14 18:11           ` Rebecca Cran
2020-12-14 18:48             ` Peter Maydell
2020-12-11  5:13 ` [PATCH 2/2] target/arm: Set ID_AA64PFR0.DIT and ID_PFR0.DIT to 1 for "max" AA64 CPU Rebecca Cran
2020-12-11 14:09   ` Richard Henderson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201211051359.3231-2-rebecca@nuviainc.com \
    --to=rebecca@nuviainc.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.