The following commit has been merged into the sched/core branch of tip:

Commit-ID:     ea366dd79c05fcd4cf5e225d2de8a3a7c293160c
Gitweb:        
https://git.kernel.org/tip/ea366dd79c05fcd4cf5e225d2de8a3a7c293160c
Author:        Peter Oskolkov <p...@google.com>
AuthorDate:    Wed, 23 Sep 2020 16:36:17 -07:00
Committer:     Peter Zijlstra <pet...@infradead.org>
CommitterDate: Fri, 25 Sep 2020 14:23:27 +02:00

rseq/selftests,x86_64: Add rseq_offset_deref_addv()

This patch adds rseq_offset_deref_addv() function to
tools/testing/selftests/rseq/rseq-x86.h, to be used in a selftest in
the next patch in the patchset.

Once an architecture adds support for this function they should define
"RSEQ_ARCH_HAS_OFFSET_DEREF_ADDV".

Signed-off-by: Peter Oskolkov <p...@google.com>
Signed-off-by: Peter Zijlstra (Intel) <pet...@infradead.org>
Acked-by: Mathieu Desnoyers <mathieu.desnoy...@efficios.com>
Link: https://lkml.kernel.org/r/20200923233618.2572849-2-p...@google.com
---
 tools/testing/selftests/rseq/rseq-x86.h | 57 ++++++++++++++++++++++++-
 1 file changed, 57 insertions(+)

diff --git a/tools/testing/selftests/rseq/rseq-x86.h 
b/tools/testing/selftests/rseq/rseq-x86.h
index b2da600..6404115 100644
--- a/tools/testing/selftests/rseq/rseq-x86.h
+++ b/tools/testing/selftests/rseq/rseq-x86.h
@@ -279,6 +279,63 @@ error1:
 #endif
 }
 
+#define RSEQ_ARCH_HAS_OFFSET_DEREF_ADDV
+
+/*
+ *   pval = *(ptr+off)
+ *  *pval += inc;
+ */
+static inline __attribute__((always_inline))
+int rseq_offset_deref_addv(intptr_t *ptr, off_t off, intptr_t inc, int cpu)
+{
+       RSEQ_INJECT_C(9)
+
+       __asm__ __volatile__ goto (
+               RSEQ_ASM_DEFINE_TABLE(3, 1f, 2f, 4f) /* start, commit, abort */
+#ifdef RSEQ_COMPARE_TWICE
+               RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error1])
+#endif
+               /* Start rseq by storing table entry pointer into rseq_cs. */
+               RSEQ_ASM_STORE_RSEQ_CS(1, 3b, RSEQ_CS_OFFSET(%[rseq_abi]))
+               RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_CPU_ID_OFFSET(%[rseq_abi]), 4f)
+               RSEQ_INJECT_ASM(3)
+#ifdef RSEQ_COMPARE_TWICE
+               RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_CPU_ID_OFFSET(%[rseq_abi]), 
%l[error1])
+#endif
+               /* get p+v */
+               "movq %[ptr], %%rbx\n\t"
+               "addq %[off], %%rbx\n\t"
+               /* get pv */
+               "movq (%%rbx), %%rcx\n\t"
+               /* *pv += inc */
+               "addq %[inc], (%%rcx)\n\t"
+               "2:\n\t"
+               RSEQ_INJECT_ASM(4)
+               RSEQ_ASM_DEFINE_ABORT(4, "", abort)
+               : /* gcc asm goto does not allow outputs */
+               : [cpu_id]              "r" (cpu),
+                 [rseq_abi]            "r" (&__rseq_abi),
+                 /* final store input */
+                 [ptr]                 "m" (*ptr),
+                 [off]                 "er" (off),
+                 [inc]                 "er" (inc)
+               : "memory", "cc", "rax", "rbx", "rcx"
+                 RSEQ_INJECT_CLOBBER
+               : abort
+#ifdef RSEQ_COMPARE_TWICE
+                 , error1
+#endif
+       );
+       return 0;
+abort:
+       RSEQ_INJECT_FAILED
+       return -1;
+#ifdef RSEQ_COMPARE_TWICE
+error1:
+       rseq_bug("cpu_id comparison failed");
+#endif
+}
+
 static inline __attribute__((always_inline))
 int rseq_cmpeqv_trystorev_storev(intptr_t *v, intptr_t expect,
                                 intptr_t *v2, intptr_t newv2,

Reply via email to