Merge tag 'linux-kselftest-5.2-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel...
[platform/kernel/linux-starfive.git] / tools / testing / selftests / rseq / rseq-s390.h
index 0afdf79..8ef94ad 100644 (file)
@@ -44,22 +44,54 @@ do {                                                                        \
 
 #define __RSEQ_ASM_DEFINE_TABLE(label, version, flags,                 \
                                start_ip, post_commit_offset, abort_ip) \
-               ".pushsection __rseq_table, \"aw\"\n\t"                 \
+               ".pushsection __rseq_cs, \"aw\"\n\t"                    \
                ".balign 32\n\t"                                        \
                __rseq_str(label) ":\n\t"                               \
                ".long " __rseq_str(version) ", " __rseq_str(flags) "\n\t" \
                ".quad " __rseq_str(start_ip) ", " __rseq_str(post_commit_offset) ", " __rseq_str(abort_ip) "\n\t" \
+               ".popsection\n\t"                                       \
+               ".pushsection __rseq_cs_ptr_array, \"aw\"\n\t"          \
+               ".quad " __rseq_str(label) "b\n\t"                      \
+               ".popsection\n\t"
+
+/*
+ * Exit points of a rseq critical section consist of all instructions outside
+ * of the critical section where a critical section can either branch to or
+ * reach through the normal course of its execution. The abort IP and the
+ * post-commit IP are already part of the __rseq_cs section and should not be
+ * explicitly defined as additional exit points. Knowing all exit points is
+ * useful to assist debuggers stepping over the critical section.
+ */
+#define RSEQ_ASM_DEFINE_EXIT_POINT(start_ip, exit_ip)                  \
+               ".pushsection __rseq_exit_point_array, \"aw\"\n\t"      \
+               ".quad " __rseq_str(start_ip) ", " __rseq_str(exit_ip) "\n\t" \
                ".popsection\n\t"
 
 #elif __s390__
 
 #define __RSEQ_ASM_DEFINE_TABLE(label, version, flags,                 \
                                start_ip, post_commit_offset, abort_ip) \
-               ".pushsection __rseq_table, \"aw\"\n\t"                 \
+               ".pushsection __rseq_cs, \"aw\"\n\t"                    \
                ".balign 32\n\t"                                        \
                __rseq_str(label) ":\n\t"                               \
                ".long " __rseq_str(version) ", " __rseq_str(flags) "\n\t" \
                ".long 0x0, " __rseq_str(start_ip) ", 0x0, " __rseq_str(post_commit_offset) ", 0x0, " __rseq_str(abort_ip) "\n\t" \
+               ".popsection\n\t"                                       \
+               ".pushsection __rseq_cs_ptr_array, \"aw\"\n\t"          \
+               ".long 0x0, " __rseq_str(label) "b\n\t"                 \
+               ".popsection\n\t"
+
+/*
+ * Exit points of a rseq critical section consist of all instructions outside
+ * of the critical section where a critical section can either branch to or
+ * reach through the normal course of its execution. The abort IP and the
+ * post-commit IP are already part of the __rseq_cs section and should not be
+ * explicitly defined as additional exit points. Knowing all exit points is
+ * useful to assist debuggers stepping over the critical section.
+ */
+#define RSEQ_ASM_DEFINE_EXIT_POINT(start_ip, exit_ip)                  \
+               ".pushsection __rseq_exit_point_array, \"aw\"\n\t"      \
+               ".long 0x0, " __rseq_str(start_ip) ", 0x0, " __rseq_str(exit_ip) "\n\t" \
                ".popsection\n\t"
 
 #define LONG_L                 "l"
@@ -92,14 +124,14 @@ do {                                                                       \
                ".long " __rseq_str(RSEQ_SIG) "\n\t"                    \
                __rseq_str(label) ":\n\t"                               \
                teardown                                                \
-               "j %l[" __rseq_str(abort_label) "]\n\t"                 \
+               "jg %l[" __rseq_str(abort_label) "]\n\t"                \
                ".popsection\n\t"
 
 #define RSEQ_ASM_DEFINE_CMPFAIL(label, teardown, cmpfail_label)                \
                ".pushsection __rseq_failure, \"ax\"\n\t"               \
                __rseq_str(label) ":\n\t"                               \
                teardown                                                \
-               "j %l[" __rseq_str(cmpfail_label) "]\n\t"               \
+               "jg %l[" __rseq_str(cmpfail_label) "]\n\t"              \
                ".popsection\n\t"
 
 static inline __attribute__((always_inline))
@@ -109,6 +141,11 @@ int rseq_cmpeqv_storev(intptr_t *v, intptr_t expect, intptr_t newv, int cpu)
 
        __asm__ __volatile__ goto (
                RSEQ_ASM_DEFINE_TABLE(3, 1f, 2f, 4f) /* start, commit, abort */
+               RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[cmpfail])
+#ifdef RSEQ_COMPARE_TWICE
+               RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error1])
+               RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error2])
+#endif
                /* Start rseq by storing table entry pointer into rseq_cs. */
                RSEQ_ASM_STORE_RSEQ_CS(1, 3b, rseq_cs)
                RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
@@ -167,6 +204,11 @@ int rseq_cmpnev_storeoffp_load(intptr_t *v, intptr_t expectnot,
 
        __asm__ __volatile__ goto (
                RSEQ_ASM_DEFINE_TABLE(3, 1f, 2f, 4f) /* start, commit, abort */
+               RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[cmpfail])
+#ifdef RSEQ_COMPARE_TWICE
+               RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error1])
+               RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error2])
+#endif
                /* Start rseq by storing table entry pointer into rseq_cs. */
                RSEQ_ASM_STORE_RSEQ_CS(1, 3b, rseq_cs)
                RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
@@ -227,6 +269,9 @@ int rseq_addv(intptr_t *v, intptr_t count, int cpu)
 
        __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)
                RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
@@ -275,6 +320,11 @@ int rseq_cmpeqv_trystorev_storev(intptr_t *v, intptr_t expect,
 
        __asm__ __volatile__ goto (
                RSEQ_ASM_DEFINE_TABLE(3, 1f, 2f, 4f) /* start, commit, abort */
+               RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[cmpfail])
+#ifdef RSEQ_COMPARE_TWICE
+               RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error1])
+               RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error2])
+#endif
                /* Start rseq by storing table entry pointer into rseq_cs. */
                RSEQ_ASM_STORE_RSEQ_CS(1, 3b, rseq_cs)
                RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
@@ -346,6 +396,12 @@ int rseq_cmpeqv_cmpeqv_storev(intptr_t *v, intptr_t expect,
 
        __asm__ __volatile__ goto (
                RSEQ_ASM_DEFINE_TABLE(3, 1f, 2f, 4f) /* start, commit, abort */
+               RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[cmpfail])
+#ifdef RSEQ_COMPARE_TWICE
+               RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error1])
+               RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error2])
+               RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error3])
+#endif
                /* Start rseq by storing table entry pointer into rseq_cs. */
                RSEQ_ASM_STORE_RSEQ_CS(1, 3b, rseq_cs)
                RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
@@ -414,6 +470,11 @@ int rseq_cmpeqv_trymemcpy_storev(intptr_t *v, intptr_t expect,
 
        __asm__ __volatile__ goto (
                RSEQ_ASM_DEFINE_TABLE(3, 1f, 2f, 4f) /* start, commit, abort */
+               RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[cmpfail])
+#ifdef RSEQ_COMPARE_TWICE
+               RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error1])
+               RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error2])
+#endif
                LONG_S " %[src], %[rseq_scratch0]\n\t"
                LONG_S " %[dst], %[rseq_scratch1]\n\t"
                LONG_S " %[len], %[rseq_scratch2]\n\t"