Re: [Qemu-devel] [PATCH v2 04/27] target/arm: Add PAuth helpers

2019-01-07 Thread Richard Henderson
On 1/5/19 2:25 AM, Peter Maydell wrote:
> On Fri, 14 Dec 2018 at 05:24, Richard Henderson
>  wrote:
>>
>> The cryptographic internals are stubbed out for now,
>> but the enable and trap bits are checked.
>>
>> Signed-off-by: Richard Henderson 
>> 
> 
>> +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~



Re: [Qemu-devel] [PATCH v2 04/27] target/arm: Add PAuth helpers

2019-01-04 Thread Peter Maydell
On Fri, 14 Dec 2018 at 05:24, Richard Henderson
 wrote:
>
> The cryptographic internals are stubbed out for now,
> but the enable and trap bits are checked.
>
> Signed-off-by: Richard Henderson 
> 

> +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



[Qemu-devel] [PATCH v2 04/27] target/arm: Add PAuth helpers

2018-12-13 Thread Richard Henderson
The cryptographic internals are stubbed out for now,
but the enable and trap bits are checked.

Signed-off-by: Richard Henderson 

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, >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)) {
+