From: Mark Rutland <[email protected]>

This patch implements ifence_array_ptr() for arm64, using an
LDR+CSEL+CSDB sequence to inhibit speculative use of the returned value.

Signed-off-by: Mark Rutland <[email protected]>
Signed-off-by: Will Deacon <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Signed-off-by: Dan Williams <[email protected]>
---
 arch/arm64/include/asm/barrier.h |   24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/arch/arm64/include/asm/barrier.h b/arch/arm64/include/asm/barrier.h
index 77651c49ef44..74ffcddb26e6 100644
--- a/arch/arm64/include/asm/barrier.h
+++ b/arch/arm64/include/asm/barrier.h
@@ -40,6 +40,30 @@
 #define dma_rmb()      dmb(oshld)
 #define dma_wmb()      dmb(oshst)
 
+#define ifence_array_ptr(arr, idx, sz)                                 \
+({                                                                     \
+       typeof(&(arr)[0]) __nap_arr = (arr);                            \
+       typeof(idx) __nap_idx = (idx);                                  \
+       typeof(sz) __nap_sz = (sz);                                     \
+                                                                       \
+       unsigned long __nap_ptr = (unsigned long)__nap_arr +            \
+                                 sizeof(__nap_arr[0]) * idx;           \
+                                                                       \
+       asm volatile(                                                   \
+       "       cmp     %[i], %[s]\n"                                   \
+       "       b.cs    1f\n"                                           \
+       "       ldr     %[p], %[pp]\n"                                  \
+       "1:     csel    %[p], %[p], xzr, cc\n"                          \
+       "       hint    #0x14 // CSDB\n"                                \
+       : [p] "=&r" (__nap_ptr)                                         \
+       : [pp] "m" (__nap_ptr),                                         \
+         [i] "r" ((unsigned long)__nap_idx),                           \
+         [s] "r" ((unsigned long)__nap_sz)                             \
+       : "cc");                                                        \
+                                                                       \
+       (typeof(&(__nap_arr)[0]))__nap_ptr;                             \
+})
+
 #define __smp_mb()     dmb(ish)
 #define __smp_rmb()    dmb(ishld)
 #define __smp_wmb()    dmb(ishst)

Reply via email to