qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/4] target/arm: Implement ARMv8.2-UAO
@ 2019-12-03 23:42 Richard Henderson
  2019-12-03 23:42 ` [PATCH 1/4] target/arm: Add ID_AA64MMFR2_EL1 Richard Henderson
                   ` (3 more replies)
  0 siblings, 4 replies; 14+ messages in thread
From: Richard Henderson @ 2019-12-03 23:42 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell

Based-on: <20191203225333.17055-1-richard.henderson@linaro.org>
("target/arm: Implement ARMv8.1-PAN + ARMv8.2-ATS1E1")

This was relatively easy to do, and related to the VHE
and PAN patch sets.  It's also already supported by the
Linux kernel and thus easily tested.


r~


Richard Henderson (4):
  target/arm: Add ID_AA64MMFR2_EL1
  target/arm: Update MSR access to UAO
  target/arm: Implement UAO semantics
  target/arm: Enable ARMv8.2-UAO in -cpu max

 target/arm/cpu.h           | 23 +++++++++++++
 target/arm/cpu64.c         |  4 +++
 target/arm/helper.c        | 66 +++++++++++++++++++++++++-------------
 target/arm/kvm64.c         |  2 ++
 target/arm/translate-a64.c | 14 ++++++++
 5 files changed, 87 insertions(+), 22 deletions(-)

-- 
2.17.1



^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 1/4] target/arm: Add ID_AA64MMFR2_EL1
  2019-12-03 23:42 [PATCH 0/4] target/arm: Implement ARMv8.2-UAO Richard Henderson
@ 2019-12-03 23:42 ` Richard Henderson
  2019-12-06 18:19   ` Peter Maydell
  2019-12-03 23:42 ` [PATCH 2/4] target/arm: Update MSR access to UAO Richard Henderson
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 14+ messages in thread
From: Richard Henderson @ 2019-12-03 23:42 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell

Add definitions for all of the fields, up to ARMv8.5.
Convert the existing RESERVED register to a full register.
Query KVM for the value of the register for the host.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/cpu.h    | 17 +++++++++++++++++
 target/arm/helper.c |  4 ++--
 target/arm/kvm64.c  |  2 ++
 3 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index d403dc5947..cdf6caf869 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -864,6 +864,7 @@ struct ARMCPU {
         uint64_t id_aa64pfr1;
         uint64_t id_aa64mmfr0;
         uint64_t id_aa64mmfr1;
+        uint64_t id_aa64mmfr2;
     } isar;
     uint32_t midr;
     uint32_t revidr;
@@ -1778,6 +1779,22 @@ FIELD(ID_AA64MMFR1, PAN, 20, 4)
 FIELD(ID_AA64MMFR1, SPECSEI, 24, 4)
 FIELD(ID_AA64MMFR1, XNX, 28, 4)
 
+FIELD(ID_AA64MMFR2, CNP, 0, 4)
+FIELD(ID_AA64MMFR2, UAO, 4, 4)
+FIELD(ID_AA64MMFR2, LSM, 8, 4)
+FIELD(ID_AA64MMFR2, IESB, 12, 4)
+FIELD(ID_AA64MMFR2, VARANGE, 16, 4)
+FIELD(ID_AA64MMFR2, CCIDX, 20, 4)
+FIELD(ID_AA64MMFR2, NV, 24, 4)
+FIELD(ID_AA64MMFR2, ST, 28, 4)
+FIELD(ID_AA64MMFR2, AT, 32, 4)
+FIELD(ID_AA64MMFR2, IDS, 36, 4)
+FIELD(ID_AA64MMFR2, FWB, 40, 4)
+FIELD(ID_AA64MMFR2, TTL, 48, 4)
+FIELD(ID_AA64MMFR2, BBM, 52, 4)
+FIELD(ID_AA64MMFR2, EVT, 56, 4)
+FIELD(ID_AA64MMFR2, E0PD, 60, 4)
+
 FIELD(ID_DFR0, COPDBG, 0, 4)
 FIELD(ID_DFR0, COPSDBG, 4, 4)
 FIELD(ID_DFR0, MMAPDBG, 8, 4)
diff --git a/target/arm/helper.c b/target/arm/helper.c
index f1eab4fb28..70f2db5447 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -6825,11 +6825,11 @@ void register_cp_regs_for_features(ARMCPU *cpu)
               .access = PL1_R, .type = ARM_CP_CONST,
               .accessfn = access_aa64_tid3,
               .resetvalue = cpu->isar.id_aa64mmfr1 },
-            { .name = "ID_AA64MMFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
+            { .name = "ID_AA64MMFR2_EL1", .state = ARM_CP_STATE_AA64,
               .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 2,
               .access = PL1_R, .type = ARM_CP_CONST,
               .accessfn = access_aa64_tid3,
-              .resetvalue = 0 },
+              .resetvalue = cpu->isar.id_aa64mmfr2 },
             { .name = "ID_AA64MMFR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
               .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 3,
               .access = PL1_R, .type = ARM_CP_CONST,
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
index 876184b8fe..482e7fdfbb 100644
--- a/target/arm/kvm64.c
+++ b/target/arm/kvm64.c
@@ -549,6 +549,8 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
                               ARM64_SYS_REG(3, 0, 0, 7, 0));
         err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64mmfr1,
                               ARM64_SYS_REG(3, 0, 0, 7, 1));
+        err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64mmfr2,
+                              ARM64_SYS_REG(3, 0, 0, 7, 2));
 
         /*
          * Note that if AArch32 support is not present in the host,
-- 
2.17.1



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 2/4] target/arm: Update MSR access to UAO
  2019-12-03 23:42 [PATCH 0/4] target/arm: Implement ARMv8.2-UAO Richard Henderson
  2019-12-03 23:42 ` [PATCH 1/4] target/arm: Add ID_AA64MMFR2_EL1 Richard Henderson
@ 2019-12-03 23:42 ` Richard Henderson
  2019-12-06 18:30   ` Peter Maydell
  2019-12-03 23:42 ` [PATCH 3/4] target/arm: Implement UAO semantics Richard Henderson
  2019-12-03 23:42 ` [PATCH 4/4] target/arm: Enable ARMv8.2-UAO in -cpu max Richard Henderson
  3 siblings, 1 reply; 14+ messages in thread
From: Richard Henderson @ 2019-12-03 23:42 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/cpu.h           |  6 ++++++
 target/arm/helper.c        | 21 +++++++++++++++++++++
 target/arm/translate-a64.c | 14 ++++++++++++++
 3 files changed, 41 insertions(+)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index cdf6caf869..dd284ba5c7 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1228,6 +1228,7 @@ void pmu_init(ARMCPU *cpu);
 #define PSTATE_IL (1U << 20)
 #define PSTATE_SS (1U << 21)
 #define PSTATE_PAN (1U << 22)
+#define PSTATE_UAO (1U << 23)
 #define PSTATE_V (1U << 28)
 #define PSTATE_C (1U << 29)
 #define PSTATE_Z (1U << 30)
@@ -3598,6 +3599,11 @@ static inline bool isar_feature_aa64_ats1e1(const ARMISARegisters *id)
     return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, PAN) >= 2;
 }
 
+static inline bool isar_feature_aa64_uao(const ARMISARegisters *id)
+{
+    return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, UAO) != 0;
+}
+
 static inline bool isar_feature_aa64_bti(const ARMISARegisters *id)
 {
     return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, BT) != 0;
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 70f2db5447..8941a6c10f 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -4131,6 +4131,17 @@ static void aa64_pan_write(CPUARMState *env, const ARMCPRegInfo *ri,
     env->pstate = (env->pstate & ~PSTATE_PAN) | (value & PSTATE_PAN);
 }
 
+static uint64_t aa64_uao_read(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+    return env->pstate & PSTATE_UAO;
+}
+
+static void aa64_uao_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                           uint64_t value)
+{
+    env->pstate = (env->pstate & ~PSTATE_UAO) | (value & PSTATE_UAO);
+}
+
 static CPAccessResult aa64_cacheop_access(CPUARMState *env,
                                           const ARMCPRegInfo *ri,
                                           bool isread)
@@ -7464,6 +7475,16 @@ void register_cp_regs_for_features(ARMCPU *cpu)
         define_arm_cp_regs(cpu, ats1cp_reginfo);
     }
 #endif
+    if (cpu_isar_feature(aa64_uao, cpu)) {
+        static const ARMCPRegInfo uao_reginfo[] = {
+            { .name = "UAO", .state = ARM_CP_STATE_AA64,
+              .opc0 = 3, .opc1 = 0, .crn = 4, .crm = 2, .opc2 = 4,
+              .type = ARM_CP_NO_RAW, .access = PL1_RW,
+              .readfn = aa64_uao_read, .writefn = aa64_uao_write, },
+            REGINFO_SENTINEL
+        };
+        define_arm_cp_regs(cpu, uao_reginfo);
+    }
 
     if (arm_feature(env, ARM_FEATURE_EL2) && cpu_isar_feature(aa64_vh, cpu)) {
         static const ARMCPRegInfo vhe_reginfo[] = {
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 7f5a68106b..2b6846ef01 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -1601,6 +1601,20 @@ static void handle_msr_i(DisasContext *s, uint32_t insn,
         s->base.is_jmp = DISAS_NEXT;
         break;
 
+    case 0x03: /* UAO */
+        if (!dc_isar_feature(aa64_uao, s) || s->current_el == 0) {
+            goto do_unallocated;
+        }
+        if (crm & 1) {
+            set_pstate_bits(PSTATE_UAO);
+        } else {
+            clear_pstate_bits(PSTATE_UAO);
+        }
+        t1 = tcg_const_i32(s->current_el);
+        gen_helper_rebuild_hflags_a64(cpu_env, t1);
+        tcg_temp_free_i32(t1);
+        break;
+
     case 0x04: /* PAN */
         if (!dc_isar_feature(aa64_pan, s) || s->current_el == 0) {
             goto do_unallocated;
-- 
2.17.1



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 3/4] target/arm: Implement UAO semantics
  2019-12-03 23:42 [PATCH 0/4] target/arm: Implement ARMv8.2-UAO Richard Henderson
  2019-12-03 23:42 ` [PATCH 1/4] target/arm: Add ID_AA64MMFR2_EL1 Richard Henderson
  2019-12-03 23:42 ` [PATCH 2/4] target/arm: Update MSR access to UAO Richard Henderson
@ 2019-12-03 23:42 ` Richard Henderson
  2019-12-06 18:31   ` Peter Maydell
  2019-12-03 23:42 ` [PATCH 4/4] target/arm: Enable ARMv8.2-UAO in -cpu max Richard Henderson
  3 siblings, 1 reply; 14+ messages in thread
From: Richard Henderson @ 2019-12-03 23:42 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell

We need only override the current condition under which
TBFLAG_A64.UNPRIV is set.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/helper.c | 41 +++++++++++++++++++++--------------------
 1 file changed, 21 insertions(+), 20 deletions(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index 8941a6c10f..6d7a8349b5 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -12050,28 +12050,29 @@ static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
     }
 
     /* Compute the condition for using AccType_UNPRIV for LDTR et al. */
-    /* TODO: ARMv8.2-UAO */
-    switch (mmu_idx) {
-    case ARMMMUIdx_EL10_1:
-    case ARMMMUIdx_EL10_1_PAN:
-    case ARMMMUIdx_SE1:
-    case ARMMMUIdx_SE1_PAN:
-        /* TODO: ARMv8.3-NV */
-        flags = FIELD_DP32(flags, TBFLAG_A64, UNPRIV, 1);
-        break;
-    case ARMMMUIdx_EL20_2:
-    case ARMMMUIdx_EL20_2_PAN:
-        /* TODO: ARMv8.4-SecEL2 */
-        /*
-         * Note that EL20_2 is gated by HCR_EL2.E2H == 1, but EL20_0 is
-         * gated by HCR_EL2.<E2H,TGE> == '11', and so is LDTR.
-         */
-        if (env->cp15.hcr_el2 & HCR_TGE) {
+    if (!(env->pstate & PSTATE_UAO)) {
+        switch (mmu_idx) {
+        case ARMMMUIdx_EL10_1:
+        case ARMMMUIdx_EL10_1_PAN:
+        case ARMMMUIdx_SE1:
+        case ARMMMUIdx_SE1_PAN:
+            /* TODO: ARMv8.3-NV */
             flags = FIELD_DP32(flags, TBFLAG_A64, UNPRIV, 1);
+            break;
+        case ARMMMUIdx_EL20_2:
+        case ARMMMUIdx_EL20_2_PAN:
+            /* TODO: ARMv8.4-SecEL2 */
+            /*
+             * Note that EL20_2 is gated by HCR_EL2.E2H == 1, but EL20_0 is
+             * gated by HCR_EL2.<E2H,TGE> == '11', and so is LDTR.
+             */
+            if (env->cp15.hcr_el2 & HCR_TGE) {
+                flags = FIELD_DP32(flags, TBFLAG_A64, UNPRIV, 1);
+            }
+            break;
+        default:
+            break;
         }
-        break;
-    default:
-        break;
     }
 
     return rebuild_hflags_common(env, fp_el, mmu_idx, flags);
-- 
2.17.1



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 4/4] target/arm: Enable ARMv8.2-UAO in -cpu max
  2019-12-03 23:42 [PATCH 0/4] target/arm: Implement ARMv8.2-UAO Richard Henderson
                   ` (2 preceding siblings ...)
  2019-12-03 23:42 ` [PATCH 3/4] target/arm: Implement UAO semantics Richard Henderson
@ 2019-12-03 23:42 ` Richard Henderson
  2019-12-06 18:31   ` Peter Maydell
  3 siblings, 1 reply; 14+ messages in thread
From: Richard Henderson @ 2019-12-03 23:42 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/cpu64.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 9399253b4c..03377084e3 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -674,6 +674,10 @@ static void aarch64_max_initfn(Object *obj)
         t = FIELD_DP64(t, ID_AA64MMFR1, PAN, 2); /* ATS1E1 */
         cpu->isar.id_aa64mmfr1 = t;
 
+        t = cpu->isar.id_aa64mmfr2;
+        t = FIELD_DP64(t, ID_AA64MMFR2, UAO, 1);
+        cpu->isar.id_aa64mmfr2 = t;
+
         /* Replicate the same data to the 32-bit id registers.  */
         u = cpu->isar.id_isar5;
         u = FIELD_DP32(u, ID_ISAR5, AES, 2); /* AES + PMULL */
-- 
2.17.1



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH 1/4] target/arm: Add ID_AA64MMFR2_EL1
  2019-12-03 23:42 ` [PATCH 1/4] target/arm: Add ID_AA64MMFR2_EL1 Richard Henderson
@ 2019-12-06 18:19   ` Peter Maydell
  2020-02-02  0:54     ` Richard Henderson
  0 siblings, 1 reply; 14+ messages in thread
From: Peter Maydell @ 2019-12-06 18:19 UTC (permalink / raw)
  To: Richard Henderson; +Cc: QEMU Developers

On Tue, 3 Dec 2019 at 23:42, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Add definitions for all of the fields, up to ARMv8.5.
> Convert the existing RESERVED register to a full register.
> Query KVM for the value of the register for the host.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/arm/cpu.h    | 17 +++++++++++++++++
>  target/arm/helper.c |  4 ++--
>  target/arm/kvm64.c  |  2 ++
>  3 files changed, 21 insertions(+), 2 deletions(-)

> diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
> index 876184b8fe..482e7fdfbb 100644
> --- a/target/arm/kvm64.c
> +++ b/target/arm/kvm64.c
> @@ -549,6 +549,8 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
>                                ARM64_SYS_REG(3, 0, 0, 7, 0));
>          err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64mmfr1,
>                                ARM64_SYS_REG(3, 0, 0, 7, 1));
> +        err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64mmfr2,
> +                              ARM64_SYS_REG(3, 0, 0, 7, 2));

Do current KVM kernels definitely handle the request for this
new register (ie don't return an error)?

Otherwise
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

thanks
-- PMM


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 2/4] target/arm: Update MSR access to UAO
  2019-12-03 23:42 ` [PATCH 2/4] target/arm: Update MSR access to UAO Richard Henderson
@ 2019-12-06 18:30   ` Peter Maydell
  2019-12-06 19:00     ` Richard Henderson
  2020-02-02  1:00     ` Richard Henderson
  0 siblings, 2 replies; 14+ messages in thread
From: Peter Maydell @ 2019-12-06 18:30 UTC (permalink / raw)
  To: Richard Henderson; +Cc: QEMU Developers

On Tue, 3 Dec 2019 at 23:42, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/arm/cpu.h           |  6 ++++++
>  target/arm/helper.c        | 21 +++++++++++++++++++++
>  target/arm/translate-a64.c | 14 ++++++++++++++
>  3 files changed, 41 insertions(+)
>
> diff --git a/target/arm/cpu.h b/target/arm/cpu.h
> index cdf6caf869..dd284ba5c7 100644
> --- a/target/arm/cpu.h
> +++ b/target/arm/cpu.h
> @@ -1228,6 +1228,7 @@ void pmu_init(ARMCPU *cpu);
>  #define PSTATE_IL (1U << 20)
>  #define PSTATE_SS (1U << 21)
>  #define PSTATE_PAN (1U << 22)
> +#define PSTATE_UAO (1U << 23)
>  #define PSTATE_V (1U << 28)
>  #define PSTATE_C (1U << 29)
>  #define PSTATE_Z (1U << 30)
> @@ -3598,6 +3599,11 @@ static inline bool isar_feature_aa64_ats1e1(const ARMISARegisters *id)
>      return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, PAN) >= 2;
>  }
>
> +static inline bool isar_feature_aa64_uao(const ARMISARegisters *id)
> +{
> +    return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, UAO) != 0;
> +}
> +
>  static inline bool isar_feature_aa64_bti(const ARMISARegisters *id)
>  {
>      return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, BT) != 0;
> diff --git a/target/arm/helper.c b/target/arm/helper.c
> index 70f2db5447..8941a6c10f 100644
> --- a/target/arm/helper.c
> +++ b/target/arm/helper.c
> @@ -4131,6 +4131,17 @@ static void aa64_pan_write(CPUARMState *env, const ARMCPRegInfo *ri,
>      env->pstate = (env->pstate & ~PSTATE_PAN) | (value & PSTATE_PAN);
>  }
>
> +static uint64_t aa64_uao_read(CPUARMState *env, const ARMCPRegInfo *ri)
> +{
> +    return env->pstate & PSTATE_UAO;
> +}
> +
> +static void aa64_uao_write(CPUARMState *env, const ARMCPRegInfo *ri,
> +                           uint64_t value)
> +{
> +    env->pstate = (env->pstate & ~PSTATE_UAO) | (value & PSTATE_UAO);
> +}
> +
>  static CPAccessResult aa64_cacheop_access(CPUARMState *env,
>                                            const ARMCPRegInfo *ri,
>                                            bool isread)
> @@ -7464,6 +7475,16 @@ void register_cp_regs_for_features(ARMCPU *cpu)
>          define_arm_cp_regs(cpu, ats1cp_reginfo);
>      }
>  #endif
> +    if (cpu_isar_feature(aa64_uao, cpu)) {
> +        static const ARMCPRegInfo uao_reginfo[] = {
> +            { .name = "UAO", .state = ARM_CP_STATE_AA64,
> +              .opc0 = 3, .opc1 = 0, .crn = 4, .crm = 2, .opc2 = 4,
> +              .type = ARM_CP_NO_RAW, .access = PL1_RW,
> +              .readfn = aa64_uao_read, .writefn = aa64_uao_write, },
> +            REGINFO_SENTINEL
> +        };

This could just be a file-scope global, right?
Also, you can just use define_one_arm_cp_reg() rather
than having a list with one entry. (cf zcr_el1_reginfo).

> +        define_arm_cp_regs(cpu, uao_reginfo);
> +    }
>
>      if (arm_feature(env, ARM_FEATURE_EL2) && cpu_isar_feature(aa64_vh, cpu)) {
>          static const ARMCPRegInfo vhe_reginfo[] = {
> diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
> index 7f5a68106b..2b6846ef01 100644
> --- a/target/arm/translate-a64.c
> +++ b/target/arm/translate-a64.c
> @@ -1601,6 +1601,20 @@ static void handle_msr_i(DisasContext *s, uint32_t insn,
>          s->base.is_jmp = DISAS_NEXT;
>          break;
>
> +    case 0x03: /* UAO */
> +        if (!dc_isar_feature(aa64_uao, s) || s->current_el == 0) {
> +            goto do_unallocated;
> +        }
> +        if (crm & 1) {
> +            set_pstate_bits(PSTATE_UAO);
> +        } else {
> +            clear_pstate_bits(PSTATE_UAO);
> +        }
> +        t1 = tcg_const_i32(s->current_el);
> +        gen_helper_rebuild_hflags_a64(cpu_env, t1);
> +        tcg_temp_free_i32(t1);
> +        break;

Do we also need to end the TB since we've messed with
the hflags, or is some bit of code not in the patch
context handling that?

> +
>      case 0x04: /* PAN */
>          if (!dc_isar_feature(aa64_pan, s) || s->current_el == 0) {
>              goto do_unallocated;
> --
> 2.17.1

Does the "on exception entry PSTATE.UAO is zeroed" behaviour
fall out automatically for us? How about "on exception entry
from aarch32 to aarch64 SPSR_ELx.UAO is set to zero" ?

I think we may also want a minor code change so that an exception
return from aarch64 to aarch32 doesn't copy a bogus SPSR UAO==1
into the pstate/cpsr.

thanks
-- PMM


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 3/4] target/arm: Implement UAO semantics
  2019-12-03 23:42 ` [PATCH 3/4] target/arm: Implement UAO semantics Richard Henderson
@ 2019-12-06 18:31   ` Peter Maydell
  0 siblings, 0 replies; 14+ messages in thread
From: Peter Maydell @ 2019-12-06 18:31 UTC (permalink / raw)
  To: Richard Henderson; +Cc: QEMU Developers

On Tue, 3 Dec 2019 at 23:42, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> We need only override the current condition under which
> TBFLAG_A64.UNPRIV is set.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/arm/helper.c | 41 +++++++++++++++++++++--------------------
>  1 file changed, 21 insertions(+), 20 deletions(-)

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

thanks
-- PMM


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 4/4] target/arm: Enable ARMv8.2-UAO in -cpu max
  2019-12-03 23:42 ` [PATCH 4/4] target/arm: Enable ARMv8.2-UAO in -cpu max Richard Henderson
@ 2019-12-06 18:31   ` Peter Maydell
  0 siblings, 0 replies; 14+ messages in thread
From: Peter Maydell @ 2019-12-06 18:31 UTC (permalink / raw)
  To: Richard Henderson; +Cc: QEMU Developers

On Tue, 3 Dec 2019 at 23:42, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/arm/cpu64.c | 4 ++++
>  1 file changed, 4 insertions(+)
>
> diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
> index 9399253b4c..03377084e3 100644
> --- a/target/arm/cpu64.c
> +++ b/target/arm/cpu64.c
> @@ -674,6 +674,10 @@ static void aarch64_max_initfn(Object *obj)
>          t = FIELD_DP64(t, ID_AA64MMFR1, PAN, 2); /* ATS1E1 */
>          cpu->isar.id_aa64mmfr1 = t;
>
> +        t = cpu->isar.id_aa64mmfr2;
> +        t = FIELD_DP64(t, ID_AA64MMFR2, UAO, 1);
> +        cpu->isar.id_aa64mmfr2 = t;
> +
>          /* Replicate the same data to the 32-bit id registers.  */
>          u = cpu->isar.id_isar5;
>          u = FIELD_DP32(u, ID_ISAR5, AES, 2); /* AES + PMULL */
> --
> 2.17.1

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

thanks
-- PMM


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 2/4] target/arm: Update MSR access to UAO
  2019-12-06 18:30   ` Peter Maydell
@ 2019-12-06 19:00     ` Richard Henderson
  2020-02-02  1:00     ` Richard Henderson
  1 sibling, 0 replies; 14+ messages in thread
From: Richard Henderson @ 2019-12-06 19:00 UTC (permalink / raw)
  To: Peter Maydell; +Cc: QEMU Developers

On 12/6/19 10:30 AM, Peter Maydell wrote:
>> +    if (cpu_isar_feature(aa64_uao, cpu)) {
>> +        static const ARMCPRegInfo uao_reginfo[] = {
>> +            { .name = "UAO", .state = ARM_CP_STATE_AA64,
>> +              .opc0 = 3, .opc1 = 0, .crn = 4, .crm = 2, .opc2 = 4,
>> +              .type = ARM_CP_NO_RAW, .access = PL1_RW,
>> +              .readfn = aa64_uao_read, .writefn = aa64_uao_write, },
>> +            REGINFO_SENTINEL
>> +        };
> 
> This could just be a file-scope global, right?
> Also, you can just use define_one_arm_cp_reg() rather
> than having a list with one entry. (cf zcr_el1_reginfo).

Can do.

>> +    case 0x03: /* UAO */
>> +        if (!dc_isar_feature(aa64_uao, s) || s->current_el == 0) {
>> +            goto do_unallocated;
>> +        }
>> +        if (crm & 1) {
>> +            set_pstate_bits(PSTATE_UAO);
>> +        } else {
>> +            clear_pstate_bits(PSTATE_UAO);
>> +        }
>> +        t1 = tcg_const_i32(s->current_el);
>> +        gen_helper_rebuild_hflags_a64(cpu_env, t1);
>> +        tcg_temp_free_i32(t1);
>> +        break;
> 
> Do we also need to end the TB since we've messed with
> the hflags, or is some bit of code not in the patch
> context handling that?

Outside the patch context, at the start of the function, we default to ending
the TB.

> Does the "on exception entry PSTATE.UAO is zeroed" behaviour
> fall out automatically for us? How about "on exception entry
> from aarch32 to aarch64 SPSR_ELx.UAO is set to zero" ?

Yes to both -- new_mode (perhaps better renamed as new_pstate) is initialized
as 0 + stuff required to be non-zero.  Thus PAN required special handling but
UAO does not.

> I think we may also want a minor code change so that an exception
> return from aarch64 to aarch32 doesn't copy a bogus SPSR UAO==1
> into the pstate/cpsr.

Ah, good catch.


r~


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 1/4] target/arm: Add ID_AA64MMFR2_EL1
  2019-12-06 18:19   ` Peter Maydell
@ 2020-02-02  0:54     ` Richard Henderson
  0 siblings, 0 replies; 14+ messages in thread
From: Richard Henderson @ 2020-02-02  0:54 UTC (permalink / raw)
  To: Peter Maydell; +Cc: QEMU Developers

On 12/6/19 10:19 AM, Peter Maydell wrote:
>> @@ -549,6 +549,8 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
>>                                ARM64_SYS_REG(3, 0, 0, 7, 0));
>>          err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64mmfr1,
>>                                ARM64_SYS_REG(3, 0, 0, 7, 1));
>> +        err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64mmfr2,
>> +                              ARM64_SYS_REG(3, 0, 0, 7, 2));
> 
> Do current KVM kernels definitely handle the request for this
> new register (ie don't return an error)?

Yes, ID_AA64MMFR2 was added to the sys_regs table in the same commit
(93390c0a1b20b) as all of the others here.


r~


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 2/4] target/arm: Update MSR access to UAO
  2019-12-06 18:30   ` Peter Maydell
  2019-12-06 19:00     ` Richard Henderson
@ 2020-02-02  1:00     ` Richard Henderson
  2020-02-02 13:29       ` Peter Maydell
  1 sibling, 1 reply; 14+ messages in thread
From: Richard Henderson @ 2020-02-02  1:00 UTC (permalink / raw)
  To: Peter Maydell; +Cc: QEMU Developers

On 12/6/19 10:30 AM, Peter Maydell wrote:
>> +    if (cpu_isar_feature(aa64_uao, cpu)) {
>> +        static const ARMCPRegInfo uao_reginfo[] = {
>> +            { .name = "UAO", .state = ARM_CP_STATE_AA64,
>> +              .opc0 = 3, .opc1 = 0, .crn = 4, .crm = 2, .opc2 = 4,
>> +              .type = ARM_CP_NO_RAW, .access = PL1_RW,
>> +              .readfn = aa64_uao_read, .writefn = aa64_uao_write, },
>> +            REGINFO_SENTINEL
>> +        };
> 
> This could just be a file-scope global, right?
> Also, you can just use define_one_arm_cp_reg() rather
> than having a list with one entry. (cf zcr_el1_reginfo).

Done.

>> +    case 0x03: /* UAO */
>> +        if (!dc_isar_feature(aa64_uao, s) || s->current_el == 0) {
>> +            goto do_unallocated;
>> +        }
>> +        if (crm & 1) {
>> +            set_pstate_bits(PSTATE_UAO);
>> +        } else {
>> +            clear_pstate_bits(PSTATE_UAO);
>> +        }
>> +        t1 = tcg_const_i32(s->current_el);
>> +        gen_helper_rebuild_hflags_a64(cpu_env, t1);
>> +        tcg_temp_free_i32(t1);
>> +        break;
> 
> Do we also need to end the TB since we've messed with
> the hflags, or is some bit of code not in the patch
> context handling that?

This is done by default.  We would have to do something special to avoid ending
the TB here.

> Does the "on exception entry PSTATE.UAO is zeroed" behaviour
> fall out automatically for us?

Yes, aarch64_pstate_mode() returns a clean PSTATE.

> How about "on exception entry
> from aarch32 to aarch64 SPSR_ELx.UAO is set to zero" ?

This follows the same path as above, as far as I can see.

> I think we may also want a minor code change so that an exception
> return from aarch64 to aarch32 doesn't copy a bogus SPSR UAO==1
> into the pstate/cpsr.

Well, there is no CPSR UAO bit, so there's no aarch32 bit to clear.  But I did
add a clearing of PSTATE UAO on the exception return to aarch64 path, to
prevent the guest from playing games with SPSR.


r~


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 2/4] target/arm: Update MSR access to UAO
  2020-02-02  1:00     ` Richard Henderson
@ 2020-02-02 13:29       ` Peter Maydell
  2020-02-03  7:46         ` Richard Henderson
  0 siblings, 1 reply; 14+ messages in thread
From: Peter Maydell @ 2020-02-02 13:29 UTC (permalink / raw)
  To: Richard Henderson; +Cc: QEMU Developers

On Sun, 2 Feb 2020 at 01:00, Richard Henderson
<richard.henderson@linaro.org> wrote:
> > Does the "on exception entry PSTATE.UAO is zeroed" behaviour
> > fall out automatically for us?
>
> Yes, aarch64_pstate_mode() returns a clean PSTATE.
>
> > How about "on exception entry
> > from aarch32 to aarch64 SPSR_ELx.UAO is set to zero" ?
>
> This follows the same path as above, as far as I can see.

Yes, but SPSR_ELx isn't started with a clean zero and built up
the way the new PSTATE is, it gets copied from the AArch32 CPSR
via cpsr_read(). I forget how carefully we keep the guest from setting
CPSR bits that aren't really valid for the CPU...

> > I think we may also want a minor code change so that an exception
> > return from aarch64 to aarch32 doesn't copy a bogus SPSR UAO==1
> > into the pstate/cpsr.
>
> Well, there is no CPSR UAO bit, so there's no aarch32 bit to clear.  But I did
> add a clearing of PSTATE UAO on the exception return to aarch64 path, to
> prevent the guest from playing games with SPSR.

...for instance on the aarch64->aarch32 exception return path,
I don't think we sanitize the SPSR bits, so the guest could use
a 64->32 exception return to set a bogus CPSR.UAO bit and
then enter from 32 to 64 and see SPSR_ELx.UAO set when
it should not be, unless we sanitize either in all places where
we let the guest set CPSR bits (including 64->32 return), or
we sanitize on 32->64 entry.

thanks
-- PMM


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 2/4] target/arm: Update MSR access to UAO
  2020-02-02 13:29       ` Peter Maydell
@ 2020-02-03  7:46         ` Richard Henderson
  0 siblings, 0 replies; 14+ messages in thread
From: Richard Henderson @ 2020-02-03  7:46 UTC (permalink / raw)
  To: Peter Maydell; +Cc: QEMU Developers

On 2/2/20 1:29 PM, Peter Maydell wrote:
> Yes, but SPSR_ELx isn't started with a clean zero and built up
> the way the new PSTATE is, it gets copied from the AArch32 CPSR
> via cpsr_read(). I forget how carefully we keep the guest from setting
> CPSR bits that aren't really valid for the CPU...

We do an ok job, except...

>> Well, there is no CPSR UAO bit, so there's no aarch32 bit to clear.  But I did
>> add a clearing of PSTATE UAO on the exception return to aarch64 path, to
>> prevent the guest from playing games with SPSR.
> 
> ...for instance on the aarch64->aarch32 exception return path,

... here.

> I don't think we sanitize the SPSR bits, so the guest could use
> a 64->32 exception return to set a bogus CPSR.UAO bit and
> then enter from 32 to 64 and see SPSR_ELx.UAO set when
> it should not be, unless we sanitize either in all places where
> we let the guest set CPSR bits (including 64->32 return), or
> we sanitize on 32->64 entry.

There is no CPSR.UAO bit, so this chain of logic doesn't hold for that specific
instance.  But plausibly so for CPSR.PAN.

We do sanitize all of the places where CPSR/PSTATE is explicitly set.  I think
we've covered all but one of the exception return paths, sanitizing the
SPSR_ELx values.

We could move some of this logic to internals.h so that it could be shared
between CPSR and exception return.  I'll think about that for v3.


r~


^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2020-02-03  7:47 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-12-03 23:42 [PATCH 0/4] target/arm: Implement ARMv8.2-UAO Richard Henderson
2019-12-03 23:42 ` [PATCH 1/4] target/arm: Add ID_AA64MMFR2_EL1 Richard Henderson
2019-12-06 18:19   ` Peter Maydell
2020-02-02  0:54     ` Richard Henderson
2019-12-03 23:42 ` [PATCH 2/4] target/arm: Update MSR access to UAO Richard Henderson
2019-12-06 18:30   ` Peter Maydell
2019-12-06 19:00     ` Richard Henderson
2020-02-02  1:00     ` Richard Henderson
2020-02-02 13:29       ` Peter Maydell
2020-02-03  7:46         ` Richard Henderson
2019-12-03 23:42 ` [PATCH 3/4] target/arm: Implement UAO semantics Richard Henderson
2019-12-06 18:31   ` Peter Maydell
2019-12-03 23:42 ` [PATCH 4/4] target/arm: Enable ARMv8.2-UAO in -cpu max Richard Henderson
2019-12-06 18:31   ` Peter Maydell

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).