All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v2 00/27] target/arm: Implement ARMv8.3-PAuth
@ 2018-12-14  5:23 Richard Henderson
  2018-12-14  5:23 ` [Qemu-devel] [PATCH v2 01/27] target/arm: Add state for the ARMv8.3-PAuth extension Richard Henderson
                   ` (26 more replies)
  0 siblings, 27 replies; 51+ messages in thread
From: Richard Henderson @ 2018-12-14  5:23 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell

Lots of little changes since v1, but many of which are noted
within each patch.  This version works in system mode, using

https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git/log/?h=for-next/core


r~

Richard Henderson (27):
  target/arm: Add state for the ARMv8.3-PAuth extension
  target/arm: Add SCTLR bits through ARMv8.5
  target/arm: Add PAuth active bit to tbflags
  target/arm: Add PAuth helpers
  target/arm: Decode PAuth within system hint space
  target/arm: Rearrange decode in disas_data_proc_1src
  target/arm: Decode PAuth within disas_data_proc_1src
  target/arm: Decode PAuth within disas_data_proc_2src
  target/arm: Move helper_exception_return to helper-a64.c
  target/arm: Add new_pc argument to helper_exception_return
  target/arm: Rearrange decode in disas_uncond_b_reg
  target/arm: Decode PAuth within disas_uncond_b_reg
  target/arm: Decode Load/store register (pac)
  target/arm: Move cpu_mmu_index out of line
  target/arm: Introduce arm_mmu_idx
  target/arm: Introduce arm_stage1_mmu_idx
  target/arm: Create ARMVAParameters and helpers
  target/arm: Reuse aa64_va_parameters for setting tbflags
  target/arm: Export aa64_va_parameters to internals.h
  target/arm: Implement pauth_strip
  target/arm: Implement pauth_auth
  target/arm: Implement pauth_addpac
  target/arm: Implement pauth_computepac
  target/arm: Add PAuth system registers
  target/arm: Enable PAuth for -cpu max
  target/arm: Enable PAuth for user-only, part 2
  target/arm: Tidy TBI handling in gen_a64_set_pc

 target/arm/cpu.h           | 171 +++++-----
 target/arm/helper-a64.h    |  14 +
 target/arm/helper.h        |   1 -
 target/arm/internals.h     |  62 ++++
 target/arm/translate.h     |   2 +
 target/arm/cpu.c           |   6 +
 target/arm/cpu64.c         |   4 +
 target/arm/helper-a64.c    | 629 +++++++++++++++++++++++++++++++++++++
 target/arm/helper.c        | 500 ++++++++++++++++++-----------
 target/arm/op_helper.c     | 155 ---------
 target/arm/translate-a64.c | 534 ++++++++++++++++++++++++++-----
 11 files changed, 1581 insertions(+), 497 deletions(-)

-- 
2.17.2

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

* [Qemu-devel] [PATCH v2 01/27] target/arm: Add state for the ARMv8.3-PAuth extension
  2018-12-14  5:23 [Qemu-devel] [PATCH v2 00/27] target/arm: Implement ARMv8.3-PAuth Richard Henderson
@ 2018-12-14  5:23 ` Richard Henderson
  2019-01-04 16:25   ` Peter Maydell
  2018-12-14  5:23 ` [Qemu-devel] [PATCH v2 02/27] target/arm: Add SCTLR bits through ARMv8.5 Richard Henderson
                   ` (25 subsequent siblings)
  26 siblings, 1 reply; 51+ messages in thread
From: Richard Henderson @ 2018-12-14  5:23 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell

Add storage space for the 5 encryption keys.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
----
v2: Remove pointless double migration.
    Use a struct to make it clear which half is which.
---
 target/arm/cpu.h | 30 +++++++++++++++++++++++++++++-
 1 file changed, 29 insertions(+), 1 deletion(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index c943f35dd9..39d4afdfe6 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -201,11 +201,16 @@ typedef struct ARMVectorReg {
     uint64_t d[2 * ARM_MAX_VQ] QEMU_ALIGNED(16);
 } ARMVectorReg;
 
-/* In AArch32 mode, predicate registers do not exist at all.  */
 #ifdef TARGET_AARCH64
+/* In AArch32 mode, predicate registers do not exist at all.  */
 typedef struct ARMPredicateReg {
     uint64_t p[2 * ARM_MAX_VQ / 8] QEMU_ALIGNED(16);
 } ARMPredicateReg;
+
+/* In AArch32 mode, PAC keys do not exist at all.  */
+typedef struct ARMPACKey {
+    uint64_t lo, hi;
+} ARMPACKey;
 #endif
 
 
@@ -605,6 +610,14 @@ typedef struct CPUARMState {
         uint32_t cregs[16];
     } iwmmxt;
 
+#ifdef TARGET_AARCH64
+    ARMPACKey apia_key;
+    ARMPACKey apib_key;
+    ARMPACKey apda_key;
+    ARMPACKey apdb_key;
+    ARMPACKey apga_key;
+#endif
+
 #if defined(CONFIG_USER_ONLY)
     /* For usermode syscall translation.  */
     int eabi;
@@ -3324,6 +3337,21 @@ static inline bool isar_feature_aa64_fcma(const ARMISARegisters *id)
     return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, FCMA) != 0;
 }
 
+static inline bool isar_feature_aa64_pauth(const ARMISARegisters *id)
+{
+    /*
+     * Note that while QEMU will only implement the architected algorithm
+     * QARMA, and thus APA+GPA, the host cpu for kvm may use implementation
+     * defined algorithms, and thus API+GPI, and this predicate controls
+     * migration of the 128-bit keys.
+     */
+    return (id->id_aa64isar1 &
+            (FIELD_DP64(0, ID_AA64ISAR1, APA, -1) |
+             FIELD_DP64(0, ID_AA64ISAR1, API, -1) |
+             FIELD_DP64(0, ID_AA64ISAR1, GPA, -1) |
+             FIELD_DP64(0, ID_AA64ISAR1, GPI, -1))) != 0;
+}
+
 static inline bool isar_feature_aa64_fp16(const ARMISARegisters *id)
 {
     /* We always set the AdvSIMD and FP fields identically wrt FP16.  */
-- 
2.17.2

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

* [Qemu-devel] [PATCH v2 02/27] target/arm: Add SCTLR bits through ARMv8.5
  2018-12-14  5:23 [Qemu-devel] [PATCH v2 00/27] target/arm: Implement ARMv8.3-PAuth Richard Henderson
  2018-12-14  5:23 ` [Qemu-devel] [PATCH v2 01/27] target/arm: Add state for the ARMv8.3-PAuth extension Richard Henderson
@ 2018-12-14  5:23 ` Richard Henderson
  2018-12-14  5:23 ` [Qemu-devel] [PATCH v2 03/27] target/arm: Add PAuth active bit to tbflags Richard Henderson
                   ` (24 subsequent siblings)
  26 siblings, 0 replies; 51+ messages in thread
From: Richard Henderson @ 2018-12-14  5:23 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell

Post v8.4 bits taken from SysReg_v85_xml-00bet8.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
----
v2: Review fixups from Peter.
---
 target/arm/cpu.h | 45 +++++++++++++++++++++++++++++++++------------
 1 file changed, 33 insertions(+), 12 deletions(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 39d4afdfe6..cd2519d43e 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -989,12 +989,15 @@ void pmccntr_sync(CPUARMState *env);
 #define SCTLR_A       (1U << 1)
 #define SCTLR_C       (1U << 2)
 #define SCTLR_W       (1U << 3) /* up to v6; RAO in v7 */
-#define SCTLR_SA      (1U << 3)
+#define SCTLR_nTLSMD_32 (1U << 3) /* v8.2-LSMAOC, AArch32 only */
+#define SCTLR_SA      (1U << 3) /* AArch64 only */
 #define SCTLR_P       (1U << 4) /* up to v5; RAO in v6 and v7 */
+#define SCTLR_LSMAOE_32 (1U << 4) /* v8.2-LSMAOC, AArch32 only */
 #define SCTLR_SA0     (1U << 4) /* v8 onward, AArch64 only */
 #define SCTLR_D       (1U << 5) /* up to v5; RAO in v6 */
 #define SCTLR_CP15BEN (1U << 5) /* v7 onward */
 #define SCTLR_L       (1U << 6) /* up to v5; RAO in v6 and v7; RAZ in v8 */
+#define SCTLR_nAA     (1U << 6) /* when v8.4-LSE is implemented */
 #define SCTLR_B       (1U << 7) /* up to v6; RAZ in v7 */
 #define SCTLR_ITD     (1U << 7) /* v8 onward */
 #define SCTLR_S       (1U << 8) /* up to v6; RAZ in v7 */
@@ -1002,35 +1005,53 @@ void pmccntr_sync(CPUARMState *env);
 #define SCTLR_R       (1U << 9) /* up to v6; RAZ in v7 */
 #define SCTLR_UMA     (1U << 9) /* v8 onward, AArch64 only */
 #define SCTLR_F       (1U << 10) /* up to v6 */
-#define SCTLR_SW      (1U << 10) /* v7 onward */
-#define SCTLR_Z       (1U << 11)
+#define SCTLR_SW      (1U << 10) /* v7, RES0 in v8 */
+#define SCTLR_Z       (1U << 11) /* in v7, RES1 in v8 */
+#define SCTLR_EOS     (1U << 11) /* v8.5-ExS */
 #define SCTLR_I       (1U << 12)
-#define SCTLR_V       (1U << 13)
+#define SCTLR_V       (1U << 13) /* AArch32 only */
+#define SCTLR_EnDB    (1U << 13) /* v8.3, AArch64 only */
 #define SCTLR_RR      (1U << 14) /* up to v7 */
 #define SCTLR_DZE     (1U << 14) /* v8 onward, AArch64 only */
 #define SCTLR_L4      (1U << 15) /* up to v6; RAZ in v7 */
 #define SCTLR_UCT     (1U << 15) /* v8 onward, AArch64 only */
 #define SCTLR_DT      (1U << 16) /* up to ??, RAO in v6 and v7 */
 #define SCTLR_nTWI    (1U << 16) /* v8 onward */
-#define SCTLR_HA      (1U << 17)
+#define SCTLR_HA      (1U << 17) /* up to v7, RES0 in v8 */
 #define SCTLR_BR      (1U << 17) /* PMSA only */
 #define SCTLR_IT      (1U << 18) /* up to ??, RAO in v6 and v7 */
 #define SCTLR_nTWE    (1U << 18) /* v8 onward */
 #define SCTLR_WXN     (1U << 19)
 #define SCTLR_ST      (1U << 20) /* up to ??, RAZ in v6 */
-#define SCTLR_UWXN    (1U << 20) /* v7 onward */
-#define SCTLR_FI      (1U << 21)
-#define SCTLR_U       (1U << 22)
+#define SCTLR_UWXN    (1U << 20) /* v7 onward, AArch32 only */
+#define SCTLR_FI      (1U << 21) /* up to v7, v8 RES0 */
+#define SCTLR_IESB    (1U << 21) /* v8.2-IESB, AArch64 only */
+#define SCTLR_U       (1U << 22) /* up to v6, RAO in v7 */
+#define SCTLR_EIS     (1U << 22) /* v8.5-ExS */
 #define SCTLR_XP      (1U << 23) /* up to v6; v7 onward RAO */
+#define SCTLR_SPAN    (1U << 23) /* v8.1-PAN */
 #define SCTLR_VE      (1U << 24) /* up to v7 */
 #define SCTLR_E0E     (1U << 24) /* v8 onward, AArch64 only */
 #define SCTLR_EE      (1U << 25)
 #define SCTLR_L2      (1U << 26) /* up to v6, RAZ in v7 */
 #define SCTLR_UCI     (1U << 26) /* v8 onward, AArch64 only */
-#define SCTLR_NMFI    (1U << 27)
-#define SCTLR_TRE     (1U << 28)
-#define SCTLR_AFE     (1U << 29)
-#define SCTLR_TE      (1U << 30)
+#define SCTLR_NMFI    (1U << 27) /* up to v7, RAZ in v7VE and v8 */
+#define SCTLR_EnDA    (1U << 27) /* v8.3, AArch64 only */
+#define SCTLR_TRE     (1U << 28) /* AArch32 only */
+#define SCTLR_nTLSMD_64 (1U << 28) /* v8.2-LSMAOC, AArch64 only */
+#define SCTLR_AFE     (1U << 29) /* AArch32 only */
+#define SCTLR_LSMAOE_64 (1U << 29) /* v8.2-LSMAOC, AArch64 only */
+#define SCTLR_TE      (1U << 30) /* AArch32 only */
+#define SCTLR_EnIB    (1U << 30) /* v8.3, AArch64 only */
+#define SCTLR_EnIA    (1U << 31) /* v8.3, AArch64 only */
+#define SCTLR_BT0     (1ULL << 35) /* v8.5-BTI */
+#define SCTLR_BT1     (1ULL << 36) /* v8.5-BTI */
+#define SCTLR_ITFSB   (1ULL << 37) /* v8.5-MemTag */
+#define SCTLR_TCF0    (3ULL << 38) /* v8.5-MemTag */
+#define SCTLR_TCF     (3ULL << 40) /* v8.5-MemTag */
+#define SCTLR_ATA0    (1ULL << 42) /* v8.5-MemTag */
+#define SCTLR_ATA     (1ULL << 43) /* v8.5-MemTag */
+#define SCTLR_DSSBS   (1ULL << 44) /* v8.5 */
 
 #define CPTR_TCPAC    (1U << 31)
 #define CPTR_TTA      (1U << 20)
-- 
2.17.2

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

* [Qemu-devel] [PATCH v2 03/27] target/arm: Add PAuth active bit to tbflags
  2018-12-14  5:23 [Qemu-devel] [PATCH v2 00/27] target/arm: Implement ARMv8.3-PAuth Richard Henderson
  2018-12-14  5:23 ` [Qemu-devel] [PATCH v2 01/27] target/arm: Add state for the ARMv8.3-PAuth extension Richard Henderson
  2018-12-14  5:23 ` [Qemu-devel] [PATCH v2 02/27] target/arm: Add SCTLR bits through ARMv8.5 Richard Henderson
@ 2018-12-14  5:23 ` Richard Henderson
  2018-12-14  5:23 ` [Qemu-devel] [PATCH v2 04/27] target/arm: Add PAuth helpers Richard Henderson
                   ` (23 subsequent siblings)
  26 siblings, 0 replies; 51+ messages in thread
From: Richard Henderson @ 2018-12-14  5:23 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell

There are 5 bits of state that could be added, but to save
space within tbflags, add only a single enable bit.
Helpers will determine the rest of the state at runtime.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
----
v2: Fix whitespace, comment grammar.
---
 target/arm/cpu.h           |  4 ++++
 target/arm/translate.h     |  2 ++
 target/arm/helper.c        | 19 +++++++++++++++++++
 target/arm/translate-a64.c |  1 +
 4 files changed, 26 insertions(+)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index cd2519d43e..898243c93e 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -3032,6 +3032,8 @@ static inline bool arm_cpu_data_is_big_endian(CPUARMState *env)
 #define ARM_TBFLAG_SVEEXC_EL_MASK   (0x3 << ARM_TBFLAG_SVEEXC_EL_SHIFT)
 #define ARM_TBFLAG_ZCR_LEN_SHIFT    4
 #define ARM_TBFLAG_ZCR_LEN_MASK     (0xf << ARM_TBFLAG_ZCR_LEN_SHIFT)
+#define ARM_TBFLAG_PAUTH_ACTIVE_SHIFT  8
+#define ARM_TBFLAG_PAUTH_ACTIVE_MASK   (1ull << ARM_TBFLAG_PAUTH_ACTIVE_SHIFT)
 
 /* some convenience accessor macros */
 #define ARM_TBFLAG_AARCH64_STATE(F) \
@@ -3074,6 +3076,8 @@ static inline bool arm_cpu_data_is_big_endian(CPUARMState *env)
     (((F) & ARM_TBFLAG_SVEEXC_EL_MASK) >> ARM_TBFLAG_SVEEXC_EL_SHIFT)
 #define ARM_TBFLAG_ZCR_LEN(F) \
     (((F) & ARM_TBFLAG_ZCR_LEN_MASK) >> ARM_TBFLAG_ZCR_LEN_SHIFT)
+#define ARM_TBFLAG_PAUTH_ACTIVE(F) \
+    (((F) & ARM_TBFLAG_PAUTH_ACTIVE_MASK) >> ARM_TBFLAG_PAUTH_ACTIVE_SHIFT)
 
 static inline bool bswap_code(bool sctlr_b)
 {
diff --git a/target/arm/translate.h b/target/arm/translate.h
index 1550aa8bc7..d8a8bb4e9c 100644
--- a/target/arm/translate.h
+++ b/target/arm/translate.h
@@ -68,6 +68,8 @@ typedef struct DisasContext {
     bool is_ldex;
     /* True if a single-step exception will be taken to the current EL */
     bool ss_same_el;
+    /* True if v8.3-PAuth is active.  */
+    bool pauth_active;
     /* Bottom two bits of XScale c15_cpar coprocessor access control reg */
     int c15_cpar;
     /* TCG op of the current insn_start.  */
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 644599b29d..bd0cff5c27 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -12981,6 +12981,25 @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
             flags |= sve_el << ARM_TBFLAG_SVEEXC_EL_SHIFT;
             flags |= zcr_len << ARM_TBFLAG_ZCR_LEN_SHIFT;
         }
+
+        if (cpu_isar_feature(aa64_pauth, cpu)) {
+            /*
+             * In order to save space in flags, we record only whether
+             * pauth is "inactive", meaning all insns are implemented as
+             * a nop, or "active" when some action must be performed.
+             * The decision of which action to take is left to a helper.
+             */
+            uint64_t sctlr;
+            if (current_el == 0) {
+                /* FIXME: ARMv8.1-VHE S2 translation regime.  */
+                sctlr = env->cp15.sctlr_el[1];
+            } else {
+                sctlr = env->cp15.sctlr_el[current_el];
+            }
+            if (sctlr & (SCTLR_EnIA | SCTLR_EnIB | SCTLR_EnDA | SCTLR_EnDB)) {
+                flags |= ARM_TBFLAG_PAUTH_ACTIVE_MASK;
+            }
+        }
     } else {
         *pc = env->regs[15];
         flags = (env->thumb << ARM_TBFLAG_THUMB_SHIFT)
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index e1da1e4d6f..7c1cc1ce8e 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -13407,6 +13407,7 @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
     dc->fp_excp_el = ARM_TBFLAG_FPEXC_EL(dc->base.tb->flags);
     dc->sve_excp_el = ARM_TBFLAG_SVEEXC_EL(dc->base.tb->flags);
     dc->sve_len = (ARM_TBFLAG_ZCR_LEN(dc->base.tb->flags) + 1) * 16;
+    dc->pauth_active = ARM_TBFLAG_PAUTH_ACTIVE(dc->base.tb->flags);
     dc->vec_len = 0;
     dc->vec_stride = 0;
     dc->cp_regs = arm_cpu->cp_regs;
-- 
2.17.2

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

* [Qemu-devel] [PATCH v2 04/27] target/arm: Add PAuth helpers
  2018-12-14  5:23 [Qemu-devel] [PATCH v2 00/27] target/arm: Implement ARMv8.3-PAuth Richard Henderson
                   ` (2 preceding siblings ...)
  2018-12-14  5:23 ` [Qemu-devel] [PATCH v2 03/27] target/arm: Add PAuth active bit to tbflags Richard Henderson
@ 2018-12-14  5:23 ` Richard Henderson
  2019-01-04 16:25   ` Peter Maydell
  2018-12-14  5:23 ` [Qemu-devel] [PATCH v2 05/27] target/arm: Decode PAuth within system hint space Richard Henderson
                   ` (22 subsequent siblings)
  26 siblings, 1 reply; 51+ messages in thread
From: Richard Henderson @ 2018-12-14  5:23 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell

The cryptographic internals are stubbed out for now,
but the enable and trap bits are checked.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
----
v2: Remove trap from xpac* helpers; these are now side-effect free.
    Use struct ARMPACKey.
---
 target/arm/helper-a64.h |  12 +++
 target/arm/internals.h  |   6 ++
 target/arm/helper-a64.c | 166 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 184 insertions(+)

diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
index 9d3a907049..28aa0af69d 100644
--- a/target/arm/helper-a64.h
+++ b/target/arm/helper-a64.h
@@ -85,3 +85,15 @@ DEF_HELPER_2(advsimd_rinth, f16, f16, ptr)
 DEF_HELPER_2(advsimd_f16tosinth, i32, f16, ptr)
 DEF_HELPER_2(advsimd_f16touinth, i32, f16, ptr)
 DEF_HELPER_2(sqrt_f16, f16, f16, ptr)
+
+DEF_HELPER_FLAGS_3(pacia, TCG_CALL_NO_WG, i64, env, i64, i64)
+DEF_HELPER_FLAGS_3(pacib, TCG_CALL_NO_WG, i64, env, i64, i64)
+DEF_HELPER_FLAGS_3(pacda, TCG_CALL_NO_WG, i64, env, i64, i64)
+DEF_HELPER_FLAGS_3(pacdb, TCG_CALL_NO_WG, i64, env, i64, i64)
+DEF_HELPER_FLAGS_3(pacga, TCG_CALL_NO_WG, i64, env, i64, i64)
+DEF_HELPER_FLAGS_3(autia, TCG_CALL_NO_WG, i64, env, i64, i64)
+DEF_HELPER_FLAGS_3(autib, TCG_CALL_NO_WG, i64, env, i64, i64)
+DEF_HELPER_FLAGS_3(autda, TCG_CALL_NO_WG, i64, env, i64, i64)
+DEF_HELPER_FLAGS_3(autdb, TCG_CALL_NO_WG, i64, env, i64, i64)
+DEF_HELPER_FLAGS_2(xpaci, TCG_CALL_NO_RWG_SE, i64, env, i64)
+DEF_HELPER_FLAGS_2(xpacd, TCG_CALL_NO_RWG_SE, i64, env, i64)
diff --git a/target/arm/internals.h b/target/arm/internals.h
index 78e026d6e9..6bc0daf560 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -259,6 +259,7 @@ enum arm_exception_class {
     EC_CP14DTTRAP             = 0x06,
     EC_ADVSIMDFPACCESSTRAP    = 0x07,
     EC_FPIDTRAP               = 0x08,
+    EC_PACTRAP                = 0x09,
     EC_CP14RRTTRAP            = 0x0c,
     EC_ILLEGALSTATE           = 0x0e,
     EC_AA32_SVC               = 0x11,
@@ -426,6 +427,11 @@ static inline uint32_t syn_sve_access_trap(void)
     return EC_SVEACCESSTRAP << ARM_EL_EC_SHIFT;
 }
 
+static inline uint32_t syn_pactrap(void)
+{
+    return EC_PACTRAP << ARM_EL_EC_SHIFT;
+}
+
 static inline uint32_t syn_insn_abort(int same_el, int ea, int s1ptw, int fsc)
 {
     return (EC_INSNABORT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
index 61799d20e1..bb64700e10 100644
--- a/target/arm/helper-a64.c
+++ b/target/arm/helper-a64.c
@@ -898,4 +898,170 @@ uint32_t HELPER(sqrt_f16)(uint32_t a, void *fpstp)
     return float16_sqrt(a, s);
 }
 
+/*
+ * Helpers for ARMv8.3-PAuth.
+ */
 
+static uint64_t pauth_computepac(uint64_t data, uint64_t modifier,
+                                 ARMPACKey key)
+{
+    g_assert_not_reached(); /* FIXME */
+}
+
+static uint64_t pauth_addpac(CPUARMState *env, uint64_t ptr, uint64_t modifier,
+                             ARMPACKey *key, bool data)
+{
+    g_assert_not_reached(); /* FIXME */
+}
+
+static uint64_t pauth_auth(CPUARMState *env, uint64_t ptr, uint64_t modifier,
+                           ARMPACKey *key, bool data, int keynumber)
+{
+    g_assert_not_reached(); /* FIXME */
+}
+
+static uint64_t pauth_strip(CPUARMState *env, uint64_t ptr, bool data)
+{
+    g_assert_not_reached(); /* FIXME */
+}
+
+static void QEMU_NORETURN pauth_trap(CPUARMState *env, int target_el,
+                                     uintptr_t ra)
+{
+    CPUState *cs = ENV_GET_CPU(env);
+
+    cs->exception_index = EXCP_UDEF;
+    env->exception.syndrome = syn_pactrap();
+    env->exception.target_el = target_el;
+    cpu_loop_exit_restore(cs, ra);
+}
+
+static void pauth_check_trap(CPUARMState *env, int el, uintptr_t ra)
+{
+    if (el < 2 && arm_feature(env, ARM_FEATURE_EL2)) {
+        uint64_t hcr = arm_hcr_el2_eff(env);
+        bool trap = !(hcr & HCR_API);
+        /* FIXME: ARMv8.1-VHE: trap only applies to EL1&0 regime.  */
+        /* FIXME: ARMv8.3-NV: HCR_NV trap takes precedence for ERETA[AB].  */
+        if (trap) {
+            pauth_trap(env, 2, ra);
+        }
+    }
+    if (el < 3 && arm_feature(env, ARM_FEATURE_EL3)) {
+        if (!(env->cp15.scr_el3 & SCR_API)) {
+            pauth_trap(env, 3, ra);
+        }
+    }
+}
+
+static bool pauth_key_enabled(CPUARMState *env, int el, uint32_t bit)
+{
+    uint32_t sctlr;
+    if (el == 0) {
+        /* FIXME: ARMv8.1-VHE S2 translation regime.  */
+        sctlr = env->cp15.sctlr_el[1];
+    } else {
+        sctlr = env->cp15.sctlr_el[el];
+    }
+    return (sctlr & bit) != 0;
+}
+
+uint64_t HELPER(pacia)(CPUARMState *env, uint64_t x, uint64_t y)
+{
+    int el = arm_current_el(env);
+    if (!pauth_key_enabled(env, el, SCTLR_EnIA)) {
+        return x;
+    }
+    pauth_check_trap(env, el, GETPC());
+    return pauth_addpac(env, x, y, &env->apia_key, false);
+}
+
+uint64_t HELPER(pacib)(CPUARMState *env, uint64_t x, uint64_t y)
+{
+    int el = arm_current_el(env);
+    if (!pauth_key_enabled(env, el, SCTLR_EnIB)) {
+        return x;
+    }
+    pauth_check_trap(env, el, GETPC());
+    return pauth_addpac(env, x, y, &env->apib_key, false);
+}
+
+uint64_t HELPER(pacda)(CPUARMState *env, uint64_t x, uint64_t y)
+{
+    int el = arm_current_el(env);
+    if (!pauth_key_enabled(env, el, SCTLR_EnDA)) {
+        return x;
+    }
+    pauth_check_trap(env, el, GETPC());
+    return pauth_addpac(env, x, y, &env->apda_key, true);
+}
+
+uint64_t HELPER(pacdb)(CPUARMState *env, uint64_t x, uint64_t y)
+{
+    int el = arm_current_el(env);
+    if (!pauth_key_enabled(env, el, SCTLR_EnDB)) {
+        return x;
+    }
+    pauth_check_trap(env, el, GETPC());
+    return pauth_addpac(env, x, y, &env->apdb_key, true);
+}
+
+uint64_t HELPER(pacga)(CPUARMState *env, uint64_t x, uint64_t y)
+{
+    uint64_t pac;
+
+    pauth_check_trap(env, arm_current_el(env), GETPC());
+    pac = pauth_computepac(x, y, env->apga_key);
+
+    return pac & 0xffffffff00000000ull;
+}
+
+uint64_t HELPER(autia)(CPUARMState *env, uint64_t x, uint64_t y)
+{
+    int el = arm_current_el(env);
+    if (!pauth_key_enabled(env, el, SCTLR_EnIA)) {
+        return x;
+    }
+    pauth_check_trap(env, el, GETPC());
+    return pauth_auth(env, x, y, &env->apia_key, false, 0);
+}
+
+uint64_t HELPER(autib)(CPUARMState *env, uint64_t x, uint64_t y)
+{
+    int el = arm_current_el(env);
+    if (!pauth_key_enabled(env, el, SCTLR_EnIB)) {
+        return x;
+    }
+    pauth_check_trap(env, el, GETPC());
+    return pauth_auth(env, x, y, &env->apib_key, false, 1);
+}
+
+uint64_t HELPER(autda)(CPUARMState *env, uint64_t x, uint64_t y)
+{
+    int el = arm_current_el(env);
+    if (!pauth_key_enabled(env, el, SCTLR_EnDA)) {
+        return x;
+    }
+    pauth_check_trap(env, el, GETPC());
+    return pauth_auth(env, x, y, &env->apda_key, true, 0);
+}
+
+uint64_t HELPER(autdb)(CPUARMState *env, uint64_t x, uint64_t y)
+{
+    int el = arm_current_el(env);
+    if (!pauth_key_enabled(env, el, SCTLR_EnDB)) {
+        return x;
+    }
+    pauth_check_trap(env, el, GETPC());
+    return pauth_auth(env, x, y, &env->apdb_key, true, 1);
+}
+
+uint64_t HELPER(xpaci)(CPUARMState *env, uint64_t a)
+{
+    return pauth_strip(env, a, false);
+}
+
+uint64_t HELPER(xpacd)(CPUARMState *env, uint64_t a)
+{
+    return pauth_strip(env, a, true);
+}
-- 
2.17.2

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

* [Qemu-devel] [PATCH v2 05/27] target/arm: Decode PAuth within system hint space
  2018-12-14  5:23 [Qemu-devel] [PATCH v2 00/27] target/arm: Implement ARMv8.3-PAuth Richard Henderson
                   ` (3 preceding siblings ...)
  2018-12-14  5:23 ` [Qemu-devel] [PATCH v2 04/27] target/arm: Add PAuth helpers Richard Henderson
@ 2018-12-14  5:23 ` Richard Henderson
  2019-01-04 16:50   ` Peter Maydell
  2018-12-14  5:23 ` [Qemu-devel] [PATCH v2 06/27] target/arm: Rearrange decode in disas_data_proc_1src Richard Henderson
                   ` (21 subsequent siblings)
  26 siblings, 1 reply; 51+ messages in thread
From: Richard Henderson @ 2018-12-14  5:23 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/translate-a64.c | 93 +++++++++++++++++++++++++++++++++-----
 1 file changed, 81 insertions(+), 12 deletions(-)

diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 7c1cc1ce8e..0df344f9e8 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -1471,33 +1471,102 @@ static void handle_hint(DisasContext *s, uint32_t insn,
     }
 
     switch (selector) {
-    case 0: /* NOP */
-        return;
-    case 3: /* WFI */
+    case 000: /* NOP */
+        break;
+    case 003: /* WFI */
         s->base.is_jmp = DISAS_WFI;
-        return;
+        break;
+    case 001: /* YIELD */
         /* When running in MTTCG we don't generate jumps to the yield and
          * WFE helpers as it won't affect the scheduling of other vCPUs.
          * If we wanted to more completely model WFE/SEV so we don't busy
          * spin unnecessarily we would need to do something more involved.
          */
-    case 1: /* YIELD */
         if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
             s->base.is_jmp = DISAS_YIELD;
         }
-        return;
-    case 2: /* WFE */
+        break;
+    case 002: /* WFE */
         if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
             s->base.is_jmp = DISAS_WFE;
         }
-        return;
-    case 4: /* SEV */
-    case 5: /* SEVL */
+        break;
+    case 004: /* SEV */
+    case 005: /* SEVL */
         /* we treat all as NOP at least for now */
-        return;
+        break;
+    case 007: /* XPACLRI */
+        if (s->pauth_active) {
+            gen_helper_xpaci(cpu_X[30], cpu_env, cpu_X[30]);
+        }
+        break;
+    case 010: /* PACIA1716 */
+        if (s->pauth_active) {
+            gen_helper_pacia(cpu_X[17], cpu_env, cpu_X[17], cpu_X[16]);
+        }
+        break;
+    case 012: /* PACIB1716 */
+        if (s->pauth_active) {
+            gen_helper_pacib(cpu_X[17], cpu_env, cpu_X[17], cpu_X[16]);
+        }
+        break;
+    case 014: /* AUTIA1716 */
+        if (s->pauth_active) {
+            gen_helper_autia(cpu_X[17], cpu_env, cpu_X[17], cpu_X[16]);
+        }
+        break;
+    case 016: /* AUTIB1716 */
+        if (s->pauth_active) {
+            gen_helper_autib(cpu_X[17], cpu_env, cpu_X[17], cpu_X[16]);
+        }
+        break;
+    case 030: /* PACIAZ */
+        if (s->pauth_active) {
+            gen_helper_pacia(cpu_X[30], cpu_env, cpu_X[30],
+                                new_tmp_a64_zero(s));
+        }
+        break;
+    case 031: /* PACIASP */
+        if (s->pauth_active) {
+            gen_helper_pacia(cpu_X[30], cpu_env, cpu_X[30], cpu_X[31]);
+        }
+        break;
+    case 032: /* PACIBZ */
+        if (s->pauth_active) {
+            gen_helper_pacib(cpu_X[30], cpu_env, cpu_X[30],
+                                new_tmp_a64_zero(s));
+        }
+        break;
+    case 033: /* PACIBSP */
+        if (s->pauth_active) {
+            gen_helper_pacib(cpu_X[30], cpu_env, cpu_X[30], cpu_X[31]);
+        }
+        break;
+    case 034: /* AUTIAZ */
+        if (s->pauth_active) {
+            gen_helper_autia(cpu_X[30], cpu_env, cpu_X[30],
+                              new_tmp_a64_zero(s));
+        }
+        break;
+    case 035: /* AUTIASP */
+        if (s->pauth_active) {
+            gen_helper_autia(cpu_X[30], cpu_env, cpu_X[30], cpu_X[31]);
+        }
+        break;
+    case 036: /* AUTIBZ */
+        if (s->pauth_active) {
+            gen_helper_autib(cpu_X[30], cpu_env, cpu_X[30],
+                              new_tmp_a64_zero(s));
+        }
+        break;
+    case 037: /* AUTIBSP */
+        if (s->pauth_active) {
+            gen_helper_autib(cpu_X[30], cpu_env, cpu_X[30], cpu_X[31]);
+        }
+        break;
     default:
         /* default specified as NOP equivalent */
-        return;
+        break;
     }
 }
 
-- 
2.17.2

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

* [Qemu-devel] [PATCH v2 06/27] target/arm: Rearrange decode in disas_data_proc_1src
  2018-12-14  5:23 [Qemu-devel] [PATCH v2 00/27] target/arm: Implement ARMv8.3-PAuth Richard Henderson
                   ` (4 preceding siblings ...)
  2018-12-14  5:23 ` [Qemu-devel] [PATCH v2 05/27] target/arm: Decode PAuth within system hint space Richard Henderson
@ 2018-12-14  5:23 ` Richard Henderson
  2018-12-14  5:23 ` [Qemu-devel] [PATCH v2 07/27] target/arm: Decode PAuth within disas_data_proc_1src Richard Henderson
                   ` (20 subsequent siblings)
  26 siblings, 0 replies; 51+ messages in thread
From: Richard Henderson @ 2018-12-14  5:23 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell

Now properly signals unallocated for REV64 with SF=0.
Allows for the opcode2 field to be decoded shortly.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/translate-a64.c | 31 ++++++++++++++++++++++---------
 1 file changed, 22 insertions(+), 9 deletions(-)

diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 0df344f9e8..c5ec430b42 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -4563,38 +4563,51 @@ static void handle_rev16(DisasContext *s, unsigned int sf,
  */
 static void disas_data_proc_1src(DisasContext *s, uint32_t insn)
 {
-    unsigned int sf, opcode, rn, rd;
+    unsigned int sf, opcode, opcode2, rn, rd;
 
-    if (extract32(insn, 29, 1) || extract32(insn, 16, 5)) {
+    if (extract32(insn, 29, 1)) {
         unallocated_encoding(s);
         return;
     }
 
     sf = extract32(insn, 31, 1);
     opcode = extract32(insn, 10, 6);
+    opcode2 = extract32(insn, 16, 5);
     rn = extract32(insn, 5, 5);
     rd = extract32(insn, 0, 5);
 
-    switch (opcode) {
-    case 0: /* RBIT */
+#define MAP(SF, O2, O1) ((SF) | (O1 << 1) | (O2 << 7))
+
+    switch (MAP(sf, opcode2, opcode)) {
+    case MAP(0, 0x00, 0x00): /* RBIT */
+    case MAP(1, 0x00, 0x00):
         handle_rbit(s, sf, rn, rd);
         break;
-    case 1: /* REV16 */
+    case MAP(0, 0x00, 0x01): /* REV16 */
+    case MAP(1, 0x00, 0x01):
         handle_rev16(s, sf, rn, rd);
         break;
-    case 2: /* REV32 */
+    case MAP(0, 0x00, 0x02): /* REV/REV32 */
+    case MAP(1, 0x00, 0x02):
         handle_rev32(s, sf, rn, rd);
         break;
-    case 3: /* REV64 */
+    case MAP(1, 0x00, 0x03): /* REV64 */
         handle_rev64(s, sf, rn, rd);
         break;
-    case 4: /* CLZ */
+    case MAP(0, 0x00, 0x04): /* CLZ */
+    case MAP(1, 0x00, 0x04):
         handle_clz(s, sf, rn, rd);
         break;
-    case 5: /* CLS */
+    case MAP(0, 0x00, 0x05): /* CLS */
+    case MAP(1, 0x00, 0x05):
         handle_cls(s, sf, rn, rd);
         break;
+    default:
+        unallocated_encoding(s);
+        break;
     }
+
+#undef MAP
 }
 
 static void handle_div(DisasContext *s, bool is_signed, unsigned int sf,
-- 
2.17.2

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

* [Qemu-devel] [PATCH v2 07/27] target/arm: Decode PAuth within disas_data_proc_1src
  2018-12-14  5:23 [Qemu-devel] [PATCH v2 00/27] target/arm: Implement ARMv8.3-PAuth Richard Henderson
                   ` (5 preceding siblings ...)
  2018-12-14  5:23 ` [Qemu-devel] [PATCH v2 06/27] target/arm: Rearrange decode in disas_data_proc_1src Richard Henderson
@ 2018-12-14  5:23 ` Richard Henderson
  2019-01-04 17:00   ` Peter Maydell
  2018-12-14  5:23 ` [Qemu-devel] [PATCH v2 08/27] target/arm: Decode PAuth within disas_data_proc_2src Richard Henderson
                   ` (19 subsequent siblings)
  26 siblings, 1 reply; 51+ messages in thread
From: Richard Henderson @ 2018-12-14  5:23 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell

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

diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index c5ec430b42..7ba4c996cf 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -4564,6 +4564,7 @@ static void handle_rev16(DisasContext *s, unsigned int sf,
 static void disas_data_proc_1src(DisasContext *s, uint32_t insn)
 {
     unsigned int sf, opcode, opcode2, rn, rd;
+    TCGv_i64 tcg_rd;
 
     if (extract32(insn, 29, 1)) {
         unallocated_encoding(s);
@@ -4602,7 +4603,152 @@ static void disas_data_proc_1src(DisasContext *s, uint32_t insn)
     case MAP(1, 0x00, 0x05):
         handle_cls(s, sf, rn, rd);
         break;
+    case MAP(1, 0x01, 0x00): /* PACIA */
+        if (s->pauth_active) {
+            tcg_rd = cpu_reg(s, rd);
+            gen_helper_pacia(tcg_rd, cpu_env, tcg_rd, cpu_reg_sp(s, rn));
+        } else if (!dc_isar_feature(aa64_pauth, s)) {
+            goto do_unallocated;
+        }
+        break;
+    case MAP(1, 0x01, 0x01): /* PACIB */
+        if (s->pauth_active) {
+            tcg_rd = cpu_reg(s, rd);
+            gen_helper_pacib(tcg_rd, cpu_env, tcg_rd, cpu_reg_sp(s, rn));
+        } else if (!dc_isar_feature(aa64_pauth, s)) {
+            goto do_unallocated;
+        }
+        break;
+    case MAP(1, 0x01, 0x02): /* PACDA */
+        if (s->pauth_active) {
+            tcg_rd = cpu_reg(s, rd);
+            gen_helper_pacda(tcg_rd, cpu_env, tcg_rd, cpu_reg_sp(s, rn));
+        } else if (!dc_isar_feature(aa64_pauth, s)) {
+            goto do_unallocated;
+        }
+        break;
+    case MAP(1, 0x01, 0x03): /* PACDB */
+        if (s->pauth_active) {
+            tcg_rd = cpu_reg(s, rd);
+            gen_helper_pacdb(tcg_rd, cpu_env, tcg_rd, cpu_reg_sp(s, rn));
+        } else if (!dc_isar_feature(aa64_pauth, s)) {
+            goto do_unallocated;
+        }
+        break;
+    case MAP(1, 0x01, 0x04): /* AUTIA */
+        if (s->pauth_active) {
+            tcg_rd = cpu_reg(s, rd);
+            gen_helper_autia(tcg_rd, cpu_env, tcg_rd, cpu_reg_sp(s, rn));
+        } else if (!dc_isar_feature(aa64_pauth, s)) {
+            goto do_unallocated;
+        }
+        break;
+    case MAP(1, 0x01, 0x05): /* AUTIB */
+        if (s->pauth_active) {
+            tcg_rd = cpu_reg(s, rd);
+            gen_helper_autib(tcg_rd, cpu_env, tcg_rd, cpu_reg_sp(s, rn));
+        } else if (!dc_isar_feature(aa64_pauth, s)) {
+            goto do_unallocated;
+        }
+        break;
+    case MAP(1, 0x01, 0x06): /* AUTDA */
+        if (s->pauth_active) {
+            tcg_rd = cpu_reg(s, rd);
+            gen_helper_autda(tcg_rd, cpu_env, tcg_rd, cpu_reg_sp(s, rn));
+        } else if (!dc_isar_feature(aa64_pauth, s)) {
+            goto do_unallocated;
+        }
+        break;
+    case MAP(1, 0x01, 0x07): /* AUTDB */
+        if (s->pauth_active) {
+            tcg_rd = cpu_reg(s, rd);
+            gen_helper_autdb(tcg_rd, cpu_env, tcg_rd, cpu_reg_sp(s, rn));
+        } else if (!dc_isar_feature(aa64_pauth, s)) {
+            goto do_unallocated;
+        }
+        break;
+    case MAP(1, 0x01, 0x08): /* PACIZA */
+        if (!dc_isar_feature(aa64_pauth, s) || rn != 31) {
+            goto do_unallocated;
+        } else if (s->pauth_active) {
+            tcg_rd = cpu_reg(s, rd);
+            gen_helper_pacia(tcg_rd, cpu_env, tcg_rd, new_tmp_a64_zero(s));
+        }
+        break;
+    case MAP(1, 0x01, 0x09): /* PACIZB */
+        if (!dc_isar_feature(aa64_pauth, s) || rn != 31) {
+            goto do_unallocated;
+        } else if (s->pauth_active) {
+            tcg_rd = cpu_reg(s, rd);
+            gen_helper_pacib(tcg_rd, cpu_env, tcg_rd, new_tmp_a64_zero(s));
+        }
+        break;
+    case MAP(1, 0x01, 0x0a): /* PACDZA */
+        if (!dc_isar_feature(aa64_pauth, s) || rn != 31) {
+            goto do_unallocated;
+        } else if (s->pauth_active) {
+            tcg_rd = cpu_reg(s, rd);
+            gen_helper_pacda(tcg_rd, cpu_env, tcg_rd, new_tmp_a64_zero(s));
+        }
+        break;
+    case MAP(1, 0x01, 0x0b): /* PACDZB */
+        if (!dc_isar_feature(aa64_pauth, s) || rn != 31) {
+            goto do_unallocated;
+        } else if (s->pauth_active) {
+            tcg_rd = cpu_reg(s, rd);
+            gen_helper_pacdb(tcg_rd, cpu_env, tcg_rd, new_tmp_a64_zero(s));
+        }
+        break;
+    case MAP(1, 0x01, 0x0c): /* AUTIZA */
+        if (!dc_isar_feature(aa64_pauth, s) || rn != 31) {
+            goto do_unallocated;
+        } else if (s->pauth_active) {
+            tcg_rd = cpu_reg(s, rd);
+            gen_helper_autia(tcg_rd, cpu_env, tcg_rd, new_tmp_a64_zero(s));
+        }
+        break;
+    case MAP(1, 0x01, 0x0d): /* AUTIZB */
+        if (!dc_isar_feature(aa64_pauth, s) || rn != 31) {
+            goto do_unallocated;
+        } else if (s->pauth_active) {
+            tcg_rd = cpu_reg(s, rd);
+            gen_helper_autib(tcg_rd, cpu_env, tcg_rd, new_tmp_a64_zero(s));
+        }
+        break;
+    case MAP(1, 0x01, 0x0e): /* AUTDZA */
+        if (!dc_isar_feature(aa64_pauth, s) || rn != 31) {
+            goto do_unallocated;
+        } else if (s->pauth_active) {
+            tcg_rd = cpu_reg(s, rd);
+            gen_helper_autda(tcg_rd, cpu_env, tcg_rd, new_tmp_a64_zero(s));
+        }
+        break;
+    case MAP(1, 0x01, 0x0f): /* AUTDZB */
+        if (!dc_isar_feature(aa64_pauth, s) || rn != 31) {
+            goto do_unallocated;
+        } else if (s->pauth_active) {
+            tcg_rd = cpu_reg(s, rd);
+            gen_helper_autdb(tcg_rd, cpu_env, tcg_rd, new_tmp_a64_zero(s));
+        }
+        break;
+    case MAP(1, 0x01, 0x10): /* XPACI */
+        if (!dc_isar_feature(aa64_pauth, s) || rn != 31) {
+            goto do_unallocated;
+        } else if (s->pauth_active) {
+            tcg_rd = cpu_reg(s, rd);
+            gen_helper_xpaci(tcg_rd, cpu_env, tcg_rd);
+        }
+        break;
+    case MAP(1, 0x01, 0x11): /* XPACD */
+        if (!dc_isar_feature(aa64_pauth, s) || rn != 31) {
+            goto do_unallocated;
+        } else if (s->pauth_active) {
+            tcg_rd = cpu_reg(s, rd);
+            gen_helper_xpacd(tcg_rd, cpu_env, tcg_rd);
+        }
+        break;
     default:
+    do_unallocated:
         unallocated_encoding(s);
         break;
     }
-- 
2.17.2

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

* [Qemu-devel] [PATCH v2 08/27] target/arm: Decode PAuth within disas_data_proc_2src
  2018-12-14  5:23 [Qemu-devel] [PATCH v2 00/27] target/arm: Implement ARMv8.3-PAuth Richard Henderson
                   ` (6 preceding siblings ...)
  2018-12-14  5:23 ` [Qemu-devel] [PATCH v2 07/27] target/arm: Decode PAuth within disas_data_proc_1src Richard Henderson
@ 2018-12-14  5:23 ` Richard Henderson
  2018-12-14  5:23 ` [Qemu-devel] [PATCH v2 09/27] target/arm: Move helper_exception_return to helper-a64.c Richard Henderson
                   ` (18 subsequent siblings)
  26 siblings, 0 replies; 51+ messages in thread
From: Richard Henderson @ 2018-12-14  5:23 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/translate-a64.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 7ba4c996cf..d034a5edf3 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -4884,6 +4884,13 @@ static void disas_data_proc_2src(DisasContext *s, uint32_t insn)
     case 11: /* RORV */
         handle_shift_reg(s, A64_SHIFT_TYPE_ROR, sf, rm, rn, rd);
         break;
+    case 12: /* PACGA */
+        if (sf == 0 || !dc_isar_feature(aa64_pauth, s)) {
+            goto do_unallocated;
+        }
+        gen_helper_pacga(cpu_reg(s, rd), cpu_env,
+                         cpu_reg(s, rn), cpu_reg_sp(s, rm));
+        break;
     case 16:
     case 17:
     case 18:
@@ -4899,6 +4906,7 @@ static void disas_data_proc_2src(DisasContext *s, uint32_t insn)
         break;
     }
     default:
+    do_unallocated:
         unallocated_encoding(s);
         break;
     }
-- 
2.17.2

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

* [Qemu-devel] [PATCH v2 09/27] target/arm: Move helper_exception_return to helper-a64.c
  2018-12-14  5:23 [Qemu-devel] [PATCH v2 00/27] target/arm: Implement ARMv8.3-PAuth Richard Henderson
                   ` (7 preceding siblings ...)
  2018-12-14  5:23 ` [Qemu-devel] [PATCH v2 08/27] target/arm: Decode PAuth within disas_data_proc_2src Richard Henderson
@ 2018-12-14  5:23 ` Richard Henderson
  2018-12-14  5:23 ` [Qemu-devel] [PATCH v2 10/27] target/arm: Add new_pc argument to helper_exception_return Richard Henderson
                   ` (17 subsequent siblings)
  26 siblings, 0 replies; 51+ messages in thread
From: Richard Henderson @ 2018-12-14  5:23 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell

This function is only used by AArch64.  Code movement only.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/helper-a64.h |   2 +
 target/arm/helper.h     |   1 -
 target/arm/helper-a64.c | 155 ++++++++++++++++++++++++++++++++++++++++
 target/arm/op_helper.c  | 155 ----------------------------------------
 4 files changed, 157 insertions(+), 156 deletions(-)

diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
index 28aa0af69d..55299896c4 100644
--- a/target/arm/helper-a64.h
+++ b/target/arm/helper-a64.h
@@ -86,6 +86,8 @@ DEF_HELPER_2(advsimd_f16tosinth, i32, f16, ptr)
 DEF_HELPER_2(advsimd_f16touinth, i32, f16, ptr)
 DEF_HELPER_2(sqrt_f16, f16, f16, ptr)
 
+DEF_HELPER_1(exception_return, void, env)
+
 DEF_HELPER_FLAGS_3(pacia, TCG_CALL_NO_WG, i64, env, i64, i64)
 DEF_HELPER_FLAGS_3(pacib, TCG_CALL_NO_WG, i64, env, i64, i64)
 DEF_HELPER_FLAGS_3(pacda, TCG_CALL_NO_WG, i64, env, i64, i64)
diff --git a/target/arm/helper.h b/target/arm/helper.h
index 8c9590091b..53a38188c6 100644
--- a/target/arm/helper.h
+++ b/target/arm/helper.h
@@ -79,7 +79,6 @@ DEF_HELPER_2(get_cp_reg64, i64, env, ptr)
 
 DEF_HELPER_3(msr_i_pstate, void, env, i32, i32)
 DEF_HELPER_1(clear_pstate_ss, void, env)
-DEF_HELPER_1(exception_return, void, env)
 
 DEF_HELPER_2(get_r13_banked, i32, env, i32)
 DEF_HELPER_3(set_r13_banked, void, env, i32, i32)
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
index bb64700e10..f70c8d9818 100644
--- a/target/arm/helper-a64.c
+++ b/target/arm/helper-a64.c
@@ -887,6 +887,161 @@ uint32_t HELPER(advsimd_f16touinth)(uint32_t a, void *fpstp)
     return float16_to_uint16(a, fpst);
 }
 
+static int el_from_spsr(uint32_t spsr)
+{
+    /* Return the exception level that this SPSR is requesting a return to,
+     * or -1 if it is invalid (an illegal return)
+     */
+    if (spsr & PSTATE_nRW) {
+        switch (spsr & CPSR_M) {
+        case ARM_CPU_MODE_USR:
+            return 0;
+        case ARM_CPU_MODE_HYP:
+            return 2;
+        case ARM_CPU_MODE_FIQ:
+        case ARM_CPU_MODE_IRQ:
+        case ARM_CPU_MODE_SVC:
+        case ARM_CPU_MODE_ABT:
+        case ARM_CPU_MODE_UND:
+        case ARM_CPU_MODE_SYS:
+            return 1;
+        case ARM_CPU_MODE_MON:
+            /* Returning to Mon from AArch64 is never possible,
+             * so this is an illegal return.
+             */
+        default:
+            return -1;
+        }
+    } else {
+        if (extract32(spsr, 1, 1)) {
+            /* Return with reserved M[1] bit set */
+            return -1;
+        }
+        if (extract32(spsr, 0, 4) == 1) {
+            /* return to EL0 with M[0] bit set */
+            return -1;
+        }
+        return extract32(spsr, 2, 2);
+    }
+}
+
+void HELPER(exception_return)(CPUARMState *env)
+{
+    int cur_el = arm_current_el(env);
+    unsigned int spsr_idx = aarch64_banked_spsr_index(cur_el);
+    uint32_t spsr = env->banked_spsr[spsr_idx];
+    int new_el;
+    bool return_to_aa64 = (spsr & PSTATE_nRW) == 0;
+
+    aarch64_save_sp(env, cur_el);
+
+    arm_clear_exclusive(env);
+
+    /* We must squash the PSTATE.SS bit to zero unless both of the
+     * following hold:
+     *  1. debug exceptions are currently disabled
+     *  2. singlestep will be active in the EL we return to
+     * We check 1 here and 2 after we've done the pstate/cpsr write() to
+     * transition to the EL we're going to.
+     */
+    if (arm_generate_debug_exceptions(env)) {
+        spsr &= ~PSTATE_SS;
+    }
+
+    new_el = el_from_spsr(spsr);
+    if (new_el == -1) {
+        goto illegal_return;
+    }
+    if (new_el > cur_el
+        || (new_el == 2 && !arm_feature(env, ARM_FEATURE_EL2))) {
+        /* Disallow return to an EL which is unimplemented or higher
+         * than the current one.
+         */
+        goto illegal_return;
+    }
+
+    if (new_el != 0 && arm_el_is_aa64(env, new_el) != return_to_aa64) {
+        /* Return to an EL which is configured for a different register width */
+        goto illegal_return;
+    }
+
+    if (new_el == 2 && arm_is_secure_below_el3(env)) {
+        /* Return to the non-existent secure-EL2 */
+        goto illegal_return;
+    }
+
+    if (new_el == 1 && (arm_hcr_el2_eff(env) & HCR_TGE)) {
+        goto illegal_return;
+    }
+
+    qemu_mutex_lock_iothread();
+    arm_call_pre_el_change_hook(arm_env_get_cpu(env));
+    qemu_mutex_unlock_iothread();
+
+    if (!return_to_aa64) {
+        env->aarch64 = 0;
+        /* We do a raw CPSR write because aarch64_sync_64_to_32()
+         * will sort the register banks out for us, and we've already
+         * caught all the bad-mode cases in el_from_spsr().
+         */
+        cpsr_write(env, spsr, ~0, CPSRWriteRaw);
+        if (!arm_singlestep_active(env)) {
+            env->uncached_cpsr &= ~PSTATE_SS;
+        }
+        aarch64_sync_64_to_32(env);
+
+        if (spsr & CPSR_T) {
+            env->regs[15] = env->elr_el[cur_el] & ~0x1;
+        } else {
+            env->regs[15] = env->elr_el[cur_el] & ~0x3;
+        }
+        qemu_log_mask(CPU_LOG_INT, "Exception return from AArch64 EL%d to "
+                      "AArch32 EL%d PC 0x%" PRIx32 "\n",
+                      cur_el, new_el, env->regs[15]);
+    } else {
+        env->aarch64 = 1;
+        pstate_write(env, spsr);
+        if (!arm_singlestep_active(env)) {
+            env->pstate &= ~PSTATE_SS;
+        }
+        aarch64_restore_sp(env, new_el);
+        env->pc = env->elr_el[cur_el];
+        qemu_log_mask(CPU_LOG_INT, "Exception return from AArch64 EL%d to "
+                      "AArch64 EL%d PC 0x%" PRIx64 "\n",
+                      cur_el, new_el, env->pc);
+    }
+    /*
+     * Note that cur_el can never be 0.  If new_el is 0, then
+     * el0_a64 is return_to_aa64, else el0_a64 is ignored.
+     */
+    aarch64_sve_change_el(env, cur_el, new_el, return_to_aa64);
+
+    qemu_mutex_lock_iothread();
+    arm_call_el_change_hook(arm_env_get_cpu(env));
+    qemu_mutex_unlock_iothread();
+
+    return;
+
+illegal_return:
+    /* Illegal return events of various kinds have architecturally
+     * mandated behaviour:
+     * restore NZCV and DAIF from SPSR_ELx
+     * set PSTATE.IL
+     * restore PC from ELR_ELx
+     * no change to exception level, execution state or stack pointer
+     */
+    env->pstate |= PSTATE_IL;
+    env->pc = env->elr_el[cur_el];
+    spsr &= PSTATE_NZCV | PSTATE_DAIF;
+    spsr |= pstate_read(env) & ~(PSTATE_NZCV | PSTATE_DAIF);
+    pstate_write(env, spsr);
+    if (!arm_singlestep_active(env)) {
+        env->pstate &= ~PSTATE_SS;
+    }
+    qemu_log_mask(LOG_GUEST_ERROR, "Illegal exception return at EL%d: "
+                  "resuming execution at 0x%" PRIx64 "\n", cur_el, env->pc);
+}
+
 /*
  * Square Root and Reciprocal square root
  */
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
index ef72361a36..24229981cd 100644
--- a/target/arm/op_helper.c
+++ b/target/arm/op_helper.c
@@ -1014,161 +1014,6 @@ void HELPER(pre_smc)(CPUARMState *env, uint32_t syndrome)
     }
 }
 
-static int el_from_spsr(uint32_t spsr)
-{
-    /* Return the exception level that this SPSR is requesting a return to,
-     * or -1 if it is invalid (an illegal return)
-     */
-    if (spsr & PSTATE_nRW) {
-        switch (spsr & CPSR_M) {
-        case ARM_CPU_MODE_USR:
-            return 0;
-        case ARM_CPU_MODE_HYP:
-            return 2;
-        case ARM_CPU_MODE_FIQ:
-        case ARM_CPU_MODE_IRQ:
-        case ARM_CPU_MODE_SVC:
-        case ARM_CPU_MODE_ABT:
-        case ARM_CPU_MODE_UND:
-        case ARM_CPU_MODE_SYS:
-            return 1;
-        case ARM_CPU_MODE_MON:
-            /* Returning to Mon from AArch64 is never possible,
-             * so this is an illegal return.
-             */
-        default:
-            return -1;
-        }
-    } else {
-        if (extract32(spsr, 1, 1)) {
-            /* Return with reserved M[1] bit set */
-            return -1;
-        }
-        if (extract32(spsr, 0, 4) == 1) {
-            /* return to EL0 with M[0] bit set */
-            return -1;
-        }
-        return extract32(spsr, 2, 2);
-    }
-}
-
-void HELPER(exception_return)(CPUARMState *env)
-{
-    int cur_el = arm_current_el(env);
-    unsigned int spsr_idx = aarch64_banked_spsr_index(cur_el);
-    uint32_t spsr = env->banked_spsr[spsr_idx];
-    int new_el;
-    bool return_to_aa64 = (spsr & PSTATE_nRW) == 0;
-
-    aarch64_save_sp(env, cur_el);
-
-    arm_clear_exclusive(env);
-
-    /* We must squash the PSTATE.SS bit to zero unless both of the
-     * following hold:
-     *  1. debug exceptions are currently disabled
-     *  2. singlestep will be active in the EL we return to
-     * We check 1 here and 2 after we've done the pstate/cpsr write() to
-     * transition to the EL we're going to.
-     */
-    if (arm_generate_debug_exceptions(env)) {
-        spsr &= ~PSTATE_SS;
-    }
-
-    new_el = el_from_spsr(spsr);
-    if (new_el == -1) {
-        goto illegal_return;
-    }
-    if (new_el > cur_el
-        || (new_el == 2 && !arm_feature(env, ARM_FEATURE_EL2))) {
-        /* Disallow return to an EL which is unimplemented or higher
-         * than the current one.
-         */
-        goto illegal_return;
-    }
-
-    if (new_el != 0 && arm_el_is_aa64(env, new_el) != return_to_aa64) {
-        /* Return to an EL which is configured for a different register width */
-        goto illegal_return;
-    }
-
-    if (new_el == 2 && arm_is_secure_below_el3(env)) {
-        /* Return to the non-existent secure-EL2 */
-        goto illegal_return;
-    }
-
-    if (new_el == 1 && (arm_hcr_el2_eff(env) & HCR_TGE)) {
-        goto illegal_return;
-    }
-
-    qemu_mutex_lock_iothread();
-    arm_call_pre_el_change_hook(arm_env_get_cpu(env));
-    qemu_mutex_unlock_iothread();
-
-    if (!return_to_aa64) {
-        env->aarch64 = 0;
-        /* We do a raw CPSR write because aarch64_sync_64_to_32()
-         * will sort the register banks out for us, and we've already
-         * caught all the bad-mode cases in el_from_spsr().
-         */
-        cpsr_write(env, spsr, ~0, CPSRWriteRaw);
-        if (!arm_singlestep_active(env)) {
-            env->uncached_cpsr &= ~PSTATE_SS;
-        }
-        aarch64_sync_64_to_32(env);
-
-        if (spsr & CPSR_T) {
-            env->regs[15] = env->elr_el[cur_el] & ~0x1;
-        } else {
-            env->regs[15] = env->elr_el[cur_el] & ~0x3;
-        }
-        qemu_log_mask(CPU_LOG_INT, "Exception return from AArch64 EL%d to "
-                      "AArch32 EL%d PC 0x%" PRIx32 "\n",
-                      cur_el, new_el, env->regs[15]);
-    } else {
-        env->aarch64 = 1;
-        pstate_write(env, spsr);
-        if (!arm_singlestep_active(env)) {
-            env->pstate &= ~PSTATE_SS;
-        }
-        aarch64_restore_sp(env, new_el);
-        env->pc = env->elr_el[cur_el];
-        qemu_log_mask(CPU_LOG_INT, "Exception return from AArch64 EL%d to "
-                      "AArch64 EL%d PC 0x%" PRIx64 "\n",
-                      cur_el, new_el, env->pc);
-    }
-    /*
-     * Note that cur_el can never be 0.  If new_el is 0, then
-     * el0_a64 is return_to_aa64, else el0_a64 is ignored.
-     */
-    aarch64_sve_change_el(env, cur_el, new_el, return_to_aa64);
-
-    qemu_mutex_lock_iothread();
-    arm_call_el_change_hook(arm_env_get_cpu(env));
-    qemu_mutex_unlock_iothread();
-
-    return;
-
-illegal_return:
-    /* Illegal return events of various kinds have architecturally
-     * mandated behaviour:
-     * restore NZCV and DAIF from SPSR_ELx
-     * set PSTATE.IL
-     * restore PC from ELR_ELx
-     * no change to exception level, execution state or stack pointer
-     */
-    env->pstate |= PSTATE_IL;
-    env->pc = env->elr_el[cur_el];
-    spsr &= PSTATE_NZCV | PSTATE_DAIF;
-    spsr |= pstate_read(env) & ~(PSTATE_NZCV | PSTATE_DAIF);
-    pstate_write(env, spsr);
-    if (!arm_singlestep_active(env)) {
-        env->pstate &= ~PSTATE_SS;
-    }
-    qemu_log_mask(LOG_GUEST_ERROR, "Illegal exception return at EL%d: "
-                  "resuming execution at 0x%" PRIx64 "\n", cur_el, env->pc);
-}
-
 /* Return true if the linked breakpoint entry lbn passes its checks */
 static bool linked_bp_matches(ARMCPU *cpu, int lbn)
 {
-- 
2.17.2

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

* [Qemu-devel] [PATCH v2 10/27] target/arm: Add new_pc argument to helper_exception_return
  2018-12-14  5:23 [Qemu-devel] [PATCH v2 00/27] target/arm: Implement ARMv8.3-PAuth Richard Henderson
                   ` (8 preceding siblings ...)
  2018-12-14  5:23 ` [Qemu-devel] [PATCH v2 09/27] target/arm: Move helper_exception_return to helper-a64.c Richard Henderson
@ 2018-12-14  5:23 ` Richard Henderson
  2018-12-14  5:23 ` [Qemu-devel] [PATCH v2 11/27] target/arm: Rearrange decode in disas_uncond_b_reg Richard Henderson
                   ` (16 subsequent siblings)
  26 siblings, 0 replies; 51+ messages in thread
From: Richard Henderson @ 2018-12-14  5:23 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/helper-a64.h    |  2 +-
 target/arm/helper-a64.c    | 10 +++++-----
 target/arm/translate-a64.c |  7 ++++++-
 3 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
index 55299896c4..aff8d6c9f3 100644
--- a/target/arm/helper-a64.h
+++ b/target/arm/helper-a64.h
@@ -86,7 +86,7 @@ DEF_HELPER_2(advsimd_f16tosinth, i32, f16, ptr)
 DEF_HELPER_2(advsimd_f16touinth, i32, f16, ptr)
 DEF_HELPER_2(sqrt_f16, f16, f16, ptr)
 
-DEF_HELPER_1(exception_return, void, env)
+DEF_HELPER_2(exception_return, void, env, i64)
 
 DEF_HELPER_FLAGS_3(pacia, TCG_CALL_NO_WG, i64, env, i64, i64)
 DEF_HELPER_FLAGS_3(pacib, TCG_CALL_NO_WG, i64, env, i64, i64)
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
index f70c8d9818..79cc9cf47b 100644
--- a/target/arm/helper-a64.c
+++ b/target/arm/helper-a64.c
@@ -925,7 +925,7 @@ static int el_from_spsr(uint32_t spsr)
     }
 }
 
-void HELPER(exception_return)(CPUARMState *env)
+void HELPER(exception_return)(CPUARMState *env, uint64_t new_pc)
 {
     int cur_el = arm_current_el(env);
     unsigned int spsr_idx = aarch64_banked_spsr_index(cur_el);
@@ -991,9 +991,9 @@ void HELPER(exception_return)(CPUARMState *env)
         aarch64_sync_64_to_32(env);
 
         if (spsr & CPSR_T) {
-            env->regs[15] = env->elr_el[cur_el] & ~0x1;
+            env->regs[15] = new_pc & ~0x1;
         } else {
-            env->regs[15] = env->elr_el[cur_el] & ~0x3;
+            env->regs[15] = new_pc & ~0x3;
         }
         qemu_log_mask(CPU_LOG_INT, "Exception return from AArch64 EL%d to "
                       "AArch32 EL%d PC 0x%" PRIx32 "\n",
@@ -1005,7 +1005,7 @@ void HELPER(exception_return)(CPUARMState *env)
             env->pstate &= ~PSTATE_SS;
         }
         aarch64_restore_sp(env, new_el);
-        env->pc = env->elr_el[cur_el];
+        env->pc = new_pc;
         qemu_log_mask(CPU_LOG_INT, "Exception return from AArch64 EL%d to "
                       "AArch64 EL%d PC 0x%" PRIx64 "\n",
                       cur_el, new_el, env->pc);
@@ -1031,7 +1031,7 @@ illegal_return:
      * no change to exception level, execution state or stack pointer
      */
     env->pstate |= PSTATE_IL;
-    env->pc = env->elr_el[cur_el];
+    env->pc = new_pc;
     spsr &= PSTATE_NZCV | PSTATE_DAIF;
     spsr |= pstate_read(env) & ~(PSTATE_NZCV | PSTATE_DAIF);
     pstate_write(env, spsr);
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index d034a5edf3..c84c2dbb66 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -1981,6 +1981,7 @@ static void disas_exc(DisasContext *s, uint32_t insn)
 static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
 {
     unsigned int opc, op2, op3, rn, op4;
+    TCGv_i64 dst;
 
     opc = extract32(insn, 21, 4);
     op2 = extract32(insn, 16, 5);
@@ -2011,7 +2012,11 @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
         if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
             gen_io_start();
         }
-        gen_helper_exception_return(cpu_env);
+        dst = tcg_temp_new_i64();
+        tcg_gen_ld_i64(dst, cpu_env,
+                       offsetof(CPUARMState, elr_el[s->current_el]));
+        gen_helper_exception_return(cpu_env, dst);
+        tcg_temp_free_i64(dst);
         if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
             gen_io_end();
         }
-- 
2.17.2

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

* [Qemu-devel] [PATCH v2 11/27] target/arm: Rearrange decode in disas_uncond_b_reg
  2018-12-14  5:23 [Qemu-devel] [PATCH v2 00/27] target/arm: Implement ARMv8.3-PAuth Richard Henderson
                   ` (9 preceding siblings ...)
  2018-12-14  5:23 ` [Qemu-devel] [PATCH v2 10/27] target/arm: Add new_pc argument to helper_exception_return Richard Henderson
@ 2018-12-14  5:23 ` Richard Henderson
  2019-01-04 17:05   ` Peter Maydell
  2018-12-14  5:23 ` [Qemu-devel] [PATCH v2 12/27] target/arm: Decode PAuth within disas_uncond_b_reg Richard Henderson
                   ` (15 subsequent siblings)
  26 siblings, 1 reply; 51+ messages in thread
From: Richard Henderson @ 2018-12-14  5:23 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell

This will enable PAuth decode in a subsequent patch.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/translate-a64.c | 47 +++++++++++++++++++++++++++++---------
 1 file changed, 36 insertions(+), 11 deletions(-)

diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index c84c2dbb66..30086a5d7f 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -1989,32 +1989,54 @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
     rn = extract32(insn, 5, 5);
     op4 = extract32(insn, 0, 5);
 
-    if (op4 != 0x0 || op3 != 0x0 || op2 != 0x1f) {
-        unallocated_encoding(s);
-        return;
+    if (op2 != 0x1f) {
+        goto do_unallocated;
     }
 
     switch (opc) {
     case 0: /* BR */
     case 1: /* BLR */
     case 2: /* RET */
-        gen_a64_set_pc(s, cpu_reg(s, rn));
+        switch (op3) {
+        case 0:
+            if (op4 != 0) {
+                goto do_unallocated;
+            }
+            dst = cpu_reg(s, rn);
+            break;
+
+        default:
+            goto do_unallocated;
+        }
+
+        gen_a64_set_pc(s, dst);
         /* BLR also needs to load return address */
         if (opc == 1) {
             tcg_gen_movi_i64(cpu_reg(s, 30), s->pc);
         }
         break;
+
     case 4: /* ERET */
         if (s->current_el == 0) {
-            unallocated_encoding(s);
-            return;
+            goto do_unallocated;
+        }
+        switch (op3) {
+        case 0:
+            if (op4 != 0) {
+                goto do_unallocated;
+            }
+            dst = tcg_temp_new_i64();
+            tcg_gen_ld_i64(dst, cpu_env,
+                           offsetof(CPUARMState, elr_el[s->current_el]));
+            break;
+
+        default:
+            goto do_unallocated;
         }
         if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
             gen_io_start();
         }
-        dst = tcg_temp_new_i64();
-        tcg_gen_ld_i64(dst, cpu_env,
-                       offsetof(CPUARMState, elr_el[s->current_el]));
+
         gen_helper_exception_return(cpu_env, dst);
         tcg_temp_free_i64(dst);
         if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
@@ -2023,14 +2045,17 @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
         /* Must exit loop to check un-masked IRQs */
         s->base.is_jmp = DISAS_EXIT;
         return;
+
     case 5: /* DRPS */
-        if (rn != 0x1f) {
-            unallocated_encoding(s);
+        if (op3 != 0 || op4 != 0 || rn != 0x1f) {
+            goto do_unallocated;
         } else {
             unsupported_encoding(s, insn);
         }
         return;
+
     default:
+    do_unallocated:
         unallocated_encoding(s);
         return;
     }
-- 
2.17.2

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

* [Qemu-devel] [PATCH v2 12/27] target/arm: Decode PAuth within disas_uncond_b_reg
  2018-12-14  5:23 [Qemu-devel] [PATCH v2 00/27] target/arm: Implement ARMv8.3-PAuth Richard Henderson
                   ` (10 preceding siblings ...)
  2018-12-14  5:23 ` [Qemu-devel] [PATCH v2 11/27] target/arm: Rearrange decode in disas_uncond_b_reg Richard Henderson
@ 2018-12-14  5:23 ` Richard Henderson
  2019-01-04 17:12   ` Peter Maydell
  2018-12-14  5:23 ` [Qemu-devel] [PATCH v2 13/27] target/arm: Decode Load/store register (pac) Richard Henderson
                   ` (14 subsequent siblings)
  26 siblings, 1 reply; 51+ messages in thread
From: Richard Henderson @ 2018-12-14  5:23 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell

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

diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 30086a5d7f..e62d248894 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -1982,6 +1982,7 @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
 {
     unsigned int opc, op2, op3, rn, op4;
     TCGv_i64 dst;
+    TCGv_i64 modifier;
 
     opc = extract32(insn, 21, 4);
     op2 = extract32(insn, 16, 5);
@@ -1999,12 +2000,44 @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
     case 2: /* RET */
         switch (op3) {
         case 0:
+            /* BR, BLR, RET */
             if (op4 != 0) {
                 goto do_unallocated;
             }
             dst = cpu_reg(s, rn);
             break;
 
+        case 2:
+        case 3:
+            if (!dc_isar_feature(aa64_pauth, s)) {
+                goto do_unallocated;
+            }
+            if (opc == 2) {
+                /* RETAA, RETAB */
+                if (rn != 0x1f || op4 != 0x1f) {
+                    goto do_unallocated;
+                }
+                rn = 30;
+                modifier = cpu_X[31];
+            } else {
+                /* BRAAZ, BRABZ, BLRAAZ, BLRABZ */
+                if (op4 != 0x1f) {
+                    goto do_unallocated;
+                }
+                modifier = new_tmp_a64_zero(s);
+            }
+            if (s->pauth_active) {
+                dst = new_tmp_a64(s);
+                if (op3 == 2) {
+                    gen_helper_autia(dst, cpu_env, cpu_reg(s, rn), modifier);
+                } else {
+                    gen_helper_autib(dst, cpu_env, cpu_reg(s, rn), modifier);
+                }
+            } else {
+                dst = cpu_reg(s, rn);
+            }
+            break;
+
         default:
             goto do_unallocated;
         }
@@ -2016,12 +2049,38 @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
         }
         break;
 
+    case 8: /* BRAA */
+    case 9: /* BLRAA */
+        if (!dc_isar_feature(aa64_pauth, s)) {
+            goto do_unallocated;
+        }
+        if (op3 != 2 || op3 != 3) {
+            goto do_unallocated;
+        }
+        if (s->pauth_active) {
+            dst = new_tmp_a64(s);
+            modifier = cpu_reg_sp(s, op4);
+            if (op3 == 2) {
+                gen_helper_autia(dst, cpu_env, cpu_reg(s, rn), modifier);
+            } else {
+                gen_helper_autib(dst, cpu_env, cpu_reg(s, rn), modifier);
+            }
+        } else {
+            dst = cpu_reg(s, rn);
+        }
+        gen_a64_set_pc(s, dst);
+        /* BLRAA also needs to load return address */
+        if (opc == 9) {
+            tcg_gen_movi_i64(cpu_reg(s, 30), s->pc);
+        }
+        break;
+
     case 4: /* ERET */
         if (s->current_el == 0) {
             goto do_unallocated;
         }
         switch (op3) {
-        case 0:
+        case 0: /* ERET */
             if (op4 != 0) {
                 goto do_unallocated;
             }
@@ -2030,6 +2089,27 @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
                            offsetof(CPUARMState, elr_el[s->current_el]));
             break;
 
+        case 2: /* ERETAA */
+        case 3: /* ERETAB */
+            if (!dc_isar_feature(aa64_pauth, s)) {
+                goto do_unallocated;
+            }
+            if (rn != 0x1f || op4 != 0x1f) {
+                goto do_unallocated;
+            }
+            dst = tcg_temp_new_i64();
+            tcg_gen_ld_i64(dst, cpu_env,
+                           offsetof(CPUARMState, elr_el[s->current_el]));
+            if (s->pauth_active) {
+                modifier = cpu_X[31];
+                if (op3 == 2) {
+                    gen_helper_autia(dst, cpu_env, dst, modifier);
+                } else {
+                    gen_helper_autib(dst, cpu_env, dst, modifier);
+                }
+            }
+            break;
+
         default:
             goto do_unallocated;
         }
-- 
2.17.2

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

* [Qemu-devel] [PATCH v2 13/27] target/arm: Decode Load/store register (pac)
  2018-12-14  5:23 [Qemu-devel] [PATCH v2 00/27] target/arm: Implement ARMv8.3-PAuth Richard Henderson
                   ` (11 preceding siblings ...)
  2018-12-14  5:23 ` [Qemu-devel] [PATCH v2 12/27] target/arm: Decode PAuth within disas_uncond_b_reg Richard Henderson
@ 2018-12-14  5:23 ` Richard Henderson
  2019-01-04 18:52   ` Peter Maydell
  2018-12-14  5:23 ` [Qemu-devel] [PATCH v2 14/27] target/arm: Move cpu_mmu_index out of line Richard Henderson
                   ` (13 subsequent siblings)
  26 siblings, 1 reply; 51+ messages in thread
From: Richard Henderson @ 2018-12-14  5:23 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell

Not that there are any stores involved, but why argue with ARM's
naming convention.

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

diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index e62d248894..c57c89d98a 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -3146,6 +3146,65 @@ static void disas_ldst_atomic(DisasContext *s, uint32_t insn,
        s->be_data | size | MO_ALIGN);
 }
 
+/* PAC memory operations
+ *
+ *  31  30      27  26    24    22  21       12  11  10    5     0
+ * +------+-------+---+-----+-----+---+--------+---+---+----+-----+
+ * | size | 1 1 1 | V | 0 0 | M S | 1 |  imm9  | W | 1 | Rn |  Rt |
+ * +------+-------+---+-----+-----+------------+---+---+----+-----+
+ *
+ * Rt: the result register
+ * Rn: base address or SP
+ * Rs: the source register for the operation
+ * V: vector flag (always 0 as of v8.3)
+ * M: clear for key DA, set for key DB
+ * W: pre-indexing flag
+ * S: sign for imm9.
+ */
+static void disas_ldst_pac(DisasContext *s, uint32_t insn,
+                           int size, int rt, bool is_vector)
+{
+    int rn = extract32(insn, 5, 5);
+    bool is_wback = extract32(insn, 11, 1);
+    bool use_key_a = !extract32(insn, 23, 1);
+    int offset, memidx;
+    TCGv_i64 tcg_addr, tcg_rt;
+
+    if (size != 3 || is_vector || !dc_isar_feature(aa64_pauth, s)) {
+        unallocated_encoding(s);
+        return;
+    }
+
+    if (rn == 31) {
+        gen_check_sp_alignment(s);
+    }
+    tcg_addr = read_cpu_reg_sp(s, rn, 1);
+
+    if (s->pauth_active) {
+        if (use_key_a) {
+            gen_helper_autda(tcg_addr, cpu_env, tcg_addr, cpu_X[31]);
+        } else {
+            gen_helper_autdb(tcg_addr, cpu_env, tcg_addr, cpu_X[31]);
+        }
+    }
+
+    /* Form the 10-bit signed, scaled offset.  */
+    offset = (extract32(insn, 22, 1) << 9) | extract32(insn, 12, 9);
+    offset = sextract32(offset << size, 10 + size, 0);
+    tcg_gen_addi_i64(tcg_addr, tcg_addr, offset);
+
+    tcg_rt = cpu_reg(s, rt);
+    memidx = get_mem_index(s);
+    do_gpr_ld_memidx(s, tcg_rt, tcg_addr, size,
+                     /* is_signed */ false, /* extend */ false, memidx,
+                     /* iss_valid */ true, /* iss_srt */ rt,
+                     /* iss_sf */ true, /* iss_ar */ false);
+
+    if (is_wback) {
+        tcg_gen_mov_i64(cpu_reg_sp(s, rn), tcg_addr);
+    }
+}
+
 /* Load/store register (all forms) */
 static void disas_ldst_reg(DisasContext *s, uint32_t insn)
 {
@@ -3171,6 +3230,9 @@ static void disas_ldst_reg(DisasContext *s, uint32_t insn)
         case 2:
             disas_ldst_reg_roffset(s, insn, opc, size, rt, is_vector);
             return;
+        default:
+            disas_ldst_pac(s, insn, size, rt, is_vector);
+            return;
         }
         break;
     case 1:
-- 
2.17.2

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

* [Qemu-devel] [PATCH v2 14/27] target/arm: Move cpu_mmu_index out of line
  2018-12-14  5:23 [Qemu-devel] [PATCH v2 00/27] target/arm: Implement ARMv8.3-PAuth Richard Henderson
                   ` (12 preceding siblings ...)
  2018-12-14  5:23 ` [Qemu-devel] [PATCH v2 13/27] target/arm: Decode Load/store register (pac) Richard Henderson
@ 2018-12-14  5:23 ` Richard Henderson
  2018-12-14  5:23 ` [Qemu-devel] [PATCH v2 15/27] target/arm: Introduce arm_mmu_idx Richard Henderson
                   ` (12 subsequent siblings)
  26 siblings, 0 replies; 51+ messages in thread
From: Richard Henderson @ 2018-12-14  5:23 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell

This function is, or will shortly become, too big to inline.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/cpu.h    | 48 +++++----------------------------------------
 target/arm/helper.c | 44 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 49 insertions(+), 43 deletions(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 898243c93e..6435997111 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -2739,54 +2739,16 @@ static inline int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx)
 }
 
 /* Return the MMU index for a v7M CPU in the specified security and
- * privilege state
+ * privilege state.
  */
-static inline ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
-                                                              bool secstate,
-                                                              bool priv)
-{
-    ARMMMUIdx mmu_idx = ARM_MMU_IDX_M;
-
-    if (priv) {
-        mmu_idx |= ARM_MMU_IDX_M_PRIV;
-    }
-
-    if (armv7m_nvic_neg_prio_requested(env->nvic, secstate)) {
-        mmu_idx |= ARM_MMU_IDX_M_NEGPRI;
-    }
-
-    if (secstate) {
-        mmu_idx |= ARM_MMU_IDX_M_S;
-    }
-
-    return mmu_idx;
-}
+ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
+                                                bool secstate, bool priv);
 
 /* Return the MMU index for a v7M CPU in the specified security state */
-static inline ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env,
-                                                     bool secstate)
-{
-    bool priv = arm_current_el(env) != 0;
-
-    return arm_v7m_mmu_idx_for_secstate_and_priv(env, secstate, priv);
-}
+ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate);
 
 /* Determine the current mmu_idx to use for normal loads/stores */
-static inline int cpu_mmu_index(CPUARMState *env, bool ifetch)
-{
-    int el = arm_current_el(env);
-
-    if (arm_feature(env, ARM_FEATURE_M)) {
-        ARMMMUIdx mmu_idx = arm_v7m_mmu_idx_for_secstate(env, env->v7m.secure);
-
-        return arm_to_core_mmu_idx(mmu_idx);
-    }
-
-    if (el < 2 && arm_is_secure_below_el3(env)) {
-        return arm_to_core_mmu_idx(ARMMMUIdx_S1SE0 + el);
-    }
-    return el;
-}
+int cpu_mmu_index(CPUARMState *env, bool ifetch);
 
 /* Indexes used when registering address spaces with cpu_address_space_init */
 typedef enum ARMASIdx {
diff --git a/target/arm/helper.c b/target/arm/helper.c
index bd0cff5c27..56960411e3 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -12949,6 +12949,50 @@ int fp_exception_el(CPUARMState *env, int cur_el)
     return 0;
 }
 
+ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
+                                                bool secstate, bool priv)
+{
+    ARMMMUIdx mmu_idx = ARM_MMU_IDX_M;
+
+    if (priv) {
+        mmu_idx |= ARM_MMU_IDX_M_PRIV;
+    }
+
+    if (armv7m_nvic_neg_prio_requested(env->nvic, secstate)) {
+        mmu_idx |= ARM_MMU_IDX_M_NEGPRI;
+    }
+
+    if (secstate) {
+        mmu_idx |= ARM_MMU_IDX_M_S;
+    }
+
+    return mmu_idx;
+}
+
+/* Return the MMU index for a v7M CPU in the specified security state */
+ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate)
+{
+    bool priv = arm_current_el(env) != 0;
+
+    return arm_v7m_mmu_idx_for_secstate_and_priv(env, secstate, priv);
+}
+
+int cpu_mmu_index(CPUARMState *env, bool ifetch)
+{
+    int el = arm_current_el(env);
+
+    if (arm_feature(env, ARM_FEATURE_M)) {
+        ARMMMUIdx mmu_idx = arm_v7m_mmu_idx_for_secstate(env, env->v7m.secure);
+
+        return arm_to_core_mmu_idx(mmu_idx);
+    }
+
+    if (el < 2 && arm_is_secure_below_el3(env)) {
+        return arm_to_core_mmu_idx(ARMMMUIdx_S1SE0 + el);
+    }
+    return el;
+}
+
 void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
                           target_ulong *cs_base, uint32_t *pflags)
 {
-- 
2.17.2

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

* [Qemu-devel] [PATCH v2 15/27] target/arm: Introduce arm_mmu_idx
  2018-12-14  5:23 [Qemu-devel] [PATCH v2 00/27] target/arm: Implement ARMv8.3-PAuth Richard Henderson
                   ` (13 preceding siblings ...)
  2018-12-14  5:23 ` [Qemu-devel] [PATCH v2 14/27] target/arm: Move cpu_mmu_index out of line Richard Henderson
@ 2018-12-14  5:23 ` Richard Henderson
  2018-12-14  5:23 ` [Qemu-devel] [PATCH v2 16/27] target/arm: Introduce arm_stage1_mmu_idx Richard Henderson
                   ` (11 subsequent siblings)
  26 siblings, 0 replies; 51+ messages in thread
From: Richard Henderson @ 2018-12-14  5:23 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell

The pattern

  ARMMMUIdx mmu_idx = core_to_arm_mmu_idx(env, cpu_mmu_index(env, false));

is computing the full ARMMMUIdx, stripping off the ARM bits,
and then putting them back.

Avoid the extra two steps with the appropriate helper function.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
----
v2: Move arm_mmu_idx declaration to internals.h.
---
 target/arm/cpu.h       |  9 ++++++++-
 target/arm/internals.h |  8 ++++++++
 target/arm/helper.c    | 27 ++++++++++++++++-----------
 3 files changed, 32 insertions(+), 12 deletions(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 6435997111..3cc7a069ce 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -2747,7 +2747,14 @@ ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
 /* Return the MMU index for a v7M CPU in the specified security state */
 ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate);
 
-/* Determine the current mmu_idx to use for normal loads/stores */
+/**
+ * cpu_mmu_index:
+ * @env: The cpu environment
+ * @ifetch: True for code access, false for data access.
+ *
+ * Return the core mmu index for the current translation regime.
+ * This function is used by generic TCG code paths.
+ */
 int cpu_mmu_index(CPUARMState *env, bool ifetch);
 
 /* Indexes used when registering address spaces with cpu_address_space_init */
diff --git a/target/arm/internals.h b/target/arm/internals.h
index 6bc0daf560..4a52fe58b6 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -912,4 +912,12 @@ void arm_cpu_update_virq(ARMCPU *cpu);
  */
 void arm_cpu_update_vfiq(ARMCPU *cpu);
 
+/**
+ * arm_mmu_idx:
+ * @env: The cpu environment
+ *
+ * Return the full ARMMMUIdx for the current translation regime.
+ */
+ARMMMUIdx arm_mmu_idx(CPUARMState *env);
+
 #endif
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 56960411e3..50c1db16dd 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -7117,7 +7117,7 @@ static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
             limit = env->v7m.msplim[M_REG_S];
         }
     } else {
-        mmu_idx = core_to_arm_mmu_idx(env, cpu_mmu_index(env, false));
+        mmu_idx = arm_mmu_idx(env);
         frame_sp_p = &env->regs[13];
         limit = v7m_sp_limit(env);
     }
@@ -7298,7 +7298,7 @@ static bool v7m_push_stack(ARMCPU *cpu)
     CPUARMState *env = &cpu->env;
     uint32_t xpsr = xpsr_read(env);
     uint32_t frameptr = env->regs[13];
-    ARMMMUIdx mmu_idx = core_to_arm_mmu_idx(env, cpu_mmu_index(env, false));
+    ARMMMUIdx mmu_idx = arm_mmu_idx(env);
 
     /* Align stack pointer if the guest wants that */
     if ((frameptr & 4) &&
@@ -11073,7 +11073,7 @@ hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
     int prot;
     bool ret;
     ARMMMUFaultInfo fi = {};
-    ARMMMUIdx mmu_idx = core_to_arm_mmu_idx(env, cpu_mmu_index(env, false));
+    ARMMMUIdx mmu_idx = arm_mmu_idx(env);
 
     *attrs = (MemTxAttrs) {};
 
@@ -12977,26 +12977,31 @@ ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate)
     return arm_v7m_mmu_idx_for_secstate_and_priv(env, secstate, priv);
 }
 
-int cpu_mmu_index(CPUARMState *env, bool ifetch)
+ARMMMUIdx arm_mmu_idx(CPUARMState *env)
 {
-    int el = arm_current_el(env);
+    int el;
 
     if (arm_feature(env, ARM_FEATURE_M)) {
-        ARMMMUIdx mmu_idx = arm_v7m_mmu_idx_for_secstate(env, env->v7m.secure);
-
-        return arm_to_core_mmu_idx(mmu_idx);
+        return arm_v7m_mmu_idx_for_secstate(env, env->v7m.secure);
     }
 
+    el = arm_current_el(env);
     if (el < 2 && arm_is_secure_below_el3(env)) {
-        return arm_to_core_mmu_idx(ARMMMUIdx_S1SE0 + el);
+        return ARMMMUIdx_S1SE0 + el;
+    } else {
+        return ARMMMUIdx_S12NSE0 + el;
     }
-    return el;
+}
+
+int cpu_mmu_index(CPUARMState *env, bool ifetch)
+{
+    return arm_to_core_mmu_idx(arm_mmu_idx(env));
 }
 
 void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
                           target_ulong *cs_base, uint32_t *pflags)
 {
-    ARMMMUIdx mmu_idx = core_to_arm_mmu_idx(env, cpu_mmu_index(env, false));
+    ARMMMUIdx mmu_idx = arm_mmu_idx(env);
     int current_el = arm_current_el(env);
     int fp_el = fp_exception_el(env, current_el);
     uint32_t flags;
-- 
2.17.2

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

* [Qemu-devel] [PATCH v2 16/27] target/arm: Introduce arm_stage1_mmu_idx
  2018-12-14  5:23 [Qemu-devel] [PATCH v2 00/27] target/arm: Implement ARMv8.3-PAuth Richard Henderson
                   ` (14 preceding siblings ...)
  2018-12-14  5:23 ` [Qemu-devel] [PATCH v2 15/27] target/arm: Introduce arm_mmu_idx Richard Henderson
@ 2018-12-14  5:23 ` Richard Henderson
  2019-01-04 18:58   ` Peter Maydell
  2018-12-14  5:24 ` [Qemu-devel] [PATCH v2 17/27] target/arm: Create ARMVAParameters and helpers Richard Henderson
                   ` (10 subsequent siblings)
  26 siblings, 1 reply; 51+ messages in thread
From: Richard Henderson @ 2018-12-14  5:23 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell

While we could expose stage_1_mmu_idx, the combination is
probably going to be more useful.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/internals.h | 15 +++++++++++++++
 target/arm/helper.c    |  7 +++++++
 2 files changed, 22 insertions(+)

diff --git a/target/arm/internals.h b/target/arm/internals.h
index 4a52fe58b6..1d0d0392c9 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -920,4 +920,19 @@ void arm_cpu_update_vfiq(ARMCPU *cpu);
  */
 ARMMMUIdx arm_mmu_idx(CPUARMState *env);
 
+/**
+ * arm_stage1_mmu_idx:
+ * @env: The cpu environment
+ *
+ * Return the ARMMMUIdx for the stage1 traversal for the current regime.
+ */
+#ifdef CONFIG_USER_ONLY
+static inline ARMMMUIdx arm_stage1_mmu_idx(CPUARMState *env)
+{
+    return ARMMMUIdx_S1NSE0;
+}
+#else
+ARMMMUIdx arm_stage1_mmu_idx(CPUARMState *env);
+#endif
+
 #endif
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 50c1db16dd..b1c0ff923f 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -12998,6 +12998,13 @@ int cpu_mmu_index(CPUARMState *env, bool ifetch)
     return arm_to_core_mmu_idx(arm_mmu_idx(env));
 }
 
+#ifndef CONFIG_USER_ONLY
+ARMMMUIdx arm_stage1_mmu_idx(CPUARMState *env)
+{
+    return stage_1_mmu_idx(arm_mmu_idx(env));
+}
+#endif
+
 void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
                           target_ulong *cs_base, uint32_t *pflags)
 {
-- 
2.17.2

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

* [Qemu-devel] [PATCH v2 17/27] target/arm: Create ARMVAParameters and helpers
  2018-12-14  5:23 [Qemu-devel] [PATCH v2 00/27] target/arm: Implement ARMv8.3-PAuth Richard Henderson
                   ` (15 preceding siblings ...)
  2018-12-14  5:23 ` [Qemu-devel] [PATCH v2 16/27] target/arm: Introduce arm_stage1_mmu_idx Richard Henderson
@ 2018-12-14  5:24 ` Richard Henderson
  2019-01-07 11:40   ` Peter Maydell
  2018-12-14  5:24 ` [Qemu-devel] [PATCH v2 18/27] target/arm: Reuse aa64_va_parameters for setting tbflags Richard Henderson
                   ` (9 subsequent siblings)
  26 siblings, 1 reply; 51+ messages in thread
From: Richard Henderson @ 2018-12-14  5:24 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell

Split out functions to extract the virtual address parameters.
Let the functions choose T0 or T1 address space half, if present.
Extract (most of) the control bits that vary between EL or Tx.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
----
v2: Incorporate feedback wrt VTCR, HTCR, and more.
---
 target/arm/internals.h |  16 +++
 target/arm/helper.c    | 286 +++++++++++++++++++++++------------------
 2 files changed, 174 insertions(+), 128 deletions(-)

diff --git a/target/arm/internals.h b/target/arm/internals.h
index 1d0d0392c9..9ef9d01ee2 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -935,4 +935,20 @@ static inline ARMMMUIdx arm_stage1_mmu_idx(CPUARMState *env)
 ARMMMUIdx arm_stage1_mmu_idx(CPUARMState *env);
 #endif
 
+/*
+ * Parameters of a given virtual address, as extracted from a the
+ * translation control register (TCR) for a given regime.
+ */
+typedef struct ARMVAParameters {
+    unsigned tsz    : 8;
+    unsigned select : 1;
+    bool tbi        : 1;
+    bool epd        : 1;
+    bool hpd        : 1;
+    bool ha         : 1;
+    bool hd         : 1;
+    bool using16k   : 1;
+    bool using64k   : 1;
+} ARMVAParameters;
+
 #endif
diff --git a/target/arm/helper.c b/target/arm/helper.c
index b1c0ff923f..3422fa5943 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -9744,6 +9744,133 @@ static uint8_t convert_stage2_attrs(CPUARMState *env, uint8_t s2attrs)
     return (hiattr << 6) | (hihint << 4) | (loattr << 2) | lohint;
 }
 
+static ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
+                                          ARMMMUIdx mmu_idx, bool data)
+{
+    uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
+    uint32_t el = regime_el(env, mmu_idx);
+    bool tbi, tbid, epd, hpd, ha, hd, using16k, using64k;
+    int select, tsz;
+
+    /* Bit 55 is always between the two regions, and is canonical for
+     * determining if address tagging is enabled.
+     */
+    select = extract64(va, 55, 1);
+
+    if (el > 1) {
+        tsz = extract32(tcr, 0, 6);
+        using64k = extract32(tcr, 14, 1);
+        using16k = extract32(tcr, 15, 1);
+        if (mmu_idx == ARMMMUIdx_S2NS) {
+            /* VTCR_EL2 */
+            tbi = tbid = hpd = false;
+        } else {
+            tbi = extract32(tcr, 20, 1);
+            hpd = extract32(tcr, 24, 1);
+            tbid = extract32(tcr, 29, 1);
+        }
+        ha = extract32(tcr, 21, 1);
+        hd = extract32(tcr, 22, 1);
+        epd = false;
+    } else if (!select) {
+        tsz = extract32(tcr, 0, 6);
+        epd = extract32(tcr, 7, 1);
+        using64k = extract32(tcr, 14, 1);
+        using16k = extract32(tcr, 15, 1);
+        tbi = extract64(tcr, 37, 1);
+        ha = extract64(tcr, 39, 1);
+        hd = extract64(tcr, 40, 1);
+        hpd = extract64(tcr, 41, 1);
+        tbid = extract64(tcr, 51, 1);
+    } else {
+        int tg = extract32(tcr, 30, 2);
+        using16k = tg == 1;
+        using64k = tg == 3;
+        tsz = extract32(tcr, 16, 6);
+        epd = extract32(tcr, 23, 1);
+        tbi = extract64(tcr, 38, 1);
+        ha = extract64(tcr, 39, 1);
+        hd = extract64(tcr, 40, 1);
+        hpd = extract64(tcr, 42, 1);
+        tbid = extract64(tcr, 52, 1);
+    }
+    tsz = MIN(tsz, 39);  /* TODO: ARMv8.4-TTST */
+    tsz = MAX(tsz, 16);  /* TODO: ARMv8.2-LVA  */
+
+    return (ARMVAParameters) {
+        .tsz = tsz,
+        .select = select,
+        .tbi = tbi & (data | !tbid),
+        .epd = epd,
+        .hpd = hpd,
+        .ha = ha,
+        .hd = hd,
+        .using16k = using16k,
+        .using64k = using64k,
+    };
+}
+
+static ARMVAParameters aa32_va_parameters(CPUARMState *env, uint32_t va,
+                                          ARMMMUIdx mmu_idx)
+{
+    uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
+    uint32_t el = regime_el(env, mmu_idx);
+    int select, tsz;
+    bool epd, hpd;
+
+    if (mmu_idx == ARMMMUIdx_S2NS) {
+        /* VTCR */
+        bool sext = extract32(tcr, 4, 1);
+        bool sign = extract32(tcr, 3, 1);
+
+        /* If the sign-extend bit is not the same as t0sz[3], the result
+         * is unpredictable. Flag this as a guest error.
+         */
+        if (sign != sext) {
+            qemu_log_mask(LOG_GUEST_ERROR,
+                          "AArch32: VTCR.S / VTCR.T0SZ[3] mismatch\n");
+        }
+        tsz = sextract32(tcr, 0, 4) + 8;
+        select = 0;
+        hpd = false;
+        epd = false;
+    } else if (el == 2) {
+        /* HTCR */
+        tsz = extract32(tcr, 0, 3);
+        select = 0;
+        hpd = extract64(tcr, 24, 1);
+        epd = false;
+    } else {
+        int t0sz = extract32(tcr, 0, 3);
+        int t1sz = extract32(tcr, 16, 3);
+
+        if (t1sz == 0) {
+            select = va > (0xffffffffu >> t0sz);
+        } else {
+            /* Note that we will detect errors later.  */
+            select = va >= ~(0xffffffffu >> t1sz);
+        }
+        if (!select) {
+            tsz = t0sz;
+            epd = extract32(tcr, 7, 1);
+            hpd = extract64(tcr, 41, 1);
+        } else {
+            tsz = t1sz;
+            epd = extract32(tcr, 23, 1);
+            hpd = extract64(tcr, 42, 1);
+        }
+        /* For aarch32, hpd0 is not enabled without t2e as well.  */
+        hpd &= extract32(tcr, 6, 1);
+    }
+
+    return (ARMVAParameters) {
+        .tsz = tsz,
+        .select = select,
+        .epd = epd,
+        .hpd = hpd,
+    };
+}
+
 static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
                                MMUAccessType access_type, ARMMMUIdx mmu_idx,
                                hwaddr *phys_ptr, MemTxAttrs *txattrs, int *prot,
@@ -9755,26 +9882,20 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
     /* Read an LPAE long-descriptor translation table. */
     ARMFaultType fault_type = ARMFault_Translation;
     uint32_t level;
-    uint32_t epd = 0;
-    int32_t t0sz, t1sz;
-    uint32_t tg;
+    ARMVAParameters param;
     uint64_t ttbr;
-    int ttbr_select;
     hwaddr descaddr, indexmask, indexmask_grainsize;
     uint32_t tableattrs;
-    target_ulong page_size;
+    target_ulong page_size, top_bits;
     uint32_t attrs;
-    int32_t stride = 9;
-    int32_t addrsize;
-    int inputsize;
-    int32_t tbi = 0;
+    int32_t stride;
+    int addrsize, inputsize;
     TCR *tcr = regime_tcr(env, mmu_idx);
     int ap, ns, xn, pxn;
     uint32_t el = regime_el(env, mmu_idx);
-    bool ttbr1_valid = true;
+    bool ttbr1_valid;
     uint64_t descaddrmask;
     bool aarch64 = arm_el_is_aa64(env, el);
-    bool hpd = false;
 
     /* TODO:
      * This code does not handle the different format TCR for VTCR_EL2.
@@ -9783,91 +9904,43 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
      * support for those page table walks.
      */
     if (aarch64) {
+        param = aa64_va_parameters(env, address, mmu_idx,
+                                   access_type != MMU_INST_FETCH);
         level = 0;
-        addrsize = 64;
-        if (el > 1) {
-            if (mmu_idx != ARMMMUIdx_S2NS) {
-                tbi = extract64(tcr->raw_tcr, 20, 1);
-            }
-        } else {
-            if (extract64(address, 55, 1)) {
-                tbi = extract64(tcr->raw_tcr, 38, 1);
-            } else {
-                tbi = extract64(tcr->raw_tcr, 37, 1);
-            }
-        }
-        tbi *= 8;
-
         /* If we are in 64-bit EL2 or EL3 then there is no TTBR1, so mark it
          * invalid.
          */
-        if (el > 1) {
-            ttbr1_valid = false;
-        }
+        ttbr1_valid = (el < 2);
+        addrsize = 64 - 8 * param.tbi;
+        inputsize = 64 - param.tsz;
     } else {
+        param = aa32_va_parameters(env, address, mmu_idx);
         level = 1;
-        addrsize = 32;
         /* There is no TTBR1 for EL2 */
-        if (el == 2) {
-            ttbr1_valid = false;
-        }
+        ttbr1_valid = (el != 2);
+        addrsize = (mmu_idx == ARMMMUIdx_S2NS ? 40 : 32);
+        inputsize = addrsize - param.tsz;
     }
 
-    /* Determine whether this address is in the region controlled by
-     * TTBR0 or TTBR1 (or if it is in neither region and should fault).
-     * This is a Non-secure PL0/1 stage 1 translation, so controlled by
-     * TTBCR/TTBR0/TTBR1 in accordance with ARM ARM DDI0406C table B-32:
+    /* We determined the region when collecting the parameters, but we
+     * have not yet validated that the address is valid for the region.
+     * Extract the top bits and verify that they all match select.
      */
-    if (aarch64) {
-        /* AArch64 translation.  */
-        t0sz = extract32(tcr->raw_tcr, 0, 6);
-        t0sz = MIN(t0sz, 39);
-        t0sz = MAX(t0sz, 16);
-    } else if (mmu_idx != ARMMMUIdx_S2NS) {
-        /* AArch32 stage 1 translation.  */
-        t0sz = extract32(tcr->raw_tcr, 0, 3);
-    } else {
-        /* AArch32 stage 2 translation.  */
-        bool sext = extract32(tcr->raw_tcr, 4, 1);
-        bool sign = extract32(tcr->raw_tcr, 3, 1);
-        /* Address size is 40-bit for a stage 2 translation,
-         * and t0sz can be negative (from -8 to 7),
-         * so we need to adjust it to use the TTBR selecting logic below.
-         */
-        addrsize = 40;
-        t0sz = sextract32(tcr->raw_tcr, 0, 4) + 8;
-
-        /* If the sign-extend bit is not the same as t0sz[3], the result
-         * is unpredictable. Flag this as a guest error.  */
-        if (sign != sext) {
-            qemu_log_mask(LOG_GUEST_ERROR,
-                          "AArch32: VTCR.S / VTCR.T0SZ[3] mismatch\n");
-        }
-    }
-    t1sz = extract32(tcr->raw_tcr, 16, 6);
-    if (aarch64) {
-        t1sz = MIN(t1sz, 39);
-        t1sz = MAX(t1sz, 16);
-    }
-    if (t0sz && !extract64(address, addrsize - t0sz, t0sz - tbi)) {
-        /* there is a ttbr0 region and we are in it (high bits all zero) */
-        ttbr_select = 0;
-    } else if (ttbr1_valid && t1sz &&
-               !extract64(~address, addrsize - t1sz, t1sz - tbi)) {
-        /* there is a ttbr1 region and we are in it (high bits all one) */
-        ttbr_select = 1;
-    } else if (!t0sz) {
-        /* ttbr0 region is "everything not in the ttbr1 region" */
-        ttbr_select = 0;
-    } else if (!t1sz && ttbr1_valid) {
-        /* ttbr1 region is "everything not in the ttbr0 region" */
-        ttbr_select = 1;
-    } else {
-        /* in the gap between the two regions, this is a Translation fault */
+    top_bits = sextract64(address, inputsize, addrsize - inputsize);
+    if (-top_bits != param.select || (param.select && !ttbr1_valid)) {
+        /* In the gap between the two regions, this is a Translation fault */
         fault_type = ARMFault_Translation;
         goto do_fault;
     }
 
+    if (param.using64k) {
+        stride = 13;
+    } else if (param.using16k) {
+        stride = 11;
+    } else {
+        stride = 9;
+    }
+
     /* Note that QEMU ignores shareability and cacheability attributes,
      * so we don't need to do anything with the SH, ORGN, IRGN fields
      * in the TTBCR.  Similarly, TTBCR:A1 selects whether we get the
@@ -9875,56 +9948,13 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
      * implement any ASID-like capability so we can ignore it (instead
      * we will always flush the TLB any time the ASID is changed).
      */
-    if (ttbr_select == 0) {
-        ttbr = regime_ttbr(env, mmu_idx, 0);
-        if (el < 2) {
-            epd = extract32(tcr->raw_tcr, 7, 1);
-        }
-        inputsize = addrsize - t0sz;
-
-        tg = extract32(tcr->raw_tcr, 14, 2);
-        if (tg == 1) { /* 64KB pages */
-            stride = 13;
-        }
-        if (tg == 2) { /* 16KB pages */
-            stride = 11;
-        }
-        if (aarch64 && el > 1) {
-            hpd = extract64(tcr->raw_tcr, 24, 1);
-        } else {
-            hpd = extract64(tcr->raw_tcr, 41, 1);
-        }
-        if (!aarch64) {
-            /* For aarch32, hpd0 is not enabled without t2e as well.  */
-            hpd &= extract64(tcr->raw_tcr, 6, 1);
-        }
-    } else {
-        /* We should only be here if TTBR1 is valid */
-        assert(ttbr1_valid);
-
-        ttbr = regime_ttbr(env, mmu_idx, 1);
-        epd = extract32(tcr->raw_tcr, 23, 1);
-        inputsize = addrsize - t1sz;
-
-        tg = extract32(tcr->raw_tcr, 30, 2);
-        if (tg == 3)  { /* 64KB pages */
-            stride = 13;
-        }
-        if (tg == 1) { /* 16KB pages */
-            stride = 11;
-        }
-        hpd = extract64(tcr->raw_tcr, 42, 1);
-        if (!aarch64) {
-            /* For aarch32, hpd1 is not enabled without t2e as well.  */
-            hpd &= extract64(tcr->raw_tcr, 6, 1);
-        }
-    }
+    ttbr = regime_ttbr(env, mmu_idx, param.select);
 
     /* Here we should have set up all the parameters for the translation:
      * inputsize, ttbr, epd, stride, tbi
      */
 
-    if (epd) {
+    if (param.epd) {
         /* Translation table walk disabled => Translation fault on TLB miss
          * Note: This is always 0 on 64-bit EL2 and EL3.
          */
@@ -10037,7 +10067,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
         }
         /* Merge in attributes from table descriptors */
         attrs |= nstable << 3; /* NS */
-        if (hpd) {
+        if (param.hpd) {
             /* HPD disables all the table attributes except NSTable.  */
             break;
         }
-- 
2.17.2

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

* [Qemu-devel] [PATCH v2 18/27] target/arm: Reuse aa64_va_parameters for setting tbflags
  2018-12-14  5:23 [Qemu-devel] [PATCH v2 00/27] target/arm: Implement ARMv8.3-PAuth Richard Henderson
                   ` (16 preceding siblings ...)
  2018-12-14  5:24 ` [Qemu-devel] [PATCH v2 17/27] target/arm: Create ARMVAParameters and helpers Richard Henderson
@ 2018-12-14  5:24 ` Richard Henderson
  2019-01-07 11:44   ` Peter Maydell
  2018-12-14  5:24 ` [Qemu-devel] [PATCH v2 19/27] target/arm: Export aa64_va_parameters to internals.h Richard Henderson
                   ` (8 subsequent siblings)
  26 siblings, 1 reply; 51+ messages in thread
From: Richard Henderson @ 2018-12-14  5:24 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell

The arm_regime_tbi{0,1} functions are replacable with the new function
by giving the lowest and highest address.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/cpu.h    | 35 --------------------------
 target/arm/helper.c | 61 ++++++++++++---------------------------------
 2 files changed, 16 insertions(+), 80 deletions(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 3cc7a069ce..7c7dbc216c 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -3079,41 +3079,6 @@ static inline bool arm_cpu_bswap_data(CPUARMState *env)
 }
 #endif
 
-#ifndef CONFIG_USER_ONLY
-/**
- * arm_regime_tbi0:
- * @env: CPUARMState
- * @mmu_idx: MMU index indicating required translation regime
- *
- * Extracts the TBI0 value from the appropriate TCR for the current EL
- *
- * Returns: the TBI0 value.
- */
-uint32_t arm_regime_tbi0(CPUARMState *env, ARMMMUIdx mmu_idx);
-
-/**
- * arm_regime_tbi1:
- * @env: CPUARMState
- * @mmu_idx: MMU index indicating required translation regime
- *
- * Extracts the TBI1 value from the appropriate TCR for the current EL
- *
- * Returns: the TBI1 value.
- */
-uint32_t arm_regime_tbi1(CPUARMState *env, ARMMMUIdx mmu_idx);
-#else
-/* We can't handle tagged addresses properly in user-only mode */
-static inline uint32_t arm_regime_tbi0(CPUARMState *env, ARMMMUIdx mmu_idx)
-{
-    return 0;
-}
-
-static inline uint32_t arm_regime_tbi1(CPUARMState *env, ARMMMUIdx mmu_idx)
-{
-    return 0;
-}
-#endif
-
 void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
                           target_ulong *cs_base, uint32_t *flags);
 
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 3422fa5943..bd1b683766 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -8957,48 +8957,6 @@ static inline ARMMMUIdx stage_1_mmu_idx(ARMMMUIdx mmu_idx)
     return mmu_idx;
 }
 
-/* Returns TBI0 value for current regime el */
-uint32_t arm_regime_tbi0(CPUARMState *env, ARMMMUIdx mmu_idx)
-{
-    TCR *tcr;
-    uint32_t el;
-
-    /* For EL0 and EL1, TBI is controlled by stage 1's TCR, so convert
-     * a stage 1+2 mmu index into the appropriate stage 1 mmu index.
-     */
-    mmu_idx = stage_1_mmu_idx(mmu_idx);
-
-    tcr = regime_tcr(env, mmu_idx);
-    el = regime_el(env, mmu_idx);
-
-    if (el > 1) {
-        return extract64(tcr->raw_tcr, 20, 1);
-    } else {
-        return extract64(tcr->raw_tcr, 37, 1);
-    }
-}
-
-/* Returns TBI1 value for current regime el */
-uint32_t arm_regime_tbi1(CPUARMState *env, ARMMMUIdx mmu_idx)
-{
-    TCR *tcr;
-    uint32_t el;
-
-    /* For EL0 and EL1, TBI is controlled by stage 1's TCR, so convert
-     * a stage 1+2 mmu index into the appropriate stage 1 mmu index.
-     */
-    mmu_idx = stage_1_mmu_idx(mmu_idx);
-
-    tcr = regime_tcr(env, mmu_idx);
-    el = regime_el(env, mmu_idx);
-
-    if (el > 1) {
-        return 0;
-    } else {
-        return extract64(tcr->raw_tcr, 38, 1);
-    }
-}
-
 /* Return the TTBR associated with this translation regime */
 static inline uint64_t regime_ttbr(CPUARMState *env, ARMMMUIdx mmu_idx,
                                    int ttbrn)
@@ -13048,9 +13006,22 @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
 
         *pc = env->pc;
         flags = ARM_TBFLAG_AARCH64_STATE_MASK;
-        /* Get control bits for tagged addresses */
-        flags |= (arm_regime_tbi0(env, mmu_idx) << ARM_TBFLAG_TBI0_SHIFT);
-        flags |= (arm_regime_tbi1(env, mmu_idx) << ARM_TBFLAG_TBI1_SHIFT);
+
+#ifndef CONFIG_USER_ONLY
+        /* Get control bits for tagged addresses.  Note that the
+         * translator only uses this for instruction addresses.
+         */
+        {
+            ARMMMUIdx stage1 = stage_1_mmu_idx(mmu_idx);
+            ARMVAParameters p0, p1;
+
+            p0 = aa64_va_parameters(env, 0, stage1, false);
+            p1 = aa64_va_parameters(env, -1, stage1, false);
+
+            flags |= p0.tbi << ARM_TBFLAG_TBI0_SHIFT;
+            flags |= p1.tbi << ARM_TBFLAG_TBI1_SHIFT;
+        }
+#endif
 
         if (cpu_isar_feature(aa64_sve, cpu)) {
             int sve_el = sve_exception_el(env, current_el);
-- 
2.17.2

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

* [Qemu-devel] [PATCH v2 19/27] target/arm: Export aa64_va_parameters to internals.h
  2018-12-14  5:23 [Qemu-devel] [PATCH v2 00/27] target/arm: Implement ARMv8.3-PAuth Richard Henderson
                   ` (17 preceding siblings ...)
  2018-12-14  5:24 ` [Qemu-devel] [PATCH v2 18/27] target/arm: Reuse aa64_va_parameters for setting tbflags Richard Henderson
@ 2018-12-14  5:24 ` Richard Henderson
  2019-01-07 11:45   ` Peter Maydell
  2018-12-14  5:24 ` [Qemu-devel] [PATCH v2 20/27] target/arm: Implement pauth_strip Richard Henderson
                   ` (7 subsequent siblings)
  26 siblings, 1 reply; 51+ messages in thread
From: Richard Henderson @ 2018-12-14  5:24 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell

We need to reuse this from helper-a64.c.  Provide a stub
definition for CONFIG_USER_ONLY.  This matches the stub
definitions that we removed for arm_regime_tbi{0,1} before.

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

diff --git a/target/arm/internals.h b/target/arm/internals.h
index 9ef9d01ee2..4fbef58126 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -951,4 +951,21 @@ typedef struct ARMVAParameters {
     bool using64k   : 1;
 } ARMVAParameters;
 
+#ifdef CONFIG_USER_ONLY
+static inline ARMVAParameters aa64_va_parameters(CPUARMState *env,
+                                                 uint64_t va,
+                                                 ARMMMUIdx mmu_idx, bool data)
+{
+    return (ARMVAParameters) {
+        /* 48-bit address space */
+        .tsz = 16,
+        /* We can't handle tagged addresses properly in user-only mode */
+        .tbi = false,
+    };
+}
+#else
+ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
+                                   ARMMMUIdx mmu_idx, bool data);
+#endif
+
 #endif
diff --git a/target/arm/helper.c b/target/arm/helper.c
index bd1b683766..b9ffc07fbc 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -9702,8 +9702,8 @@ static uint8_t convert_stage2_attrs(CPUARMState *env, uint8_t s2attrs)
     return (hiattr << 6) | (hihint << 4) | (loattr << 2) | lohint;
 }
 
-static ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
-                                          ARMMMUIdx mmu_idx, bool data)
+ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
+                                   ARMMMUIdx mmu_idx, bool data)
 {
     uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
     uint32_t el = regime_el(env, mmu_idx);
-- 
2.17.2

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

* [Qemu-devel] [PATCH v2 20/27] target/arm: Implement pauth_strip
  2018-12-14  5:23 [Qemu-devel] [PATCH v2 00/27] target/arm: Implement ARMv8.3-PAuth Richard Henderson
                   ` (18 preceding siblings ...)
  2018-12-14  5:24 ` [Qemu-devel] [PATCH v2 19/27] target/arm: Export aa64_va_parameters to internals.h Richard Henderson
@ 2018-12-14  5:24 ` Richard Henderson
  2019-01-07 11:52   ` Peter Maydell
  2018-12-14  5:24 ` [Qemu-devel] [PATCH v2 21/27] target/arm: Implement pauth_auth Richard Henderson
                   ` (6 subsequent siblings)
  26 siblings, 1 reply; 51+ messages in thread
From: Richard Henderson @ 2018-12-14  5:24 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell

Stripping out the authentication data does not require any crypto,
it merely requires the virtual address parameters.

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

diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
index 79cc9cf47b..329af51232 100644
--- a/target/arm/helper-a64.c
+++ b/target/arm/helper-a64.c
@@ -1069,6 +1069,15 @@ static uint64_t pauth_addpac(CPUARMState *env, uint64_t ptr, uint64_t modifier,
     g_assert_not_reached(); /* FIXME */
 }
 
+static uint64_t pauth_original_ptr(uint64_t ptr, ARMVAParameters param)
+{
+    uint64_t extfield = -param.select;
+    int bot_pac_bit = 64 - param.tsz;
+    int top_pac_bit = 64 - 8 * param.tbi;
+
+    return deposit64(ptr, bot_pac_bit, top_pac_bit - bot_pac_bit, extfield);
+}
+
 static uint64_t pauth_auth(CPUARMState *env, uint64_t ptr, uint64_t modifier,
                            ARMPACKey *key, bool data, int keynumber)
 {
@@ -1077,7 +1086,10 @@ static uint64_t pauth_auth(CPUARMState *env, uint64_t ptr, uint64_t modifier,
 
 static uint64_t pauth_strip(CPUARMState *env, uint64_t ptr, bool data)
 {
-    g_assert_not_reached(); /* FIXME */
+    ARMMMUIdx mmu_idx = arm_stage1_mmu_idx(env);
+    ARMVAParameters param = aa64_va_parameters(env, ptr, mmu_idx, data);
+
+    return pauth_original_ptr(ptr, param);
 }
 
 static void QEMU_NORETURN pauth_trap(CPUARMState *env, int target_el,
-- 
2.17.2

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

* [Qemu-devel] [PATCH v2 21/27] target/arm: Implement pauth_auth
  2018-12-14  5:23 [Qemu-devel] [PATCH v2 00/27] target/arm: Implement ARMv8.3-PAuth Richard Henderson
                   ` (19 preceding siblings ...)
  2018-12-14  5:24 ` [Qemu-devel] [PATCH v2 20/27] target/arm: Implement pauth_strip Richard Henderson
@ 2018-12-14  5:24 ` Richard Henderson
  2019-01-07 11:58   ` Peter Maydell
  2018-12-14  5:24 ` [Qemu-devel] [PATCH v2 22/27] target/arm: Implement pauth_addpac Richard Henderson
                   ` (5 subsequent siblings)
  26 siblings, 1 reply; 51+ messages in thread
From: Richard Henderson @ 2018-12-14  5:24 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell

This is not really functional yet, because the crypto is not yet
implemented.  This, however follows the Auth pseudo function.

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

diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
index 329af51232..87cff7d96a 100644
--- a/target/arm/helper-a64.c
+++ b/target/arm/helper-a64.c
@@ -1081,7 +1081,26 @@ static uint64_t pauth_original_ptr(uint64_t ptr, ARMVAParameters param)
 static uint64_t pauth_auth(CPUARMState *env, uint64_t ptr, uint64_t modifier,
                            ARMPACKey *key, bool data, int keynumber)
 {
-    g_assert_not_reached(); /* FIXME */
+    ARMMMUIdx mmu_idx = arm_stage1_mmu_idx(env);
+    ARMVAParameters param = aa64_va_parameters(env, ptr, mmu_idx, data);
+    int bot_bit, top_bit;
+    uint64_t pac, orig_ptr, test;
+
+    orig_ptr = pauth_original_ptr(ptr, param);
+    pac = pauth_computepac(orig_ptr, modifier, *key);
+    bot_bit = 64 - param.tsz;
+    top_bit = 64 - 8 * param.tbi;
+
+    test = (pac ^ ptr) & ~MAKE_64BIT_MASK(55, 1);
+    if (unlikely(extract64(test, bot_bit, top_bit - bot_bit))) {
+        int error_code = (keynumber << 1) | (keynumber ^ 1);
+        if (param.tbi) {
+            return deposit64(ptr, 53, 2, error_code);
+        } else {
+            return deposit64(ptr, 61, 2, error_code);
+        }
+    }
+    return orig_ptr;
 }
 
 static uint64_t pauth_strip(CPUARMState *env, uint64_t ptr, bool data)
-- 
2.17.2

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

* [Qemu-devel] [PATCH v2 22/27] target/arm: Implement pauth_addpac
  2018-12-14  5:23 [Qemu-devel] [PATCH v2 00/27] target/arm: Implement ARMv8.3-PAuth Richard Henderson
                   ` (20 preceding siblings ...)
  2018-12-14  5:24 ` [Qemu-devel] [PATCH v2 21/27] target/arm: Implement pauth_auth Richard Henderson
@ 2018-12-14  5:24 ` Richard Henderson
  2019-01-07 13:31   ` Peter Maydell
  2018-12-14  5:24 ` [Qemu-devel] [PATCH v2 23/27] target/arm: Implement pauth_computepac Richard Henderson
                   ` (4 subsequent siblings)
  26 siblings, 1 reply; 51+ messages in thread
From: Richard Henderson @ 2018-12-14  5:24 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell

This is not really functional yet, because the crypto is not yet
implemented.  This, however follows the AddPAC pseudo function.

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

diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
index 87cff7d96a..19486b9677 100644
--- a/target/arm/helper-a64.c
+++ b/target/arm/helper-a64.c
@@ -1066,7 +1066,45 @@ static uint64_t pauth_computepac(uint64_t data, uint64_t modifier,
 static uint64_t pauth_addpac(CPUARMState *env, uint64_t ptr, uint64_t modifier,
                              ARMPACKey *key, bool data)
 {
-    g_assert_not_reached(); /* FIXME */
+    ARMMMUIdx mmu_idx = arm_stage1_mmu_idx(env);
+    ARMVAParameters param = aa64_va_parameters(env, ptr, mmu_idx, data);
+    uint64_t pac, ext_ptr, ext, test;
+    int bot_bit, top_bit;
+
+    /* If tagged pointers are in use, use ptr<55>, otherwise ptr<63>.  */
+    if (param.tbi) {
+        ext = sextract64(ptr, 55, 1);
+    } else {
+        ext = sextract64(ptr, 63, 1);
+    }
+
+    /* Build a pointer with known good extension bits.  */
+    top_bit = 64 - 8 * param.tbi;
+    bot_bit = 64 - param.tsz;
+    ext_ptr = deposit64(ptr, bot_bit, top_bit - bot_bit, ext);
+
+    pac = pauth_computepac(ext_ptr, modifier, *key);
+
+    /* Check if the ptr has good extension bits and corrupt the
+     * pointer authentication code if not.
+     */
+    test = sextract64(ptr, bot_bit, top_bit - bot_bit);
+    if (test != 0 && test != -1) {
+        pac ^= 1ull << (top_bit - 1);
+    }
+
+    /* Preserve the determination between upper and lower at bit 55,
+     * and insert pointer authentication code.
+     */
+    if (param.tbi) {
+        ptr &= ~MAKE_64BIT_MASK(bot_bit, 55 - bot_bit + 1);
+        pac &= MAKE_64BIT_MASK(bot_bit, 54 - bot_bit + 1);
+    } else {
+        ptr &= MAKE_64BIT_MASK(0, bot_bit);
+        pac &= ~(MAKE_64BIT_MASK(55, 1) | MAKE_64BIT_MASK(0, bot_bit));
+    }
+    ext &= MAKE_64BIT_MASK(55, 1);
+    return pac | ext | ptr;
 }
 
 static uint64_t pauth_original_ptr(uint64_t ptr, ARMVAParameters param)
-- 
2.17.2

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

* [Qemu-devel] [PATCH v2 23/27] target/arm: Implement pauth_computepac
  2018-12-14  5:23 [Qemu-devel] [PATCH v2 00/27] target/arm: Implement ARMv8.3-PAuth Richard Henderson
                   ` (21 preceding siblings ...)
  2018-12-14  5:24 ` [Qemu-devel] [PATCH v2 22/27] target/arm: Implement pauth_addpac Richard Henderson
@ 2018-12-14  5:24 ` Richard Henderson
  2019-01-07 14:09   ` Peter Maydell
  2018-12-14  5:24 ` [Qemu-devel] [PATCH v2 24/27] target/arm: Add PAuth system registers Richard Henderson
                   ` (3 subsequent siblings)
  26 siblings, 1 reply; 51+ messages in thread
From: Richard Henderson @ 2018-12-14  5:24 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell

This is the main crypto routine, an implementation of QARMA.
This matches, as much as possible, ARM pseudocode.

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

diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
index 19486b9677..1da7867a42 100644
--- a/target/arm/helper-a64.c
+++ b/target/arm/helper-a64.c
@@ -1057,10 +1057,249 @@ uint32_t HELPER(sqrt_f16)(uint32_t a, void *fpstp)
  * Helpers for ARMv8.3-PAuth.
  */
 
+static uint64_t pac_cell_shuffle(uint64_t i)
+{
+    uint64_t o = 0;
+
+    o |= extract64(i, 52, 4);
+    o |= extract64(i, 24, 4) << 4;
+    o |= extract64(i, 44, 4) << 8;
+    o |= extract64(i,  0, 4) << 12;
+
+    o |= extract64(i, 28, 4) << 16;
+    o |= extract64(i, 48, 4) << 20;
+    o |= extract64(i,  4, 4) << 24;
+    o |= extract64(i, 40, 4) << 28;
+
+    o |= i & MAKE_64BIT_MASK(32, 4);
+    o |= extract64(i, 12, 4) << 36;
+    o |= extract64(i, 56, 4) << 40;
+    o |= extract64(i,  8, 4) << 44;
+
+    o |= extract64(i, 36, 4) << 48;
+    o |= extract64(i, 16, 4) << 52;
+    o |= extract64(i, 40, 4) << 56;
+    o |= i & MAKE_64BIT_MASK(60, 4);
+
+    return o;
+}
+
+static uint64_t pac_cell_inv_shuffle(uint64_t i)
+{
+    uint64_t o = 0;
+
+    o |= extract64(i, 12, 4);
+    o |= extract64(i, 24, 4) << 4;
+    o |= extract64(i, 48, 4) << 8;
+    o |= extract64(i, 36, 4) << 12;
+
+    o |= extract64(i, 56, 4) << 16;
+    o |= extract64(i, 44, 4) << 20;
+    o |= extract64(i,  4, 4) << 24;
+    o |= extract64(i, 16, 4) << 28;
+
+    o |= i & MAKE_64BIT_MASK(32, 4);
+    o |= extract64(i, 52, 4) << 36;
+    o |= extract64(i, 28, 4) << 40;
+    o |= extract64(i,  8, 4) << 44;
+
+    o |= extract64(i, 20, 4) << 48;
+    o |= extract64(i,  0, 4) << 52;
+    o |= extract64(i, 40, 4) << 56;
+    o |= i & MAKE_64BIT_MASK(60, 4);
+
+    return o;
+}
+
+static uint64_t pac_sub(uint64_t i)
+{
+    static const uint8_t sub[16] = {
+        0xb, 0x6, 0x8, 0xf, 0xc, 0x0, 0x9, 0xe,
+        0x3, 0x7, 0x4, 0x5, 0xd, 0x2, 0x1, 0xa,
+    };
+    uint64_t o = 0;
+    int b;
+
+    for (b = 0; b < 64; b += 16) {
+        o |= (uint64_t)sub[(i >> b) & 0xf] << b;
+    }
+    return o;
+}
+
+static uint64_t pac_inv_sub(uint64_t i)
+{
+    static const uint8_t inv_sub[16] = {
+        0x5, 0xe, 0xd, 0x8, 0xa, 0xb, 0x1, 0x9,
+        0x2, 0x6, 0xf, 0x0, 0x4, 0xc, 0x7, 0x3,
+    };
+    uint64_t o = 0;
+    int b;
+
+    for (b = 0; b < 64; b += 16) {
+        o |= (uint64_t)inv_sub[(i >> b) & 0xf] << b;
+    }
+    return o;
+}
+
+static int rot_cell(int cell, int n)
+{
+    cell |= cell << 4;
+    cell >>= n;
+    return cell & 0xf;
+}
+
+static uint64_t pac_mult(uint64_t i)
+{
+    uint64_t o = 0;
+    int b;
+
+    for (b = 0; b < 4 * 4; b += 4) {
+        int i0, i4, i8, ic, t0, t1, t2, t3;
+
+        i0 = extract64(i, b, 4);
+        i4 = extract64(i, b + 4 * 4, 4);
+        i8 = extract64(i, b + 8 * 4, 4);
+        ic = extract64(i, b + 12 * 4, 4);
+
+        t0 = rot_cell(i8, 1) ^ rot_cell(i4, 2) ^ rot_cell(i0, 1);
+        t1 = rot_cell(ic, 1) ^ rot_cell(i4, 1) ^ rot_cell(i0, 2);
+        t2 = rot_cell(ic, 2) ^ rot_cell(i8, 1) ^ rot_cell(i0, 1);
+        t3 = rot_cell(ic, 2) ^ rot_cell(i8, 2) ^ rot_cell(i4, 1);
+
+        o |= (uint64_t)t3 << b;
+        o |= (uint64_t)t2 << (b + 4 * 4);
+        o |= (uint64_t)t1 << (b + 8 * 4);
+        o |= (uint64_t)t0 << (b + 12 * 4);
+    }
+    return o;
+}
+
+static uint64_t tweak_cell_rot(uint64_t cell)
+{
+    return (cell >> 1) | (((cell ^ (cell >> 1)) & 1) << 3);
+}
+
+static uint64_t tweak_shuffle(uint64_t i)
+{
+    uint64_t o = 0;
+
+    o |= extract64(i, 16, 4) << 0;
+    o |= extract64(i, 20, 4) << 4;
+    o |= tweak_cell_rot(extract64(i, 24, 4)) << 8;
+    o |= extract64(i, 28, 4) << 12;
+
+    o |= tweak_cell_rot(extract64(i, 44, 4)) << 16;
+    o |= extract64(i,  8, 4) << 20;
+    o |= extract64(i, 12, 4) << 24;
+    o |= tweak_cell_rot(extract64(i, 32, 4)) << 28;
+
+    o |= extract64(i, 48, 4) << 32;
+    o |= extract64(i, 52, 4) << 36;
+    o |= extract64(i, 56, 4) << 40;
+    o |= tweak_cell_rot(extract64(i, 60, 4)) << 44;
+
+    o |= tweak_cell_rot(extract64(i,  0, 4)) << 48;
+    o |= extract64(i,  4, 4) << 52;
+    o |= tweak_cell_rot(extract64(i, 40, 4)) << 56;
+    o |= tweak_cell_rot(extract64(i, 36, 4)) << 60;
+
+    return o;
+}
+
+static uint64_t tweak_cell_inv_rot(uint64_t cell)
+{
+    return ((cell << 1) & 0xf) | ((cell & 1) ^ (cell >> 3));
+}
+
+static uint64_t tweak_inv_shuffle(uint64_t i)
+{
+    uint64_t o = 0;
+
+    o |= tweak_cell_inv_rot(extract64(i, 48, 4));
+    o |= extract64(i, 52, 4) << 4;
+    o |= extract64(i, 20, 4) << 8;
+    o |= extract64(i, 24, 4) << 12;
+
+    o |= extract64(i,  0, 4) << 16;
+    o |= extract64(i,  4, 4) << 20;
+    o |= tweak_cell_inv_rot(extract64(i,  8, 4)) << 24;
+    o |= extract64(i, 12, 4) << 28;
+
+    o |= tweak_cell_inv_rot(extract64(i, 28, 4)) << 32;
+    o |= tweak_cell_inv_rot(extract64(i, 60, 4)) << 36;
+    o |= tweak_cell_inv_rot(extract64(i, 56, 4)) << 40;
+    o |= tweak_cell_inv_rot(extract64(i, 16, 4)) << 44;
+
+    o |= extract64(i, 32, 4) << 48;
+    o |= extract64(i, 36, 4) << 52;
+    o |= extract64(i, 40, 4) << 56;
+    o |= tweak_cell_inv_rot(extract64(i, 44, 4)) << 60;
+
+    return o;
+}
+
 static uint64_t pauth_computepac(uint64_t data, uint64_t modifier,
                                  ARMPACKey key)
 {
-    g_assert_not_reached(); /* FIXME */
+    static const uint64_t RC[5] = {
+        0x0000000000000000ull,
+        0x13198A2E03707344ull,
+        0xA4093822299F31D0ull,
+        0x082EFA98EC4E6C89ull,
+        0x452821E638D01377ull,
+    };
+    const uint64_t alpha = 0xC0AC29B7C97C50DDull;
+    /* Note that in the ARM pseudocode, key0 contains bits <127:64>
+     * and key1 contains bits <63:0> of the 128-bit key.
+     */
+    uint64_t key0 = key.hi, key1 = key.lo;
+    uint64_t workingval, runningmod, roundkey, modk0;
+    int i;
+
+    modk0 = (key0 << 63) | ((key0 >> 1) ^ (key0 >> 63));
+    runningmod = modifier;
+    workingval = data ^ key0;
+
+    for (i = 0; i <= 4; ++i) {
+        roundkey = key1 ^ runningmod;
+        workingval ^= roundkey;
+        workingval ^= RC[i];
+        if (i > 0) {
+            workingval = pac_cell_shuffle(workingval);
+            workingval = pac_mult(workingval);
+        }
+        workingval = pac_sub(workingval);
+        runningmod = tweak_shuffle(runningmod);
+    }
+    roundkey = modk0 ^ runningmod;
+    workingval ^= roundkey;
+    workingval = pac_cell_shuffle(workingval);
+    workingval = pac_mult(workingval);
+    workingval = pac_sub(workingval);
+    workingval = pac_cell_shuffle(workingval);
+    workingval = pac_mult(workingval);
+    workingval ^= key1;
+    workingval = pac_cell_inv_shuffle(workingval);
+    workingval = pac_inv_sub(workingval);
+    workingval = pac_mult(workingval);
+    workingval = pac_cell_inv_shuffle(workingval);
+    workingval ^= key0;
+    workingval ^= runningmod;
+    for (i = 0; i <= 4; ++i) {
+        workingval = pac_inv_sub(workingval);
+        if (i < 4) {
+            workingval = pac_mult(workingval);
+            workingval = pac_cell_inv_shuffle(workingval);
+        }
+        runningmod = tweak_inv_shuffle(runningmod);
+        roundkey = key1 ^ runningmod;
+        workingval ^= RC[4-i];
+        workingval ^= roundkey;
+        workingval ^= alpha;
+    }
+    workingval ^= modk0;
+
+    return workingval;
 }
 
 static uint64_t pauth_addpac(CPUARMState *env, uint64_t ptr, uint64_t modifier,
-- 
2.17.2

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

* [Qemu-devel] [PATCH v2 24/27] target/arm: Add PAuth system registers
  2018-12-14  5:23 [Qemu-devel] [PATCH v2 00/27] target/arm: Implement ARMv8.3-PAuth Richard Henderson
                   ` (22 preceding siblings ...)
  2018-12-14  5:24 ` [Qemu-devel] [PATCH v2 23/27] target/arm: Implement pauth_computepac Richard Henderson
@ 2018-12-14  5:24 ` Richard Henderson
  2019-01-07 14:17   ` Peter Maydell
  2018-12-14  5:24 ` [Qemu-devel] [PATCH v2 25/27] target/arm: Enable PAuth for -cpu max Richard Henderson
                   ` (2 subsequent siblings)
  26 siblings, 1 reply; 51+ messages in thread
From: Richard Henderson @ 2018-12-14  5:24 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell

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

diff --git a/target/arm/helper.c b/target/arm/helper.c
index b9ffc07fbc..f1e9254c9a 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -5061,6 +5061,70 @@ static CPAccessResult access_lor_other(CPUARMState *env,
     return access_lor_ns(env);
 }
 
+#ifdef TARGET_AARCH64
+static CPAccessResult access_pauth(CPUARMState *env, const ARMCPRegInfo *ri,
+                                   bool isread)
+{
+    int el = arm_current_el(env);
+
+    if (el < 2 &&
+        arm_feature(env, ARM_FEATURE_EL2) &&
+        !(arm_hcr_el2_eff(env) & HCR_APK)) {
+        return CP_ACCESS_TRAP_EL2;
+    }
+    if (el < 3 &&
+        arm_feature(env, ARM_FEATURE_EL3) &&
+        !(env->cp15.scr_el3 & SCR_APK)) {
+        return CP_ACCESS_TRAP_EL3;
+    }
+    return CP_ACCESS_OK;
+}
+
+static const ARMCPRegInfo pauth_reginfo[] = {
+    { .name = "APDAKEYLOW_EL1", .state = ARM_CP_STATE_AA64,
+      .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 2, .opc2 = 0,
+      .access = PL1_RW, .accessfn = access_pauth,
+      .fieldoffset = offsetof(CPUARMState, apda_key.lo) },
+    { .name = "APDAKEYHI_EL1", .state = ARM_CP_STATE_AA64,
+      .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 2, .opc2 = 1,
+      .access = PL1_RW, .accessfn = access_pauth,
+      .fieldoffset = offsetof(CPUARMState, apda_key.hi) },
+    { .name = "APDBKEYLOW_EL1", .state = ARM_CP_STATE_AA64,
+      .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 2, .opc2 = 2,
+      .access = PL1_RW, .accessfn = access_pauth,
+      .fieldoffset = offsetof(CPUARMState, apdb_key.lo) },
+    { .name = "APDBKEYHI_EL1", .state = ARM_CP_STATE_AA64,
+      .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 2, .opc2 = 3,
+      .access = PL1_RW, .accessfn = access_pauth,
+      .fieldoffset = offsetof(CPUARMState, apdb_key.hi) },
+    { .name = "APGAKEYLOW_EL1", .state = ARM_CP_STATE_AA64,
+      .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 3, .opc2 = 0,
+      .access = PL1_RW, .accessfn = access_pauth,
+      .fieldoffset = offsetof(CPUARMState, apia_key.lo) },
+    { .name = "APGAKEYHI_EL1", .state = ARM_CP_STATE_AA64,
+      .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 3, .opc2 = 1,
+      .access = PL1_RW, .accessfn = access_pauth,
+      .fieldoffset = offsetof(CPUARMState, apia_key.hi) },
+    { .name = "APIAKEYLOW_EL1", .state = ARM_CP_STATE_AA64,
+      .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 1, .opc2 = 0,
+      .access = PL1_RW, .accessfn = access_pauth,
+      .fieldoffset = offsetof(CPUARMState, apia_key.lo) },
+    { .name = "APIAKEYHI_EL1", .state = ARM_CP_STATE_AA64,
+      .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 1, .opc2 = 1,
+      .access = PL1_RW, .accessfn = access_pauth,
+      .fieldoffset = offsetof(CPUARMState, apia_key.hi) },
+    { .name = "APIBKEYLOW_EL1", .state = ARM_CP_STATE_AA64,
+      .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 1, .opc2 = 2,
+      .access = PL1_RW, .accessfn = access_pauth,
+      .fieldoffset = offsetof(CPUARMState, apib_key.lo) },
+    { .name = "APIBKEYHI_EL1", .state = ARM_CP_STATE_AA64,
+      .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 1, .opc2 = 3,
+      .access = PL1_RW, .accessfn = access_pauth,
+      .fieldoffset = offsetof(CPUARMState, apib_key.hi) },
+    REGINFO_SENTINEL
+};
+#endif
+
 void register_cp_regs_for_features(ARMCPU *cpu)
 {
     /* Register all the coprocessor registers based on feature bits */
@@ -5845,6 +5909,12 @@ void register_cp_regs_for_features(ARMCPU *cpu)
             define_one_arm_cp_reg(cpu, &zcr_el3_reginfo);
         }
     }
+
+#ifdef TARGET_AARCH64
+    if (cpu_isar_feature(aa64_pauth, cpu)) {
+        define_arm_cp_regs(cpu, pauth_reginfo);
+    }
+#endif
 }
 
 void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
-- 
2.17.2

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

* [Qemu-devel] [PATCH v2 25/27] target/arm: Enable PAuth for -cpu max
  2018-12-14  5:23 [Qemu-devel] [PATCH v2 00/27] target/arm: Implement ARMv8.3-PAuth Richard Henderson
                   ` (23 preceding siblings ...)
  2018-12-14  5:24 ` [Qemu-devel] [PATCH v2 24/27] target/arm: Add PAuth system registers Richard Henderson
@ 2018-12-14  5:24 ` Richard Henderson
  2019-01-07 14:18   ` Peter Maydell
  2018-12-14  5:24 ` [Qemu-devel] [PATCH v2 26/27] target/arm: Enable PAuth for user-only, part 2 Richard Henderson
  2018-12-14  5:24 ` [Qemu-devel] [PATCH v2 27/27] target/arm: Tidy TBI handling in gen_a64_set_pc Richard Henderson
  26 siblings, 1 reply; 51+ messages in thread
From: Richard Henderson @ 2018-12-14  5:24 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 1d57be0c91..84f70b2a24 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -316,6 +316,10 @@ static void aarch64_max_initfn(Object *obj)
 
         t = cpu->isar.id_aa64isar1;
         t = FIELD_DP64(t, ID_AA64ISAR1, FCMA, 1);
+        t = FIELD_DP64(t, ID_AA64ISAR1, APA, 1); /* PAuth, architected only */
+        t = FIELD_DP64(t, ID_AA64ISAR1, API, 0);
+        t = FIELD_DP64(t, ID_AA64ISAR1, GPA, 1);
+        t = FIELD_DP64(t, ID_AA64ISAR1, GPI, 0);
         cpu->isar.id_aa64isar1 = t;
 
         t = cpu->isar.id_aa64pfr0;
-- 
2.17.2

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

* [Qemu-devel] [PATCH v2 26/27] target/arm: Enable PAuth for user-only, part 2
  2018-12-14  5:23 [Qemu-devel] [PATCH v2 00/27] target/arm: Implement ARMv8.3-PAuth Richard Henderson
                   ` (24 preceding siblings ...)
  2018-12-14  5:24 ` [Qemu-devel] [PATCH v2 25/27] target/arm: Enable PAuth for -cpu max Richard Henderson
@ 2018-12-14  5:24 ` Richard Henderson
  2019-01-07 14:23   ` Peter Maydell
  2018-12-14  5:24 ` [Qemu-devel] [PATCH v2 27/27] target/arm: Tidy TBI handling in gen_a64_set_pc Richard Henderson
  26 siblings, 1 reply; 51+ messages in thread
From: Richard Henderson @ 2018-12-14  5:24 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell

FIXME: We should have an attribute that controls the EL1 enable bits.
We may not always want to turn on pointer authentication with -cpu max.

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

diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 0b185f8d30..bc2c9eb551 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -162,6 +162,12 @@ static void arm_cpu_reset(CPUState *s)
         env->pstate = PSTATE_MODE_EL0t;
         /* Userspace expects access to DC ZVA, CTL_EL0 and the cache ops */
         env->cp15.sctlr_el[1] |= SCTLR_UCT | SCTLR_UCI | SCTLR_DZE;
+        /* Enable all PAC keys. */
+        env->cp15.sctlr_el[1] |= SCTLR_EnIA | SCTLR_EnIB;
+        env->cp15.sctlr_el[1] |= SCTLR_EnDA | SCTLR_EnDB;
+        /* Enable all PAC instructions */
+        env->cp15.hcr_el2 |= HCR_API;
+        env->cp15.scr_el3 |= SCR_API;
         /* and to the FP/Neon instructions */
         env->cp15.cpacr_el1 = deposit64(env->cp15.cpacr_el1, 20, 2, 3);
         /* and to the SVE instructions */
-- 
2.17.2

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

* [Qemu-devel] [PATCH v2 27/27] target/arm: Tidy TBI handling in gen_a64_set_pc
  2018-12-14  5:23 [Qemu-devel] [PATCH v2 00/27] target/arm: Implement ARMv8.3-PAuth Richard Henderson
                   ` (25 preceding siblings ...)
  2018-12-14  5:24 ` [Qemu-devel] [PATCH v2 26/27] target/arm: Enable PAuth for user-only, part 2 Richard Henderson
@ 2018-12-14  5:24 ` Richard Henderson
  2019-01-07 14:34   ` Peter Maydell
  26 siblings, 1 reply; 51+ messages in thread
From: Richard Henderson @ 2018-12-14  5:24 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell

We can perform this with fewer operations.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/translate-a64.c | 65 ++++++++++++++------------------------
 1 file changed, 23 insertions(+), 42 deletions(-)

diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index c57c89d98a..5c06e429d4 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -261,7 +261,7 @@ void gen_a64_set_pc_im(uint64_t val)
 /* Load the PC from a generic TCG variable.
  *
  * If address tagging is enabled via the TCR TBI bits, then loading
- * an address into the PC will clear out any tag in the it:
+ * an address into the PC will clear out any tag in it:
  *  + for EL2 and EL3 there is only one TBI bit, and if it is set
  *    then the address is zero-extended, clearing bits [63:56]
  *  + for EL0 and EL1, TBI0 controls addresses with bit 55 == 0
@@ -276,56 +276,37 @@ void gen_a64_set_pc_im(uint64_t val)
  */
 static void gen_a64_set_pc(DisasContext *s, TCGv_i64 src)
 {
+    bool tbi0 = s->tbi0, tbi1 = s->tbi1;
 
     if (s->current_el <= 1) {
-        /* Test if NEITHER or BOTH TBI values are set.  If so, no need to
-         * examine bit 55 of address, can just generate code.
-         * If mixed, then test via generated code
-         */
-        if (s->tbi0 && s->tbi1) {
-            TCGv_i64 tmp_reg = tcg_temp_new_i64();
-            /* Both bits set, sign extension from bit 55 into [63:56] will
-             * cover both cases
-             */
-            tcg_gen_shli_i64(tmp_reg, src, 8);
-            tcg_gen_sari_i64(cpu_pc, tmp_reg, 8);
-            tcg_temp_free_i64(tmp_reg);
-        } else if (!s->tbi0 && !s->tbi1) {
-            /* Neither bit set, just load it as-is */
-            tcg_gen_mov_i64(cpu_pc, src);
-        } else {
-            TCGv_i64 tcg_tmpval = tcg_temp_new_i64();
-            TCGv_i64 tcg_bit55  = tcg_temp_new_i64();
-            TCGv_i64 tcg_zero   = tcg_const_i64(0);
+        if (tbi0 || tbi1) {
+            /* Sign-extend from bit 55.  */
+            tcg_gen_sextract_i64(cpu_pc, src, 0, 56);
 
-            tcg_gen_andi_i64(tcg_bit55, src, (1ull << 55));
+            if (tbi0 != tbi1) {
+                TCGv_i64 tcg_zero = tcg_const_i64(0);
 
-            if (s->tbi0) {
-                /* tbi0==1, tbi1==0, so 0-fill upper byte if bit 55 = 0 */
-                tcg_gen_andi_i64(tcg_tmpval, src,
-                                 0x00FFFFFFFFFFFFFFull);
-                tcg_gen_movcond_i64(TCG_COND_EQ, cpu_pc, tcg_bit55, tcg_zero,
-                                    tcg_tmpval, src);
-            } else {
-                /* tbi0==0, tbi1==1, so 1-fill upper byte if bit 55 = 1 */
-                tcg_gen_ori_i64(tcg_tmpval, src,
-                                0xFF00000000000000ull);
-                tcg_gen_movcond_i64(TCG_COND_NE, cpu_pc, tcg_bit55, tcg_zero,
-                                    tcg_tmpval, src);
+                /*
+                 * The two TBI bits differ.
+                 * If tbi0, then !tbi1: only use the extension if positive.
+                 * if !tbi0, then tbi1: only use the extension if negative.
+                 */
+                tcg_gen_movcond_i64(tbi0 ? TCG_COND_GE : TCG_COND_LT,
+                                    cpu_pc, cpu_pc, tcg_zero, cpu_pc, src);
+                tcg_temp_free_i64(tcg_zero);
             }
-            tcg_temp_free_i64(tcg_zero);
-            tcg_temp_free_i64(tcg_bit55);
-            tcg_temp_free_i64(tcg_tmpval);
+            return;
         }
-    } else {  /* EL > 1 */
-        if (s->tbi0) {
+    } else {
+        if (tbi0) {
             /* Force tag byte to all zero */
-            tcg_gen_andi_i64(cpu_pc, src, 0x00FFFFFFFFFFFFFFull);
-        } else {
-            /* Load unmodified address */
-            tcg_gen_mov_i64(cpu_pc, src);
+            tcg_gen_extract_i64(cpu_pc, src, 0, 56);
+            return;
         }
     }
+
+    /* Load unmodified address */
+    tcg_gen_mov_i64(cpu_pc, src);
 }
 
 typedef struct DisasCompare64 {
-- 
2.17.2

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

* Re: [Qemu-devel] [PATCH v2 04/27] target/arm: Add PAuth helpers
  2018-12-14  5:23 ` [Qemu-devel] [PATCH v2 04/27] target/arm: Add PAuth helpers Richard Henderson
@ 2019-01-04 16:25   ` Peter Maydell
  2019-01-08  2:32     ` Richard Henderson
  0 siblings, 1 reply; 51+ messages in thread
From: Peter Maydell @ 2019-01-04 16:25 UTC (permalink / raw)
  To: Richard Henderson; +Cc: QEMU Developers

On Fri, 14 Dec 2018 at 05:24, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> The cryptographic internals are stubbed out for now,
> but the enable and trap bits are checked.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ----

> +static void QEMU_NORETURN pauth_trap(CPUARMState *env, int target_el,
> +                                     uintptr_t ra)
> +{
> +    CPUState *cs = ENV_GET_CPU(env);
> +
> +    cs->exception_index = EXCP_UDEF;
> +    env->exception.syndrome = syn_pactrap();
> +    env->exception.target_el = target_el;
> +    cpu_loop_exit_restore(cs, ra);

This should use raise_exception(), or some variant on it that
lets you pass in the ra, because otherwise you lose the
"redirect EL1 exceptions to EL2" HCR.TGE behaviour.
Or can we only ever call this for a target_el of 2 or 3?

It might be cleaner to have a raise_exception_ra() anyway,
to preserve the "all exception throwing goes through here" rule.

> +}

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH v2 01/27] target/arm: Add state for the ARMv8.3-PAuth extension
  2018-12-14  5:23 ` [Qemu-devel] [PATCH v2 01/27] target/arm: Add state for the ARMv8.3-PAuth extension Richard Henderson
@ 2019-01-04 16:25   ` Peter Maydell
  0 siblings, 0 replies; 51+ messages in thread
From: Peter Maydell @ 2019-01-04 16:25 UTC (permalink / raw)
  To: Richard Henderson; +Cc: QEMU Developers

On Fri, 14 Dec 2018 at 05:24, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Add storage space for the 5 encryption keys.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ----
> v2: Remove pointless double migration.
>     Use a struct to make it clear which half is which.
> ---


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

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH v2 05/27] target/arm: Decode PAuth within system hint space
  2018-12-14  5:23 ` [Qemu-devel] [PATCH v2 05/27] target/arm: Decode PAuth within system hint space Richard Henderson
@ 2019-01-04 16:50   ` Peter Maydell
  0 siblings, 0 replies; 51+ messages in thread
From: Peter Maydell @ 2019-01-04 16:50 UTC (permalink / raw)
  To: Richard Henderson; +Cc: QEMU Developers

On Fri, 14 Dec 2018 at 05:24, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/arm/translate-a64.c | 93 +++++++++++++++++++++++++++++++++-----
>  1 file changed, 81 insertions(+), 12 deletions(-)
>
> diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
> index 7c1cc1ce8e..0df344f9e8 100644
> --- a/target/arm/translate-a64.c
> +++ b/target/arm/translate-a64.c
> @@ -1471,33 +1471,102 @@ static void handle_hint(DisasContext *s, uint32_t insn,
>      }
>
>      switch (selector) {
> -    case 0: /* NOP */
> -        return;
> -    case 3: /* WFI */
> +    case 000: /* NOP */
> +        break;
> +    case 003: /* WFI */

I can see why you wanted to use octal here, but I think it's
confusing (simply because octal constants are so rare and
so easy to misread). Maybe we could compromise on 0bnnnn ?
It looks like disas/riscv.c has implicitly proven that all
the compilers we care about support that...

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

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH v2 07/27] target/arm: Decode PAuth within disas_data_proc_1src
  2018-12-14  5:23 ` [Qemu-devel] [PATCH v2 07/27] target/arm: Decode PAuth within disas_data_proc_1src Richard Henderson
@ 2019-01-04 17:00   ` Peter Maydell
  0 siblings, 0 replies; 51+ messages in thread
From: Peter Maydell @ 2019-01-04 17:00 UTC (permalink / raw)
  To: Richard Henderson; +Cc: QEMU Developers

On Fri, 14 Dec 2018 at 05:24, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/arm/translate-a64.c | 146 +++++++++++++++++++++++++++++++++++++
>  1 file changed, 146 insertions(+)
>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH v2 11/27] target/arm: Rearrange decode in disas_uncond_b_reg
  2018-12-14  5:23 ` [Qemu-devel] [PATCH v2 11/27] target/arm: Rearrange decode in disas_uncond_b_reg Richard Henderson
@ 2019-01-04 17:05   ` Peter Maydell
  0 siblings, 0 replies; 51+ messages in thread
From: Peter Maydell @ 2019-01-04 17:05 UTC (permalink / raw)
  To: Richard Henderson; +Cc: QEMU Developers

On Fri, 14 Dec 2018 at 05:24, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> This will enable PAuth decode in a subsequent patch.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/arm/translate-a64.c | 47 +++++++++++++++++++++++++++++---------
>  1 file changed, 36 insertions(+), 11 deletions(-)




Applied to target-arm.next, thanks.

-- PMM

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

* Re: [Qemu-devel] [PATCH v2 12/27] target/arm: Decode PAuth within disas_uncond_b_reg
  2018-12-14  5:23 ` [Qemu-devel] [PATCH v2 12/27] target/arm: Decode PAuth within disas_uncond_b_reg Richard Henderson
@ 2019-01-04 17:12   ` Peter Maydell
  0 siblings, 0 replies; 51+ messages in thread
From: Peter Maydell @ 2019-01-04 17:12 UTC (permalink / raw)
  To: Richard Henderson; +Cc: QEMU Developers

On Fri, 14 Dec 2018 at 05:24, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/arm/translate-a64.c | 82 +++++++++++++++++++++++++++++++++++++-
>  1 file changed, 81 insertions(+), 1 deletion(-)

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

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH v2 13/27] target/arm: Decode Load/store register (pac)
  2018-12-14  5:23 ` [Qemu-devel] [PATCH v2 13/27] target/arm: Decode Load/store register (pac) Richard Henderson
@ 2019-01-04 18:52   ` Peter Maydell
  0 siblings, 0 replies; 51+ messages in thread
From: Peter Maydell @ 2019-01-04 18:52 UTC (permalink / raw)
  To: Richard Henderson; +Cc: QEMU Developers

On Fri, 14 Dec 2018 at 05:24, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Not that there are any stores involved, but why argue with ARM's
> naming convention.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/arm/translate-a64.c | 62 ++++++++++++++++++++++++++++++++++++++
>  1 file changed, 62 insertions(+)
>
> diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
> index e62d248894..c57c89d98a 100644
> --- a/target/arm/translate-a64.c
> +++ b/target/arm/translate-a64.c
> @@ -3146,6 +3146,65 @@ static void disas_ldst_atomic(DisasContext *s, uint32_t insn,
>         s->be_data | size | MO_ALIGN);
>  }
>
> +/* PAC memory operations
> + *
> + *  31  30      27  26    24    22  21       12  11  10    5     0
> + * +------+-------+---+-----+-----+---+--------+---+---+----+-----+
> + * | size | 1 1 1 | V | 0 0 | M S | 1 |  imm9  | W | 1 | Rn |  Rt |
> + * +------+-------+---+-----+-----+------------+---+---+----+-----+
> + *
> + * Rt: the result register
> + * Rn: base address or SP
> + * Rs: the source register for the operation
> + * V: vector flag (always 0 as of v8.3)
> + * M: clear for key DA, set for key DB
> + * W: pre-indexing flag
> + * S: sign for imm9.
> + */
> +static void disas_ldst_pac(DisasContext *s, uint32_t insn,
> +                           int size, int rt, bool is_vector)
> +{
> +    int rn = extract32(insn, 5, 5);
> +    bool is_wback = extract32(insn, 11, 1);
> +    bool use_key_a = !extract32(insn, 23, 1);
> +    int offset, memidx;
> +    TCGv_i64 tcg_addr, tcg_rt;
> +
> +    if (size != 3 || is_vector || !dc_isar_feature(aa64_pauth, s)) {
> +        unallocated_encoding(s);
> +        return;
> +    }
> +
> +    if (rn == 31) {
> +        gen_check_sp_alignment(s);
> +    }
> +    tcg_addr = read_cpu_reg_sp(s, rn, 1);
> +
> +    if (s->pauth_active) {
> +        if (use_key_a) {
> +            gen_helper_autda(tcg_addr, cpu_env, tcg_addr, cpu_X[31]);
> +        } else {
> +            gen_helper_autdb(tcg_addr, cpu_env, tcg_addr, cpu_X[31]);
> +        }
> +    }
> +
> +    /* Form the 10-bit signed, scaled offset.  */
> +    offset = (extract32(insn, 22, 1) << 9) | extract32(insn, 12, 9);
> +    offset = sextract32(offset << size, 10 + size, 0);
> +    tcg_gen_addi_i64(tcg_addr, tcg_addr, offset);
> +
> +    tcg_rt = cpu_reg(s, rt);
> +    memidx = get_mem_index(s);
> +    do_gpr_ld_memidx(s, tcg_rt, tcg_addr, size,
> +                     /* is_signed */ false, /* extend */ false, memidx,
> +                     /* iss_valid */ true, /* iss_srt */ rt,
> +                     /* iss_sf */ true, /* iss_ar */ false);

Since you don't have the "memidx might be something other than
the result of get_mem_index()" case to worry about, you could
use do_gpr_ld() here.

ISS information is not valid for accesses which do writeback.
(We seem to get this wrong in the existing disas_ldst_reg_imm9()...)

> +
> +    if (is_wback) {
> +        tcg_gen_mov_i64(cpu_reg_sp(s, rn), tcg_addr);
> +    }
> +}
> +
>  /* Load/store register (all forms) */
>  static void disas_ldst_reg(DisasContext *s, uint32_t insn)
>  {
> @@ -3171,6 +3230,9 @@ static void disas_ldst_reg(DisasContext *s, uint32_t insn)
>          case 2:
>              disas_ldst_reg_roffset(s, insn, opc, size, rt, is_vector);
>              return;
> +        default:
> +            disas_ldst_pac(s, insn, size, rt, is_vector);
> +            return;
>          }
>          break;
>      case 1:
> --
> 2.17.2
>

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH v2 16/27] target/arm: Introduce arm_stage1_mmu_idx
  2018-12-14  5:23 ` [Qemu-devel] [PATCH v2 16/27] target/arm: Introduce arm_stage1_mmu_idx Richard Henderson
@ 2019-01-04 18:58   ` Peter Maydell
  0 siblings, 0 replies; 51+ messages in thread
From: Peter Maydell @ 2019-01-04 18:58 UTC (permalink / raw)
  To: Richard Henderson; +Cc: QEMU Developers

On Fri, 14 Dec 2018 at 05:24, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> While we could expose stage_1_mmu_idx, the combination is
> probably going to be more useful.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

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

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH v2 17/27] target/arm: Create ARMVAParameters and helpers
  2018-12-14  5:24 ` [Qemu-devel] [PATCH v2 17/27] target/arm: Create ARMVAParameters and helpers Richard Henderson
@ 2019-01-07 11:40   ` Peter Maydell
  0 siblings, 0 replies; 51+ messages in thread
From: Peter Maydell @ 2019-01-07 11:40 UTC (permalink / raw)
  To: Richard Henderson; +Cc: QEMU Developers

On Fri, 14 Dec 2018 at 05:24, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Split out functions to extract the virtual address parameters.
> Let the functions choose T0 or T1 address space half, if present.
> Extract (most of) the control bits that vary between EL or Tx.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ----
> v2: Incorporate feedback wrt VTCR, HTCR, and more.
> ---
>  target/arm/internals.h |  16 +++
>  target/arm/helper.c    | 286 +++++++++++++++++++++++------------------
>  2 files changed, 174 insertions(+), 128 deletions(-)
>
> diff --git a/target/arm/internals.h b/target/arm/internals.h
> index 1d0d0392c9..9ef9d01ee2 100644
> --- a/target/arm/internals.h
> +++ b/target/arm/internals.h
> @@ -935,4 +935,20 @@ static inline ARMMMUIdx arm_stage1_mmu_idx(CPUARMState *env)
>  ARMMMUIdx arm_stage1_mmu_idx(CPUARMState *env);
>  #endif
>
> +/*
> + * Parameters of a given virtual address, as extracted from a the

"a" or "the" but not both :-)

> + * translation control register (TCR) for a given regime.
> + */
> +typedef struct ARMVAParameters {
> +    unsigned tsz    : 8;
> +    unsigned select : 1;
> +    bool tbi        : 1;
> +    bool epd        : 1;
> +    bool hpd        : 1;
> +    bool ha         : 1;
> +    bool hd         : 1;
> +    bool using16k   : 1;
> +    bool using64k   : 1;
> +} ARMVAParameters;
> +
>  #endif
> diff --git a/target/arm/helper.c b/target/arm/helper.c
> index b1c0ff923f..3422fa5943 100644
> --- a/target/arm/helper.c
> +++ b/target/arm/helper.c
> @@ -9744,6 +9744,133 @@ static uint8_t convert_stage2_attrs(CPUARMState *env, uint8_t s2attrs)
>      return (hiattr << 6) | (hihint << 4) | (loattr << 2) | lohint;
>  }
>
> +static ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
> +                                          ARMMMUIdx mmu_idx, bool data)
> +{
> +    uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
> +    uint32_t el = regime_el(env, mmu_idx);
> +    bool tbi, tbid, epd, hpd, ha, hd, using16k, using64k;
> +    int select, tsz;
> +
> +    /* Bit 55 is always between the two regions, and is canonical for
> +     * determining if address tagging is enabled.
> +     */
> +    select = extract64(va, 55, 1);
> +
> +    if (el > 1) {
> +        tsz = extract32(tcr, 0, 6);
> +        using64k = extract32(tcr, 14, 1);
> +        using16k = extract32(tcr, 15, 1);
> +        if (mmu_idx == ARMMMUIdx_S2NS) {
> +            /* VTCR_EL2 */
> +            tbi = tbid = hpd = false;
> +        } else {
> +            tbi = extract32(tcr, 20, 1);
> +            hpd = extract32(tcr, 24, 1);
> +            tbid = extract32(tcr, 29, 1);
> +        }
> +        ha = extract32(tcr, 21, 1);
> +        hd = extract32(tcr, 22, 1);
> +        epd = false;
> +    } else if (!select) {
> +        tsz = extract32(tcr, 0, 6);
> +        epd = extract32(tcr, 7, 1);
> +        using64k = extract32(tcr, 14, 1);
> +        using16k = extract32(tcr, 15, 1);
> +        tbi = extract64(tcr, 37, 1);
> +        ha = extract64(tcr, 39, 1);
> +        hd = extract64(tcr, 40, 1);
> +        hpd = extract64(tcr, 41, 1);
> +        tbid = extract64(tcr, 51, 1);
> +    } else {
> +        int tg = extract32(tcr, 30, 2);
> +        using16k = tg == 1;
> +        using64k = tg == 3;
> +        tsz = extract32(tcr, 16, 6);
> +        epd = extract32(tcr, 23, 1);
> +        tbi = extract64(tcr, 38, 1);
> +        ha = extract64(tcr, 39, 1);
> +        hd = extract64(tcr, 40, 1);
> +        hpd = extract64(tcr, 42, 1);
> +        tbid = extract64(tcr, 52, 1);
> +    }
> +    tsz = MIN(tsz, 39);  /* TODO: ARMv8.4-TTST */
> +    tsz = MAX(tsz, 16);  /* TODO: ARMv8.2-LVA  */
> +
> +    return (ARMVAParameters) {
> +        .tsz = tsz,
> +        .select = select,
> +        .tbi = tbi & (data | !tbid),

This check on TBID is a behaviour change, isn't it ?
Can we please keep the "no change refactoring" separate from
"add new behaviour"? This patch is tricky enough to review
already. (I like the way the code ends up, but it has taken
me a fair amount of time to try to confirm that it does indeed
do the same thing as the old code, and I'm still not completely
sure about the changes in the ttbr select logic, though I
think it ends up doing the same thing.)

Similarly, .ha and .hd are new, I think, so could be added
in a later patch (presumably with whatever uses them).

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH v2 18/27] target/arm: Reuse aa64_va_parameters for setting tbflags
  2018-12-14  5:24 ` [Qemu-devel] [PATCH v2 18/27] target/arm: Reuse aa64_va_parameters for setting tbflags Richard Henderson
@ 2019-01-07 11:44   ` Peter Maydell
  0 siblings, 0 replies; 51+ messages in thread
From: Peter Maydell @ 2019-01-07 11:44 UTC (permalink / raw)
  To: Richard Henderson; +Cc: QEMU Developers

On Fri, 14 Dec 2018 at 05:24, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> The arm_regime_tbi{0,1} functions are replacable with the new function
> by giving the lowest and highest address.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/arm/cpu.h    | 35 --------------------------
>  target/arm/helper.c | 61 ++++++++++++---------------------------------
>  2 files changed, 16 insertions(+), 80 deletions(-)

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

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH v2 19/27] target/arm: Export aa64_va_parameters to internals.h
  2018-12-14  5:24 ` [Qemu-devel] [PATCH v2 19/27] target/arm: Export aa64_va_parameters to internals.h Richard Henderson
@ 2019-01-07 11:45   ` Peter Maydell
  2019-01-07 22:22     ` Richard Henderson
  0 siblings, 1 reply; 51+ messages in thread
From: Peter Maydell @ 2019-01-07 11:45 UTC (permalink / raw)
  To: Richard Henderson; +Cc: QEMU Developers

On Fri, 14 Dec 2018 at 05:24, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> We need to reuse this from helper-a64.c.  Provide a stub
> definition for CONFIG_USER_ONLY.  This matches the stub
> definitions that we removed for arm_regime_tbi{0,1} before.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/arm/internals.h | 17 +++++++++++++++++
>  target/arm/helper.c    |  4 ++--
>  2 files changed, 19 insertions(+), 2 deletions(-)
>
> diff --git a/target/arm/internals.h b/target/arm/internals.h
> index 9ef9d01ee2..4fbef58126 100644
> --- a/target/arm/internals.h
> +++ b/target/arm/internals.h
> @@ -951,4 +951,21 @@ typedef struct ARMVAParameters {
>      bool using64k   : 1;
>  } ARMVAParameters;
>
> +#ifdef CONFIG_USER_ONLY
> +static inline ARMVAParameters aa64_va_parameters(CPUARMState *env,
> +                                                 uint64_t va,
> +                                                 ARMMMUIdx mmu_idx, bool data)
> +{
> +    return (ARMVAParameters) {
> +        /* 48-bit address space */
> +        .tsz = 16,

I assume 48 bits is what the kernel sets up for userspace ?

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

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH v2 20/27] target/arm: Implement pauth_strip
  2018-12-14  5:24 ` [Qemu-devel] [PATCH v2 20/27] target/arm: Implement pauth_strip Richard Henderson
@ 2019-01-07 11:52   ` Peter Maydell
  0 siblings, 0 replies; 51+ messages in thread
From: Peter Maydell @ 2019-01-07 11:52 UTC (permalink / raw)
  To: Richard Henderson; +Cc: QEMU Developers

On Fri, 14 Dec 2018 at 05:24, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Stripping out the authentication data does not require any crypto,
> it merely requires the virtual address parameters.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH v2 21/27] target/arm: Implement pauth_auth
  2018-12-14  5:24 ` [Qemu-devel] [PATCH v2 21/27] target/arm: Implement pauth_auth Richard Henderson
@ 2019-01-07 11:58   ` Peter Maydell
  0 siblings, 0 replies; 51+ messages in thread
From: Peter Maydell @ 2019-01-07 11:58 UTC (permalink / raw)
  To: Richard Henderson; +Cc: QEMU Developers

On Fri, 14 Dec 2018 at 05:24, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> This is not really functional yet, because the crypto is not yet
> implemented.  This, however follows the Auth pseudo function.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/arm/helper-a64.c | 21 ++++++++++++++++++++-
>  1 file changed, 20 insertions(+), 1 deletion(-)

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

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH v2 22/27] target/arm: Implement pauth_addpac
  2018-12-14  5:24 ` [Qemu-devel] [PATCH v2 22/27] target/arm: Implement pauth_addpac Richard Henderson
@ 2019-01-07 13:31   ` Peter Maydell
  2019-01-08  4:48     ` Richard Henderson
  0 siblings, 1 reply; 51+ messages in thread
From: Peter Maydell @ 2019-01-07 13:31 UTC (permalink / raw)
  To: Richard Henderson; +Cc: QEMU Developers

On Fri, 14 Dec 2018 at 05:24, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> This is not really functional yet, because the crypto is not yet
> implemented.  This, however follows the AddPAC pseudo function.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/arm/helper-a64.c | 40 +++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 39 insertions(+), 1 deletion(-)
>
> diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
> index 87cff7d96a..19486b9677 100644
> --- a/target/arm/helper-a64.c
> +++ b/target/arm/helper-a64.c
> @@ -1066,7 +1066,45 @@ static uint64_t pauth_computepac(uint64_t data, uint64_t modifier,
>  static uint64_t pauth_addpac(CPUARMState *env, uint64_t ptr, uint64_t modifier,
>                               ARMPACKey *key, bool data)
>  {
> -    g_assert_not_reached(); /* FIXME */
> +    ARMMMUIdx mmu_idx = arm_stage1_mmu_idx(env);
> +    ARMVAParameters param = aa64_va_parameters(env, ptr, mmu_idx, data);
> +    uint64_t pac, ext_ptr, ext, test;
> +    int bot_bit, top_bit;
> +
> +    /* If tagged pointers are in use, use ptr<55>, otherwise ptr<63>.  */
> +    if (param.tbi) {
> +        ext = sextract64(ptr, 55, 1);
> +    } else {
> +        ext = sextract64(ptr, 63, 1);
> +    }
> +
> +    /* Build a pointer with known good extension bits.  */
> +    top_bit = 64 - 8 * param.tbi;
> +    bot_bit = 64 - param.tsz;
> +    ext_ptr = deposit64(ptr, bot_bit, top_bit - bot_bit, ext);
> +
> +    pac = pauth_computepac(ext_ptr, modifier, *key);
> +
> +    /* Check if the ptr has good extension bits and corrupt the
> +     * pointer authentication code if not.
> +     */

Newer checkpatch will grumble about this style of block
comment, by the way.

> +    test = sextract64(ptr, bot_bit, top_bit - bot_bit);
> +    if (test != 0 && test != -1) {
> +        pac ^= 1ull << (top_bit - 1);

MAKE_64BIT_MASK(top_bit - 1, 1) might be more consistent with
the code below ?

> +    }
> +
> +    /* Preserve the determination between upper and lower at bit 55,
> +     * and insert pointer authentication code.
> +     */
> +    if (param.tbi) {
> +        ptr &= ~MAKE_64BIT_MASK(bot_bit, 55 - bot_bit + 1);
> +        pac &= MAKE_64BIT_MASK(bot_bit, 54 - bot_bit + 1);
> +    } else {
> +        ptr &= MAKE_64BIT_MASK(0, bot_bit);
> +        pac &= ~(MAKE_64BIT_MASK(55, 1) | MAKE_64BIT_MASK(0, bot_bit));
> +    }
> +    ext &= MAKE_64BIT_MASK(55, 1);

I found this a bit confusing to disentangle and compare with
the pseudocode: the difference between the tbi and
not-tbi cases is only "what are bits 63:56 in the result",
but the implementation of how we put together bits 55:0 is
different in the two code paths here.

> +    return pac | ext | ptr;
>  }
>
>  static uint64_t pauth_original_ptr(uint64_t ptr, ARMVAParameters param)
> --
> 2.17.2

Anyway, the implementation is correct, so:

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

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH v2 23/27] target/arm: Implement pauth_computepac
  2018-12-14  5:24 ` [Qemu-devel] [PATCH v2 23/27] target/arm: Implement pauth_computepac Richard Henderson
@ 2019-01-07 14:09   ` Peter Maydell
  2019-01-08  5:00     ` Richard Henderson
  0 siblings, 1 reply; 51+ messages in thread
From: Peter Maydell @ 2019-01-07 14:09 UTC (permalink / raw)
  To: Richard Henderson; +Cc: QEMU Developers

On Fri, 14 Dec 2018 at 05:24, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> This is the main crypto routine, an implementation of QARMA.
> This matches, as much as possible, ARM pseudocode.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/arm/helper-a64.c | 241 +++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 240 insertions(+), 1 deletion(-)
>
> diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
> index 19486b9677..1da7867a42 100644
> --- a/target/arm/helper-a64.c
> +++ b/target/arm/helper-a64.c
> @@ -1057,10 +1057,249 @@ uint32_t HELPER(sqrt_f16)(uint32_t a, void *fpstp)
>   * Helpers for ARMv8.3-PAuth.
>   */
>
> +static uint64_t pac_cell_shuffle(uint64_t i)
> +{
> +    uint64_t o = 0;
> +
> +    o |= extract64(i, 52, 4);
> +    o |= extract64(i, 24, 4) << 4;
> +    o |= extract64(i, 44, 4) << 8;
> +    o |= extract64(i,  0, 4) << 12;
> +
> +    o |= extract64(i, 28, 4) << 16;
> +    o |= extract64(i, 48, 4) << 20;
> +    o |= extract64(i,  4, 4) << 24;
> +    o |= extract64(i, 40, 4) << 28;
> +
> +    o |= i & MAKE_64BIT_MASK(32, 4);

Can't we just use
       o |= extract64(i, 32, 4) << 32;
to stay parallel with everything else?
Similarly below.

> +    o |= extract64(i, 12, 4) << 36;
> +    o |= extract64(i, 56, 4) << 40;
> +    o |= extract64(i,  8, 4) << 44;

The pseudocode in the DDI0487D.a Arm Arm says that bits
outdata<47:44> are indata<23:20>...

> +
> +    o |= extract64(i, 36, 4) << 48;
> +    o |= extract64(i, 16, 4) << 52;

...and these don't match either...

> +    o |= extract64(i, 40, 4) << 56;

and this definitely looks wrong as we've already used
bits 43:40 earlier.

> +    o |= i & MAKE_64BIT_MASK(60, 4);
> +
> +    return o;
> +}

> +static int rot_cell(int cell, int n)
> +{
> +    cell |= cell << 4;
> +    cell >>= n;
> +    return cell & 0xf;

This doesn't seem to do what the RotCell pseudocode does?
Unless I've made an error, RotCell(ABCD, 1) == BCDA,
but rot_cell(ABCD, 1) == DABC.

> +}
> +
> +static uint64_t pac_mult(uint64_t i)
> +{
> +    uint64_t o = 0;
> +    int b;
> +
> +    for (b = 0; b < 4 * 4; b += 4) {
> +        int i0, i4, i8, ic, t0, t1, t2, t3;
> +
> +        i0 = extract64(i, b, 4);
> +        i4 = extract64(i, b + 4 * 4, 4);
> +        i8 = extract64(i, b + 8 * 4, 4);
> +        ic = extract64(i, b + 12 * 4, 4);
> +
> +        t0 = rot_cell(i8, 1) ^ rot_cell(i4, 2) ^ rot_cell(i0, 1);
> +        t1 = rot_cell(ic, 1) ^ rot_cell(i4, 1) ^ rot_cell(i0, 2);
> +        t2 = rot_cell(ic, 2) ^ rot_cell(i8, 1) ^ rot_cell(i0, 1);
> +        t3 = rot_cell(ic, 2) ^ rot_cell(i8, 2) ^ rot_cell(i4, 1);

Shouldn't the first term for t3 be rot_cell(ic, 1) ?

> +
> +        o |= (uint64_t)t3 << b;
> +        o |= (uint64_t)t2 << (b + 4 * 4);
> +        o |= (uint64_t)t1 << (b + 8 * 4);
> +        o |= (uint64_t)t0 << (b + 12 * 4);
> +    }
> +    return o;
> +}

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH v2 24/27] target/arm: Add PAuth system registers
  2018-12-14  5:24 ` [Qemu-devel] [PATCH v2 24/27] target/arm: Add PAuth system registers Richard Henderson
@ 2019-01-07 14:17   ` Peter Maydell
  0 siblings, 0 replies; 51+ messages in thread
From: Peter Maydell @ 2019-01-07 14:17 UTC (permalink / raw)
  To: Richard Henderson; +Cc: QEMU Developers

On Fri, 14 Dec 2018 at 05:24, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/arm/helper.c | 70 +++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 70 insertions(+)
>
> diff --git a/target/arm/helper.c b/target/arm/helper.c
> index b9ffc07fbc..f1e9254c9a 100644
> --- a/target/arm/helper.c
> +++ b/target/arm/helper.c
> @@ -5061,6 +5061,70 @@ static CPAccessResult access_lor_other(CPUARMState *env,
>      return access_lor_ns(env);
>  }
>
> +#ifdef TARGET_AARCH64
> +static CPAccessResult access_pauth(CPUARMState *env, const ARMCPRegInfo *ri,
> +                                   bool isread)
> +{
> +    int el = arm_current_el(env);
> +
> +    if (el < 2 &&
> +        arm_feature(env, ARM_FEATURE_EL2) &&
> +        !(arm_hcr_el2_eff(env) & HCR_APK)) {
> +        return CP_ACCESS_TRAP_EL2;
> +    }
> +    if (el < 3 &&
> +        arm_feature(env, ARM_FEATURE_EL3) &&
> +        !(env->cp15.scr_el3 & SCR_APK)) {
> +        return CP_ACCESS_TRAP_EL3;
> +    }
> +    return CP_ACCESS_OK;
> +}
> +
> +static const ARMCPRegInfo pauth_reginfo[] = {
> +    { .name = "APDAKEYLOW_EL1", .state = ARM_CP_STATE_AA64,

The Arm ARM uses "LO" in these register names, not "LOW".

> +      .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 2, .opc2 = 0,
> +      .access = PL1_RW, .accessfn = access_pauth,
> +      .fieldoffset = offsetof(CPUARMState, apda_key.lo) },
> +    { .name = "APDAKEYHI_EL1", .state = ARM_CP_STATE_AA64,
> +      .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 2, .opc2 = 1,
> +      .access = PL1_RW, .accessfn = access_pauth,
> +      .fieldoffset = offsetof(CPUARMState, apda_key.hi) },
> +    { .name = "APDBKEYLOW_EL1", .state = ARM_CP_STATE_AA64,
> +      .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 2, .opc2 = 2,
> +      .access = PL1_RW, .accessfn = access_pauth,
> +      .fieldoffset = offsetof(CPUARMState, apdb_key.lo) },
> +    { .name = "APDBKEYHI_EL1", .state = ARM_CP_STATE_AA64,
> +      .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 2, .opc2 = 3,
> +      .access = PL1_RW, .accessfn = access_pauth,
> +      .fieldoffset = offsetof(CPUARMState, apdb_key.hi) },
> +    { .name = "APGAKEYLOW_EL1", .state = ARM_CP_STATE_AA64,
> +      .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 3, .opc2 = 0,
> +      .access = PL1_RW, .accessfn = access_pauth,
> +      .fieldoffset = offsetof(CPUARMState, apia_key.lo) },

Isn't this referring to the wrong field? Same with the HI version.

> +    { .name = "APGAKEYHI_EL1", .state = ARM_CP_STATE_AA64,
> +      .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 3, .opc2 = 1,
> +      .access = PL1_RW, .accessfn = access_pauth,
> +      .fieldoffset = offsetof(CPUARMState, apia_key.hi) },
> +    { .name = "APIAKEYLOW_EL1", .state = ARM_CP_STATE_AA64,
> +      .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 1, .opc2 = 0,
> +      .access = PL1_RW, .accessfn = access_pauth,
> +      .fieldoffset = offsetof(CPUARMState, apia_key.lo) },
> +    { .name = "APIAKEYHI_EL1", .state = ARM_CP_STATE_AA64,
> +      .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 1, .opc2 = 1,
> +      .access = PL1_RW, .accessfn = access_pauth,
> +      .fieldoffset = offsetof(CPUARMState, apia_key.hi) },
> +    { .name = "APIBKEYLOW_EL1", .state = ARM_CP_STATE_AA64,
> +      .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 1, .opc2 = 2,
> +      .access = PL1_RW, .accessfn = access_pauth,
> +      .fieldoffset = offsetof(CPUARMState, apib_key.lo) },
> +    { .name = "APIBKEYHI_EL1", .state = ARM_CP_STATE_AA64,
> +      .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 1, .opc2 = 3,
> +      .access = PL1_RW, .accessfn = access_pauth,
> +      .fieldoffset = offsetof(CPUARMState, apib_key.hi) },
> +    REGINFO_SENTINEL
> +};
> +#endif

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

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH v2 25/27] target/arm: Enable PAuth for -cpu max
  2018-12-14  5:24 ` [Qemu-devel] [PATCH v2 25/27] target/arm: Enable PAuth for -cpu max Richard Henderson
@ 2019-01-07 14:18   ` Peter Maydell
  0 siblings, 0 replies; 51+ messages in thread
From: Peter Maydell @ 2019-01-07 14:18 UTC (permalink / raw)
  To: Richard Henderson; +Cc: QEMU Developers

On Fri, 14 Dec 2018 at 05:24, 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 1d57be0c91..84f70b2a24 100644
> --- a/target/arm/cpu64.c
> +++ b/target/arm/cpu64.c
> @@ -316,6 +316,10 @@ static void aarch64_max_initfn(Object *obj)
>
>          t = cpu->isar.id_aa64isar1;
>          t = FIELD_DP64(t, ID_AA64ISAR1, FCMA, 1);
> +        t = FIELD_DP64(t, ID_AA64ISAR1, APA, 1); /* PAuth, architected only */
> +        t = FIELD_DP64(t, ID_AA64ISAR1, API, 0);
> +        t = FIELD_DP64(t, ID_AA64ISAR1, GPA, 1);
> +        t = FIELD_DP64(t, ID_AA64ISAR1, GPI, 0);
>          cpu->isar.id_aa64isar1 = t;
>

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

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH v2 26/27] target/arm: Enable PAuth for user-only, part 2
  2018-12-14  5:24 ` [Qemu-devel] [PATCH v2 26/27] target/arm: Enable PAuth for user-only, part 2 Richard Henderson
@ 2019-01-07 14:23   ` Peter Maydell
  0 siblings, 0 replies; 51+ messages in thread
From: Peter Maydell @ 2019-01-07 14:23 UTC (permalink / raw)
  To: Richard Henderson; +Cc: QEMU Developers

On Fri, 14 Dec 2018 at 05:24, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> FIXME: We should have an attribute that controls the EL1 enable bits.
> We may not always want to turn on pointer authentication with -cpu max.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/arm/cpu.c | 6 ++++++
>  1 file changed, 6 insertions(+)

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

I suspect the commit message isn't a very useful place to put
a FIXME remark, though...

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH v2 27/27] target/arm: Tidy TBI handling in gen_a64_set_pc
  2018-12-14  5:24 ` [Qemu-devel] [PATCH v2 27/27] target/arm: Tidy TBI handling in gen_a64_set_pc Richard Henderson
@ 2019-01-07 14:34   ` Peter Maydell
  0 siblings, 0 replies; 51+ messages in thread
From: Peter Maydell @ 2019-01-07 14:34 UTC (permalink / raw)
  To: Richard Henderson; +Cc: QEMU Developers

On Fri, 14 Dec 2018 at 05:24, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> We can perform this with fewer operations.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---


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

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH v2 19/27] target/arm: Export aa64_va_parameters to internals.h
  2019-01-07 11:45   ` Peter Maydell
@ 2019-01-07 22:22     ` Richard Henderson
  0 siblings, 0 replies; 51+ messages in thread
From: Richard Henderson @ 2019-01-07 22:22 UTC (permalink / raw)
  To: Peter Maydell; +Cc: QEMU Developers

On 1/7/19 9:45 PM, Peter Maydell wrote:
> I assume 48 bits is what the kernel sets up for userspace ?

Yep.  There's been some discussion about what to do with 52-bit addressing, but
it hasn't landed upstream yet.


r~

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

* Re: [Qemu-devel] [PATCH v2 04/27] target/arm: Add PAuth helpers
  2019-01-04 16:25   ` Peter Maydell
@ 2019-01-08  2:32     ` Richard Henderson
  0 siblings, 0 replies; 51+ messages in thread
From: Richard Henderson @ 2019-01-08  2:32 UTC (permalink / raw)
  To: Peter Maydell; +Cc: QEMU Developers

On 1/5/19 2:25 AM, Peter Maydell wrote:
> On Fri, 14 Dec 2018 at 05:24, Richard Henderson
> <richard.henderson@linaro.org> wrote:
>>
>> The cryptographic internals are stubbed out for now,
>> but the enable and trap bits are checked.
>>
>> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
>> ----
> 
>> +static void QEMU_NORETURN pauth_trap(CPUARMState *env, int target_el,
>> +                                     uintptr_t ra)
>> +{
>> +    CPUState *cs = ENV_GET_CPU(env);
>> +
>> +    cs->exception_index = EXCP_UDEF;
>> +    env->exception.syndrome = syn_pactrap();
>> +    env->exception.target_el = target_el;
>> +    cpu_loop_exit_restore(cs, ra);
> 
> This should use raise_exception(), or some variant on it that
> lets you pass in the ra, because otherwise you lose the
> "redirect EL1 exceptions to EL2" HCR.TGE behaviour.
> Or can we only ever call this for a target_el of 2 or 3?

This particular usage can only ever target EL 2 or 3,
in response to {SCR,HCR}.API being clear.  AFAICS that
trap is properly directed already.

But, yes, raise_exception_ra would be useful.


r~

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

* Re: [Qemu-devel] [PATCH v2 22/27] target/arm: Implement pauth_addpac
  2019-01-07 13:31   ` Peter Maydell
@ 2019-01-08  4:48     ` Richard Henderson
  0 siblings, 0 replies; 51+ messages in thread
From: Richard Henderson @ 2019-01-08  4:48 UTC (permalink / raw)
  To: Peter Maydell; +Cc: QEMU Developers

On 1/7/19 11:31 PM, Peter Maydell wrote:
>> +    /* Preserve the determination between upper and lower at bit 55,
>> +     * and insert pointer authentication code.
>> +     */
>> +    if (param.tbi) {
>> +        ptr &= ~MAKE_64BIT_MASK(bot_bit, 55 - bot_bit + 1);
>> +        pac &= MAKE_64BIT_MASK(bot_bit, 54 - bot_bit + 1);
>> +    } else {
>> +        ptr &= MAKE_64BIT_MASK(0, bot_bit);
>> +        pac &= ~(MAKE_64BIT_MASK(55, 1) | MAKE_64BIT_MASK(0, bot_bit));
>> +    }
>> +    ext &= MAKE_64BIT_MASK(55, 1);
> 
> I found this a bit confusing to disentangle and compare with
> the pseudocode: the difference between the tbi and
> not-tbi cases is only "what are bits 63:56 in the result",
> but the implementation of how we put together bits 55:0 is
> different in the two code paths here.

Yes.  I found the pseudocode itself to be confusing.
Perhaps I went away from it too far.


r~

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

* Re: [Qemu-devel] [PATCH v2 23/27] target/arm: Implement pauth_computepac
  2019-01-07 14:09   ` Peter Maydell
@ 2019-01-08  5:00     ` Richard Henderson
  0 siblings, 0 replies; 51+ messages in thread
From: Richard Henderson @ 2019-01-08  5:00 UTC (permalink / raw)
  To: Peter Maydell; +Cc: QEMU Developers

On 1/8/19 12:09 AM, Peter Maydell wrote:
>> +static int rot_cell(int cell, int n)
>> +{
>> +    cell |= cell << 4;
>> +    cell >>= n;
>> +    return cell & 0xf;
> 
> This doesn't seem to do what the RotCell pseudocode does?
> Unless I've made an error, RotCell(ABCD, 1) == BCDA,
> but rot_cell(ABCD, 1) == DABC.

Yep, I mis-read the direction of the rotate.

Thanks for all of the proof-reading.
This section I found particularly eye watering.


r~

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

end of thread, other threads:[~2019-01-08  5:00 UTC | newest]

Thread overview: 51+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-12-14  5:23 [Qemu-devel] [PATCH v2 00/27] target/arm: Implement ARMv8.3-PAuth Richard Henderson
2018-12-14  5:23 ` [Qemu-devel] [PATCH v2 01/27] target/arm: Add state for the ARMv8.3-PAuth extension Richard Henderson
2019-01-04 16:25   ` Peter Maydell
2018-12-14  5:23 ` [Qemu-devel] [PATCH v2 02/27] target/arm: Add SCTLR bits through ARMv8.5 Richard Henderson
2018-12-14  5:23 ` [Qemu-devel] [PATCH v2 03/27] target/arm: Add PAuth active bit to tbflags Richard Henderson
2018-12-14  5:23 ` [Qemu-devel] [PATCH v2 04/27] target/arm: Add PAuth helpers Richard Henderson
2019-01-04 16:25   ` Peter Maydell
2019-01-08  2:32     ` Richard Henderson
2018-12-14  5:23 ` [Qemu-devel] [PATCH v2 05/27] target/arm: Decode PAuth within system hint space Richard Henderson
2019-01-04 16:50   ` Peter Maydell
2018-12-14  5:23 ` [Qemu-devel] [PATCH v2 06/27] target/arm: Rearrange decode in disas_data_proc_1src Richard Henderson
2018-12-14  5:23 ` [Qemu-devel] [PATCH v2 07/27] target/arm: Decode PAuth within disas_data_proc_1src Richard Henderson
2019-01-04 17:00   ` Peter Maydell
2018-12-14  5:23 ` [Qemu-devel] [PATCH v2 08/27] target/arm: Decode PAuth within disas_data_proc_2src Richard Henderson
2018-12-14  5:23 ` [Qemu-devel] [PATCH v2 09/27] target/arm: Move helper_exception_return to helper-a64.c Richard Henderson
2018-12-14  5:23 ` [Qemu-devel] [PATCH v2 10/27] target/arm: Add new_pc argument to helper_exception_return Richard Henderson
2018-12-14  5:23 ` [Qemu-devel] [PATCH v2 11/27] target/arm: Rearrange decode in disas_uncond_b_reg Richard Henderson
2019-01-04 17:05   ` Peter Maydell
2018-12-14  5:23 ` [Qemu-devel] [PATCH v2 12/27] target/arm: Decode PAuth within disas_uncond_b_reg Richard Henderson
2019-01-04 17:12   ` Peter Maydell
2018-12-14  5:23 ` [Qemu-devel] [PATCH v2 13/27] target/arm: Decode Load/store register (pac) Richard Henderson
2019-01-04 18:52   ` Peter Maydell
2018-12-14  5:23 ` [Qemu-devel] [PATCH v2 14/27] target/arm: Move cpu_mmu_index out of line Richard Henderson
2018-12-14  5:23 ` [Qemu-devel] [PATCH v2 15/27] target/arm: Introduce arm_mmu_idx Richard Henderson
2018-12-14  5:23 ` [Qemu-devel] [PATCH v2 16/27] target/arm: Introduce arm_stage1_mmu_idx Richard Henderson
2019-01-04 18:58   ` Peter Maydell
2018-12-14  5:24 ` [Qemu-devel] [PATCH v2 17/27] target/arm: Create ARMVAParameters and helpers Richard Henderson
2019-01-07 11:40   ` Peter Maydell
2018-12-14  5:24 ` [Qemu-devel] [PATCH v2 18/27] target/arm: Reuse aa64_va_parameters for setting tbflags Richard Henderson
2019-01-07 11:44   ` Peter Maydell
2018-12-14  5:24 ` [Qemu-devel] [PATCH v2 19/27] target/arm: Export aa64_va_parameters to internals.h Richard Henderson
2019-01-07 11:45   ` Peter Maydell
2019-01-07 22:22     ` Richard Henderson
2018-12-14  5:24 ` [Qemu-devel] [PATCH v2 20/27] target/arm: Implement pauth_strip Richard Henderson
2019-01-07 11:52   ` Peter Maydell
2018-12-14  5:24 ` [Qemu-devel] [PATCH v2 21/27] target/arm: Implement pauth_auth Richard Henderson
2019-01-07 11:58   ` Peter Maydell
2018-12-14  5:24 ` [Qemu-devel] [PATCH v2 22/27] target/arm: Implement pauth_addpac Richard Henderson
2019-01-07 13:31   ` Peter Maydell
2019-01-08  4:48     ` Richard Henderson
2018-12-14  5:24 ` [Qemu-devel] [PATCH v2 23/27] target/arm: Implement pauth_computepac Richard Henderson
2019-01-07 14:09   ` Peter Maydell
2019-01-08  5:00     ` Richard Henderson
2018-12-14  5:24 ` [Qemu-devel] [PATCH v2 24/27] target/arm: Add PAuth system registers Richard Henderson
2019-01-07 14:17   ` Peter Maydell
2018-12-14  5:24 ` [Qemu-devel] [PATCH v2 25/27] target/arm: Enable PAuth for -cpu max Richard Henderson
2019-01-07 14:18   ` Peter Maydell
2018-12-14  5:24 ` [Qemu-devel] [PATCH v2 26/27] target/arm: Enable PAuth for user-only, part 2 Richard Henderson
2019-01-07 14:23   ` Peter Maydell
2018-12-14  5:24 ` [Qemu-devel] [PATCH v2 27/27] target/arm: Tidy TBI handling in gen_a64_set_pc Richard Henderson
2019-01-07 14:34   ` Peter Maydell

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.