diff mbox series

[v2,22/27] target/arm: Implement pauth_addpac

Message ID 20181214052410.11863-23-richard.henderson@linaro.org
State New
Headers show
Series target/arm: Implement ARMv8.3-PAuth | expand

Commit Message

Richard Henderson Dec. 14, 2018, 5:24 a.m. UTC
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(-)

-- 
2.17.2

Comments

Peter Maydell Jan. 7, 2019, 1:31 p.m. UTC | #1
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
Richard Henderson Jan. 8, 2019, 4:48 a.m. UTC | #2
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~
diff mbox series

Patch

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)