All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/3] selftests/rseq: Add 64bit LoongArch support
@ 2023-10-26 11:44 Huang Pei
  2023-10-26 11:44 ` [PATCH 2/3] LoongArch: Add RSEQ_SIG break code definition Huang Pei
  2023-10-26 12:07 ` [PATCH 1/3] selftests/rseq: Add 64bit LoongArch support Huacai Chen
  0 siblings, 2 replies; 5+ messages in thread
From: Huang Pei @ 2023-10-26 11:44 UTC (permalink / raw)
  To: Huacai Chen, Mathieu Desnoyers; +Cc: loongarch, linux-kernel

Signed-off-by: Huang Pei <huangpei@loongson.cn>
---
 tools/testing/selftests/rseq/param_test.c     |  20 +
 .../selftests/rseq/rseq-loongarch-bits.h      | 463 ++++++++++++++++++
 .../rseq/rseq-loongarch-thread-pointer.h      |  22 +
 tools/testing/selftests/rseq/rseq-loongarch.h | 140 ++++++
 .../selftests/rseq/rseq-thread-pointer.h      |   2 +
 tools/testing/selftests/rseq/rseq.h           |   2 +
 6 files changed, 649 insertions(+)
 create mode 100644 tools/testing/selftests/rseq/rseq-loongarch-bits.h
 create mode 100644 tools/testing/selftests/rseq/rseq-loongarch-thread-pointer.h
 create mode 100644 tools/testing/selftests/rseq/rseq-loongarch.h

diff --git a/tools/testing/selftests/rseq/param_test.c b/tools/testing/selftests/rseq/param_test.c
index bf951a490bb4..e930aa73c219 100644
--- a/tools/testing/selftests/rseq/param_test.c
+++ b/tools/testing/selftests/rseq/param_test.c
@@ -227,7 +227,27 @@ unsigned int yield_mod_cnt, nr_abort;
 	"bnez " INJECT_ASM_REG ", 222b\n\t"			\
 	"333:\n\t"
 
+#elif defined(__loongarch__)
+#define RSEQ_INJECT_INPUT \
+	, [loop_cnt_1]"m"(loop_cnt[1]) \
+	, [loop_cnt_2]"m"(loop_cnt[2]) \
+	, [loop_cnt_3]"m"(loop_cnt[3]) \
+	, [loop_cnt_4]"m"(loop_cnt[4]) \
+	, [loop_cnt_5]"m"(loop_cnt[5]) \
+	, [loop_cnt_6]"m"(loop_cnt[6])
+
+#define INJECT_ASM_REG  "$r12"
+
+#define RSEQ_INJECT_CLOBBER \
+	, INJECT_ASM_REG
 
+#define RSEQ_INJECT_ASM(n)                                      \
+	"ld.w " INJECT_ASM_REG ", %[loop_cnt_" #n "]\n\t"         \
+	"beqz " INJECT_ASM_REG ", 333f\n\t"                     \
+	"222:\n\t"                                              \
+	"addi.w  " INJECT_ASM_REG "," INJECT_ASM_REG ", -1\n\t"   \
+	"bnez " INJECT_ASM_REG ", 222b\n\t"                     \
+	"333:\n\t"
 #else
 #error unsupported target
 #endif
diff --git a/tools/testing/selftests/rseq/rseq-loongarch-bits.h b/tools/testing/selftests/rseq/rseq-loongarch-bits.h
new file mode 100644
index 000000000000..cf933c1a2100
--- /dev/null
+++ b/tools/testing/selftests/rseq/rseq-loongarch-bits.h
@@ -0,0 +1,463 @@
+/* SPDX-License-Identifier: LGPL-2.1 OR MIT */
+/*
+ * Author: Huang Pei <huangpei@loongson.cn>
+ * (C) Copyright 2023 Loongson Technology Corporation Limited
+ * (C) Copyright 2016-2022 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ * (C) Copyright 2018 MIPS Tech LLC
+ * (C) Copyright 2018 - Paul Burton <paul.burton@mips.com>
+ */
+#include "rseq-bits-template.h"
+
+#if defined(RSEQ_TEMPLATE_MO_RELAXED) && \
+	(defined(RSEQ_TEMPLATE_CPU_ID) || defined(RSEQ_TEMPLATE_MM_CID))
+
+static inline __attribute__((always_inline))
+int RSEQ_TEMPLATE_IDENTIFIER(rseq_cmpeqv_storev)(intptr_t *v, intptr_t expect, intptr_t newv, int cpu)
+{
+	RSEQ_INJECT_C(9)
+
+	__asm__ __volatile__ goto (
+		RSEQ_ASM_DEFINE_TABLE(9, 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, 3f, rseq_cs)
+		RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
+		RSEQ_INJECT_ASM(3)
+		LONG_L " $r4, %[v]\n\t"
+		"bne $r4, %[expect], %l[cmpfail]\n\t"
+		RSEQ_INJECT_ASM(4)
+#ifdef RSEQ_COMPARE_TWICE
+		RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, %l[error1])
+		LONG_L " $r4, %[v]\n\t"
+		"bne $r4, %[expect], %l[error2]\n\t"
+#endif
+		/* final store */
+		LONG_S " %[newv], %[v]\n\t"
+		"2:\n\t"
+		RSEQ_INJECT_ASM(5)
+		"b 5f\n\t"
+		RSEQ_ASM_DEFINE_ABORT(3, 4, "", abort, 1b, 2b, 4f)
+		"5:\n\t"
+		: /* gcc asm goto does not allow outputs */
+		: [cpu_id]		"r" (cpu),
+		  [current_cpu_id]	"m" (rseq_get_abi()->RSEQ_TEMPLATE_CPU_ID_FIELD),
+		  [rseq_cs]		"m" (rseq_get_abi()->rseq_cs.arch.ptr),
+		  [v]			"m" (*v),
+		  [expect]		"r" (expect),
+		  [newv]		"r" (newv)
+		  RSEQ_INJECT_INPUT
+		: "$r4", "memory"
+		  RSEQ_INJECT_CLOBBER
+		: abort, cmpfail
+#ifdef RSEQ_COMPARE_TWICE
+		  , error1, error2
+#endif
+	);
+	return 0;
+abort:
+	RSEQ_INJECT_FAILED
+	return -1;
+cmpfail:
+	return 1;
+#ifdef RSEQ_COMPARE_TWICE
+error1:
+	rseq_bug("cpu_id comparison failed");
+error2:
+	rseq_bug("expected value comparison failed");
+#endif
+}
+
+static inline __attribute__((always_inline))
+int RSEQ_TEMPLATE_IDENTIFIER(rseq_cmpnev_storeoffp_load)(intptr_t *v, intptr_t expectnot,
+			       long voffp, intptr_t *load, int cpu)
+{
+	RSEQ_INJECT_C(9)
+
+	__asm__ __volatile__ goto (
+		RSEQ_ASM_DEFINE_TABLE(9, 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, 3f, rseq_cs)
+		RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
+		RSEQ_INJECT_ASM(3)
+		LONG_L " $r4, %[v]\n\t"
+		"beq $r4, %[expectnot], %l[cmpfail]\n\t"
+		RSEQ_INJECT_ASM(4)
+#ifdef RSEQ_COMPARE_TWICE
+		RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, %l[error1])
+		LONG_L " $r4, %[v]\n\t"
+		"beq $r4, %[expectnot], %l[error2]\n\t"
+#endif
+		LONG_S " $r4, %[load]\n\t"
+		LONG_ADDI " $r4, $r4, %[voffp]\n\t"
+		LONG_L " $r4, $r4, 0\n\t"
+		/* final store */
+		LONG_S " $r4, %[v]\n\t"
+		"2:\n\t"
+		RSEQ_INJECT_ASM(5)
+		"b 5f\n\t"
+		RSEQ_ASM_DEFINE_ABORT(3, 4, "", abort, 1b, 2b, 4f)
+		"5:\n\t"
+		: /* gcc asm goto does not allow outputs */
+		: [cpu_id]		"r" (cpu),
+		  [current_cpu_id]	"m" (rseq_get_abi()->RSEQ_TEMPLATE_CPU_ID_FIELD),
+		  [rseq_cs]		"m" (rseq_get_abi()->rseq_cs.arch.ptr),
+		  /* final store input */
+		  [v]			"m" (*v),
+		  [expectnot]		"r" (expectnot),
+		  [voffp]		"Ir" (voffp),
+		  [load]		"m" (*load)
+		  RSEQ_INJECT_INPUT
+		: "$r4", "memory"
+		  RSEQ_INJECT_CLOBBER
+		: abort, cmpfail
+#ifdef RSEQ_COMPARE_TWICE
+		  , error1, error2
+#endif
+	);
+	return 0;
+abort:
+	RSEQ_INJECT_FAILED
+	return -1;
+cmpfail:
+	return 1;
+#ifdef RSEQ_COMPARE_TWICE
+error1:
+	rseq_bug("cpu_id comparison failed");
+error2:
+	rseq_bug("expected value comparison failed");
+#endif
+}
+
+static inline __attribute__((always_inline))
+int RSEQ_TEMPLATE_IDENTIFIER(rseq_addv)(intptr_t *v, intptr_t count, int cpu)
+{
+	RSEQ_INJECT_C(9)
+
+	__asm__ __volatile__ goto (
+		RSEQ_ASM_DEFINE_TABLE(9, 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, 3f, rseq_cs)
+		RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
+		RSEQ_INJECT_ASM(3)
+#ifdef RSEQ_COMPARE_TWICE
+		RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, %l[error1])
+#endif
+		LONG_L " $r4, %[v]\n\t"
+		LONG_ADDI " $r4, $r4, %[count]\n\t"
+		/* final store */
+		LONG_S " $r4, %[v]\n\t"
+		"2:\n\t"
+		RSEQ_INJECT_ASM(4)
+		"b 5f\n\t"
+		RSEQ_ASM_DEFINE_ABORT(3, 4, "", abort, 1b, 2b, 4f)
+		"5:\n\t"
+		: /* gcc asm goto does not allow outputs */
+		: [cpu_id]		"r" (cpu),
+		  [current_cpu_id]	"m" (rseq_get_abi()->RSEQ_TEMPLATE_CPU_ID_FIELD),
+		  [rseq_cs]		"m" (rseq_get_abi()->rseq_cs.arch.ptr),
+		  [v]			"m" (*v),
+		  [count]		"Ir" (count)
+		  RSEQ_INJECT_INPUT
+		: "$r4", "memory"
+		  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_TEMPLATE_IDENTIFIER(rseq_cmpeqv_cmpeqv_storev)(intptr_t *v, intptr_t expect,
+			      intptr_t *v2, intptr_t expect2,
+			      intptr_t newv, int cpu)
+{
+	RSEQ_INJECT_C(9)
+
+	__asm__ __volatile__ goto (
+		RSEQ_ASM_DEFINE_TABLE(9, 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, 3f, rseq_cs)
+		RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
+		RSEQ_INJECT_ASM(3)
+		LONG_L " $r4, %[v]\n\t"
+		"bne $r4, %[expect], %l[cmpfail]\n\t"
+		RSEQ_INJECT_ASM(4)
+		LONG_L " $r4, %[v2]\n\t"
+		"bne $r4, %[expect2], %l[cmpfail]\n\t"
+		RSEQ_INJECT_ASM(5)
+#ifdef RSEQ_COMPARE_TWICE
+		RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, %l[error1])
+		LONG_L " $r4, %[v]\n\t"
+		"bne $r4, %[expect], %l[error2]\n\t"
+		LONG_L " $r4, %[v2]\n\t"
+		"bne $r4, %[expect2], %l[error3]\n\t"
+#endif
+		/* final store */
+		LONG_S " %[newv], %[v]\n\t"
+		"2:\n\t"
+		RSEQ_INJECT_ASM(6)
+		"b 5f\n\t"
+		RSEQ_ASM_DEFINE_ABORT(3, 4, "", abort, 1b, 2b, 4f)
+		"5:\n\t"
+		: /* gcc asm goto does not allow outputs */
+		: [cpu_id]		"r" (cpu),
+		  [current_cpu_id]	"m" (rseq_get_abi()->RSEQ_TEMPLATE_CPU_ID_FIELD),
+		  [rseq_cs]		"m" (rseq_get_abi()->rseq_cs.arch.ptr),
+		  /* cmp2 input */
+		  [v2]			"m" (*v2),
+		  [expect2]		"r" (expect2),
+		  /* final store input */
+		  [v]			"m" (*v),
+		  [expect]		"r" (expect),
+		  [newv]		"r" (newv)
+		  RSEQ_INJECT_INPUT
+		: "$r4", "memory"
+		  RSEQ_INJECT_CLOBBER
+		: abort, cmpfail
+#ifdef RSEQ_COMPARE_TWICE
+		  , error1, error2, error3
+#endif
+	);
+	return 0;
+abort:
+	RSEQ_INJECT_FAILED
+	return -1;
+cmpfail:
+	return 1;
+#ifdef RSEQ_COMPARE_TWICE
+error1:
+	rseq_bug("cpu_id comparison failed");
+error2:
+	rseq_bug("1st expected value comparison failed");
+error3:
+	rseq_bug("2nd expected value comparison failed");
+#endif
+}
+
+#endif /* #if defined(RSEQ_TEMPLATE_MO_RELAXED) &&
+	(defined(RSEQ_TEMPLATE_CPU_ID) || defined(RSEQ_TEMPLATE_MM_CID)) */
+
+#if (defined(RSEQ_TEMPLATE_MO_RELAXED) || defined(RSEQ_TEMPLATE_MO_RELEASE)) && \
+	(defined(RSEQ_TEMPLATE_CPU_ID) || defined(RSEQ_TEMPLATE_MM_CID))
+
+static inline __attribute__((always_inline))
+int RSEQ_TEMPLATE_IDENTIFIER(rseq_cmpeqv_trystorev_storev)(intptr_t *v, intptr_t expect,
+				 intptr_t *v2, intptr_t newv2,
+				 intptr_t newv, int cpu)
+{
+	RSEQ_INJECT_C(9)
+
+	__asm__ __volatile__ goto (
+		RSEQ_ASM_DEFINE_TABLE(9, 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, 3f, rseq_cs)
+		RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
+		RSEQ_INJECT_ASM(3)
+		LONG_L " $r4, %[v]\n\t"
+		"bne $r4, %[expect], %l[cmpfail]\n\t"
+		RSEQ_INJECT_ASM(4)
+#ifdef RSEQ_COMPARE_TWICE
+		RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, %l[error1])
+		LONG_L " $r4, %[v]\n\t"
+		"bne $r4, %[expect], %l[error2]\n\t"
+#endif
+		/* try store */
+		LONG_S " %[newv2], %[v2]\n\t"
+		RSEQ_INJECT_ASM(5)
+#ifdef RSEQ_TEMPLATE_MO_RELEASE
+		"dbar 0x12\n\t"	/* store-release */
+#endif
+		/* final store */
+		LONG_S " %[newv], %[v]\n\t"
+		"2:\n\t"
+		RSEQ_INJECT_ASM(6)
+		"b 5f\n\t"
+		RSEQ_ASM_DEFINE_ABORT(3, 4, "", abort, 1b, 2b, 4f)
+		"5:\n\t"
+		: /* gcc asm goto does not allow outputs */
+		: [cpu_id]		"r" (cpu),
+		  [current_cpu_id]	"m" (rseq_get_abi()->RSEQ_TEMPLATE_CPU_ID_FIELD),
+		  [rseq_cs]		"m" (rseq_get_abi()->rseq_cs.arch.ptr),
+		  /* try store input */
+		  [v2]			"m" (*v2),
+		  [newv2]		"r" (newv2),
+		  /* final store input */
+		  [v]			"m" (*v),
+		  [expect]		"r" (expect),
+		  [newv]		"r" (newv)
+		  RSEQ_INJECT_INPUT
+		: "$r4", "memory"
+		  RSEQ_INJECT_CLOBBER
+		: abort, cmpfail
+#ifdef RSEQ_COMPARE_TWICE
+		  , error1, error2
+#endif
+	);
+	return 0;
+abort:
+	RSEQ_INJECT_FAILED
+	return -1;
+cmpfail:
+	return 1;
+#ifdef RSEQ_COMPARE_TWICE
+error1:
+	rseq_bug("cpu_id comparison failed");
+error2:
+	rseq_bug("expected value comparison failed");
+#endif
+}
+
+static inline __attribute__((always_inline))
+int RSEQ_TEMPLATE_IDENTIFIER(rseq_cmpeqv_trymemcpy_storev)(intptr_t *v, intptr_t expect,
+				 void *dst, void *src, size_t len,
+				 intptr_t newv, int cpu)
+{
+	uintptr_t rseq_scratch[3];
+
+	RSEQ_INJECT_C(9)
+
+	__asm__ __volatile__ goto (
+		RSEQ_ASM_DEFINE_TABLE(9, 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"
+		/* Start rseq by storing table entry pointer into rseq_cs. */
+		RSEQ_ASM_STORE_RSEQ_CS(1, 3f, rseq_cs)
+		RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
+		RSEQ_INJECT_ASM(3)
+		LONG_L " $r4, %[v]\n\t"
+		"bne $r4, %[expect], 5f\n\t"
+		RSEQ_INJECT_ASM(4)
+#ifdef RSEQ_COMPARE_TWICE
+		RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 6f)
+		LONG_L " $r4, %[v]\n\t"
+		"bne $r4, %[expect], 7f\n\t"
+#endif
+		/* try memcpy */
+		"beqz %[len], 333f\n\t" \
+		"222:\n\t" \
+		"ld.b  $r4, %[src], 0\n\t" \
+		"st.b  $r4, %[dst], 0\n\t" \
+		LONG_ADDI " %[src], %[src], 1\n\t" \
+		LONG_ADDI " %[dst], %[dst], 1\n\t" \
+		LONG_ADDI " %[len], %[len], -1\n\t" \
+		"bnez %[len], 222b\n\t" \
+		"333:\n\t" \
+		RSEQ_INJECT_ASM(5)
+#ifdef RSEQ_TEMPLATE_MO_RELEASE
+		"dbar 0x12\n\t"	/* store-release */
+#endif
+		/* final store */
+		LONG_S " %[newv], %[v]\n\t"
+		"2:\n\t"
+		RSEQ_INJECT_ASM(6)
+		/* teardown */
+		LONG_L " %[len], %[rseq_scratch2]\n\t"
+		LONG_L " %[dst], %[rseq_scratch1]\n\t"
+		LONG_L " %[src], %[rseq_scratch0]\n\t"
+		"b 8f\n\t"
+		RSEQ_ASM_DEFINE_ABORT(3, 4,
+				      /* teardown */
+				      LONG_L " %[len], %[rseq_scratch2]\n\t"
+				      LONG_L " %[dst], %[rseq_scratch1]\n\t"
+				      LONG_L " %[src], %[rseq_scratch0]\n\t",
+				      abort, 1b, 2b, 4f)
+		RSEQ_ASM_DEFINE_CMPFAIL(5,
+					/* teardown */
+					LONG_L " %[len], %[rseq_scratch2]\n\t"
+					LONG_L " %[dst], %[rseq_scratch1]\n\t"
+					LONG_L " %[src], %[rseq_scratch0]\n\t",
+					cmpfail)
+#ifdef RSEQ_COMPARE_TWICE
+		RSEQ_ASM_DEFINE_CMPFAIL(6,
+					/* teardown */
+					LONG_L " %[len], %[rseq_scratch2]\n\t"
+					LONG_L " %[dst], %[rseq_scratch1]\n\t"
+					LONG_L " %[src], %[rseq_scratch0]\n\t",
+					error1)
+		RSEQ_ASM_DEFINE_CMPFAIL(7,
+					/* teardown */
+					LONG_L " %[len], %[rseq_scratch2]\n\t"
+					LONG_L " %[dst], %[rseq_scratch1]\n\t"
+					LONG_L " %[src], %[rseq_scratch0]\n\t",
+					error2)
+#endif
+		"8:\n\t"
+		: /* gcc asm goto does not allow outputs */
+		: [cpu_id]		"r" (cpu),
+		  [current_cpu_id]	"m" (rseq_get_abi()->RSEQ_TEMPLATE_CPU_ID_FIELD),
+		  [rseq_cs]		"m" (rseq_get_abi()->rseq_cs.arch.ptr),
+		  /* final store input */
+		  [v]			"m" (*v),
+		  [expect]		"r" (expect),
+		  [newv]		"r" (newv),
+		  /* try memcpy input */
+		  [dst]			"r" (dst),
+		  [src]			"r" (src),
+		  [len]			"r" (len),
+		  [rseq_scratch0]	"m" (rseq_scratch[0]),
+		  [rseq_scratch1]	"m" (rseq_scratch[1]),
+		  [rseq_scratch2]	"m" (rseq_scratch[2])
+		  RSEQ_INJECT_INPUT
+		: "$r4", "memory"
+		  RSEQ_INJECT_CLOBBER
+		: abort, cmpfail
+#ifdef RSEQ_COMPARE_TWICE
+		  , error1, error2
+#endif
+	);
+	return 0;
+abort:
+	RSEQ_INJECT_FAILED
+	return -1;
+cmpfail:
+	return 1;
+#ifdef RSEQ_COMPARE_TWICE
+error1:
+	rseq_bug("cpu_id comparison failed");
+error2:
+	rseq_bug("expected value comparison failed");
+#endif
+}
+
+#endif /* #if (defined(RSEQ_TEMPLATE_MO_RELAXED) || defined(RSEQ_TEMPLATE_MO_RELEASE)) &&
+	(defined(RSEQ_TEMPLATE_CPU_ID) || defined(RSEQ_TEMPLATE_MM_CID)) */
+
+#include "rseq-bits-reset.h"
diff --git a/tools/testing/selftests/rseq/rseq-loongarch-thread-pointer.h b/tools/testing/selftests/rseq/rseq-loongarch-thread-pointer.h
new file mode 100644
index 000000000000..7dc990687982
--- /dev/null
+++ b/tools/testing/selftests/rseq/rseq-loongarch-thread-pointer.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: MIT */
+/* SPDX-FileCopyrightText: 2023 Huang Pei <huangpei@loongson.cn> */
+
+#ifndef _RSEQ_LOONGARCH_THREAD_POINTER
+#define _RSEQ_LOONGARCH_THREAD_POINTER
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+static inline void *rseq_thread_pointer(void)
+{
+	register void *__result asm ("$2");
+	asm ("" : "=r" (__result));
+	return __result;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/tools/testing/selftests/rseq/rseq-loongarch.h b/tools/testing/selftests/rseq/rseq-loongarch.h
new file mode 100644
index 000000000000..37aae463edde
--- /dev/null
+++ b/tools/testing/selftests/rseq/rseq-loongarch.h
@@ -0,0 +1,140 @@
+/* SPDX-License-Identifier: LGPL-2.1 OR MIT */
+/*
+ * Author: Huang Pei <huangpei@loongson.cn>
+ * (C) Copyright 2023 Loongson Technology Corporation Limited
+ * (C) Copyright 2016-2022 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ * (C) Copyright 2018 MIPS Tech LLC
+ * (C) Copyright 2018 - Paul Burton <paul.burton@mips.com>
+ */
+
+/*
+ * RSEQ_SIG use "break 0x10" instruction.
+ */
+
+# define RSEQ_SIG	0x002a0010
+
+
+
+#define rseq_smp_mb()	__asm__ __volatile__ ("dbar 0x10" ::: "memory")
+#define rseq_smp_rmb()	__asm__ __volatile__ ("dbar 0x15" ::: "memory")
+#define rseq_smp_wmb()	__asm__ __volatile__ ("dbar 0x1a" ::: "memory")
+
+#define rseq_smp_load_acquire(p)					\
+__extension__ ({							\
+	rseq_unqual_scalar_typeof(*(p)) ____p1 = RSEQ_READ_ONCE(*(p));	\
+	__asm__ __volatile__("dbar 0x14" :::  "memory");		\
+	____p1;								\
+})
+
+#define rseq_smp_acquire__after_ctrl_dep()	rseq_smp_rmb()
+
+#define rseq_smp_store_release(p, v)					\
+do {									\
+	__asm__ __volatile__("dbar 0x12" :::  "memory");		\
+	RSEQ_WRITE_ONCE(*(p), v);					\
+} while (0)
+
+# define LONG			".dword"
+# define LONG_LA		"la.local"
+# define LONG_L			"ld.d"
+# define LONG_S			"st.d"
+# define LONG_ADDI		"addi.d"
+# define U32_U64_PAD(x)		x
+
+#define __RSEQ_ASM_DEFINE_TABLE(label, version, flags, start_ip, \
+				post_commit_offset, abort_ip) \
+		".pushsection __rseq_cs, \"aw\"\n\t" \
+		".balign 32\n\t" \
+		__rseq_str(label) ":\n\t"					\
+		".word " __rseq_str(version) ", " __rseq_str(flags) "\n\t" \
+		LONG " " U32_U64_PAD(__rseq_str(start_ip)) "\n\t" \
+		LONG " " U32_U64_PAD(__rseq_str(post_commit_offset)) "\n\t" \
+		LONG " " U32_U64_PAD(__rseq_str(abort_ip)) "\n\t" \
+		".popsection\n\t" \
+		".pushsection __rseq_cs_ptr_array, \"aw\"\n\t" \
+		LONG " " U32_U64_PAD(__rseq_str(label) "b") "\n\t" \
+		".popsection\n\t"
+
+#define RSEQ_ASM_DEFINE_TABLE(label, start_ip, post_commit_ip, abort_ip) \
+	__RSEQ_ASM_DEFINE_TABLE(label, 0x0, 0x0, start_ip, \
+				(post_commit_ip - start_ip), abort_ip)
+/*
+ * 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 " " U32_U64_PAD(__rseq_str(start_ip)) "\n\t" \
+		LONG " " U32_U64_PAD(__rseq_str(exit_ip)) "\n\t" \
+		".popsection\n\t"
+
+#define RSEQ_ASM_STORE_RSEQ_CS(label, cs_label, rseq_cs) \
+		RSEQ_INJECT_ASM(1) \
+		LONG_LA " $r4, " __rseq_str(cs_label) "\n\t" \
+		LONG_S  " $r4, %[" __rseq_str(rseq_cs) "]\n\t" \
+		__rseq_str(label) ":\n\t"
+
+#define RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, label) \
+		RSEQ_INJECT_ASM(2) \
+		"ld.w  $r4, %[" __rseq_str(current_cpu_id) "]\n\t" \
+		"bne $r4, %[" __rseq_str(cpu_id) "], " __rseq_str(label) "\n\t"
+
+#define __RSEQ_ASM_DEFINE_ABORT(table_label, label, teardown, \
+				abort_label, version, flags, \
+				start_ip, post_commit_offset, abort_ip) \
+		".balign 32\n\t" \
+		__rseq_str(table_label) ":\n\t" \
+		".word " __rseq_str(version) ", " __rseq_str(flags) "\n\t" \
+		LONG " " U32_U64_PAD(__rseq_str(start_ip)) "\n\t" \
+		LONG " " U32_U64_PAD(__rseq_str(post_commit_offset)) "\n\t" \
+		LONG " " U32_U64_PAD(__rseq_str(abort_ip)) "\n\t" \
+		".word " __rseq_str(RSEQ_SIG) "\n\t" \
+		__rseq_str(label) ":\n\t" \
+		teardown \
+		"b %l[" __rseq_str(abort_label) "]\n\t"
+
+#define RSEQ_ASM_DEFINE_ABORT(table_label, label, teardown, abort_label, \
+			      start_ip, post_commit_ip, abort_ip) \
+	__RSEQ_ASM_DEFINE_ABORT(table_label, label, teardown, \
+				abort_label, 0x0, 0x0, start_ip, \
+				(post_commit_ip - start_ip), abort_ip)
+
+#define RSEQ_ASM_DEFINE_CMPFAIL(label, teardown, cmpfail_label) \
+		__rseq_str(label) ":\n\t" \
+		teardown \
+		"b %l[" __rseq_str(cmpfail_label) "]\n\t"
+
+/* Per-cpu-id indexing. */
+#define RSEQ_TEMPLATE_CPU_ID
+#define RSEQ_TEMPLATE_MO_RELAXED
+#include "rseq-loongarch-bits.h"
+#undef RSEQ_TEMPLATE_MO_RELAXED
+
+#define RSEQ_TEMPLATE_MO_RELEASE
+#include "rseq-loongarch-bits.h"
+#undef RSEQ_TEMPLATE_MO_RELEASE
+#undef RSEQ_TEMPLATE_CPU_ID
+
+/* Per-mm-cid indexing. */
+
+#define RSEQ_TEMPLATE_MM_CID
+#define RSEQ_TEMPLATE_MO_RELAXED
+#include "rseq-loongarch-bits.h"
+#undef RSEQ_TEMPLATE_MO_RELAXED
+
+#define RSEQ_TEMPLATE_MO_RELEASE
+#include "rseq-loongarch-bits.h"
+#undef RSEQ_TEMPLATE_MO_RELEASE
+#undef RSEQ_TEMPLATE_MM_CID
+
+/* APIs which are not based on cpu ids. */
+
+#define RSEQ_TEMPLATE_CPU_ID_NONE
+#define RSEQ_TEMPLATE_MO_RELAXED
+#include "rseq-loongarch-bits.h"
+#undef RSEQ_TEMPLATE_MO_RELAXED
+#undef RSEQ_TEMPLATE_CPU_ID_NONE
diff --git a/tools/testing/selftests/rseq/rseq-thread-pointer.h b/tools/testing/selftests/rseq/rseq-thread-pointer.h
index 977c25d758b2..b9c8fe7c4683 100644
--- a/tools/testing/selftests/rseq/rseq-thread-pointer.h
+++ b/tools/testing/selftests/rseq/rseq-thread-pointer.h
@@ -12,6 +12,8 @@
 #include "rseq-x86-thread-pointer.h"
 #elif defined(__PPC__)
 #include "rseq-ppc-thread-pointer.h"
+#elif defined(__loongarch__)
+#include "rseq-loongarch-thread-pointer.h"
 #else
 #include "rseq-generic-thread-pointer.h"
 #endif
diff --git a/tools/testing/selftests/rseq/rseq.h b/tools/testing/selftests/rseq/rseq.h
index d7364ea4d201..75c4bbe013d3 100644
--- a/tools/testing/selftests/rseq/rseq.h
+++ b/tools/testing/selftests/rseq/rseq.h
@@ -128,6 +128,8 @@ static inline struct rseq_abi *rseq_get_abi(void)
 #include <rseq-s390.h>
 #elif defined(__riscv)
 #include <rseq-riscv.h>
+#elif defined(__loongarch__)
+#include <rseq-loongarch.h>
 #else
 #error unsupported target
 #endif
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 2/3] LoongArch: Add RSEQ_SIG break code definition
  2023-10-26 11:44 [PATCH 1/3] selftests/rseq: Add 64bit LoongArch support Huang Pei
@ 2023-10-26 11:44 ` Huang Pei
  2023-10-26 18:07   ` Mathieu Desnoyers
  2023-10-26 12:07 ` [PATCH 1/3] selftests/rseq: Add 64bit LoongArch support Huacai Chen
  1 sibling, 1 reply; 5+ messages in thread
From: Huang Pei @ 2023-10-26 11:44 UTC (permalink / raw)
  To: Huacai Chen, Mathieu Desnoyers; +Cc: loongarch, linux-kernel

Signed-off-by: Huang Pei <huangpei@loongson.cn>
---
 arch/loongarch/include/uapi/asm/break.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/loongarch/include/uapi/asm/break.h b/arch/loongarch/include/uapi/asm/break.h
index bb9b82ba59f2..e0fcfc304834 100644
--- a/arch/loongarch/include/uapi/asm/break.h
+++ b/arch/loongarch/include/uapi/asm/break.h
@@ -20,4 +20,6 @@
 #define BRK_UPROBE_BP		12	/* See <asm/uprobes.h> */
 #define BRK_UPROBE_XOLBP	13	/* See <asm/uprobes.h> */
 
+#define BRK_RSEQ_SIG		16	/* See rseq */
+
 #endif /* __UAPI_ASM_BREAK_H */
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/3] selftests/rseq: Add 64bit LoongArch support
  2023-10-26 11:44 [PATCH 1/3] selftests/rseq: Add 64bit LoongArch support Huang Pei
  2023-10-26 11:44 ` [PATCH 2/3] LoongArch: Add RSEQ_SIG break code definition Huang Pei
@ 2023-10-26 12:07 ` Huacai Chen
  1 sibling, 0 replies; 5+ messages in thread
From: Huacai Chen @ 2023-10-26 12:07 UTC (permalink / raw)
  To: Huang Pei; +Cc: Huacai Chen, Mathieu Desnoyers, loongarch, linux-kernel

Hi,

1, The two patches should be marked as [1/2] and [2/2], not [1/3] and [2/3].
2, It is better to exchange the two patches' order.
3, Please add some commit messages, don't leave empty.

Huacai

On Thu, Oct 26, 2023 at 7:45 PM Huang Pei <huangpei@loongson.cn> wrote:
>
> Signed-off-by: Huang Pei <huangpei@loongson.cn>
> ---
>  tools/testing/selftests/rseq/param_test.c     |  20 +
>  .../selftests/rseq/rseq-loongarch-bits.h      | 463 ++++++++++++++++++
>  .../rseq/rseq-loongarch-thread-pointer.h      |  22 +
>  tools/testing/selftests/rseq/rseq-loongarch.h | 140 ++++++
>  .../selftests/rseq/rseq-thread-pointer.h      |   2 +
>  tools/testing/selftests/rseq/rseq.h           |   2 +
>  6 files changed, 649 insertions(+)
>  create mode 100644 tools/testing/selftests/rseq/rseq-loongarch-bits.h
>  create mode 100644 tools/testing/selftests/rseq/rseq-loongarch-thread-pointer.h
>  create mode 100644 tools/testing/selftests/rseq/rseq-loongarch.h
>
> diff --git a/tools/testing/selftests/rseq/param_test.c b/tools/testing/selftests/rseq/param_test.c
> index bf951a490bb4..e930aa73c219 100644
> --- a/tools/testing/selftests/rseq/param_test.c
> +++ b/tools/testing/selftests/rseq/param_test.c
> @@ -227,7 +227,27 @@ unsigned int yield_mod_cnt, nr_abort;
>         "bnez " INJECT_ASM_REG ", 222b\n\t"                     \
>         "333:\n\t"
>
> +#elif defined(__loongarch__)
> +#define RSEQ_INJECT_INPUT \
> +       , [loop_cnt_1]"m"(loop_cnt[1]) \
> +       , [loop_cnt_2]"m"(loop_cnt[2]) \
> +       , [loop_cnt_3]"m"(loop_cnt[3]) \
> +       , [loop_cnt_4]"m"(loop_cnt[4]) \
> +       , [loop_cnt_5]"m"(loop_cnt[5]) \
> +       , [loop_cnt_6]"m"(loop_cnt[6])
> +
> +#define INJECT_ASM_REG  "$r12"
> +
> +#define RSEQ_INJECT_CLOBBER \
> +       , INJECT_ASM_REG
>
> +#define RSEQ_INJECT_ASM(n)                                      \
> +       "ld.w " INJECT_ASM_REG ", %[loop_cnt_" #n "]\n\t"         \
> +       "beqz " INJECT_ASM_REG ", 333f\n\t"                     \
> +       "222:\n\t"                                              \
> +       "addi.w  " INJECT_ASM_REG "," INJECT_ASM_REG ", -1\n\t"   \
> +       "bnez " INJECT_ASM_REG ", 222b\n\t"                     \
> +       "333:\n\t"
>  #else
>  #error unsupported target
>  #endif
> diff --git a/tools/testing/selftests/rseq/rseq-loongarch-bits.h b/tools/testing/selftests/rseq/rseq-loongarch-bits.h
> new file mode 100644
> index 000000000000..cf933c1a2100
> --- /dev/null
> +++ b/tools/testing/selftests/rseq/rseq-loongarch-bits.h
> @@ -0,0 +1,463 @@
> +/* SPDX-License-Identifier: LGPL-2.1 OR MIT */
> +/*
> + * Author: Huang Pei <huangpei@loongson.cn>
> + * (C) Copyright 2023 Loongson Technology Corporation Limited
> + * (C) Copyright 2016-2022 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
> + * (C) Copyright 2018 MIPS Tech LLC
> + * (C) Copyright 2018 - Paul Burton <paul.burton@mips.com>
> + */
> +#include "rseq-bits-template.h"
> +
> +#if defined(RSEQ_TEMPLATE_MO_RELAXED) && \
> +       (defined(RSEQ_TEMPLATE_CPU_ID) || defined(RSEQ_TEMPLATE_MM_CID))
> +
> +static inline __attribute__((always_inline))
> +int RSEQ_TEMPLATE_IDENTIFIER(rseq_cmpeqv_storev)(intptr_t *v, intptr_t expect, intptr_t newv, int cpu)
> +{
> +       RSEQ_INJECT_C(9)
> +
> +       __asm__ __volatile__ goto (
> +               RSEQ_ASM_DEFINE_TABLE(9, 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, 3f, rseq_cs)
> +               RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
> +               RSEQ_INJECT_ASM(3)
> +               LONG_L " $r4, %[v]\n\t"
> +               "bne $r4, %[expect], %l[cmpfail]\n\t"
> +               RSEQ_INJECT_ASM(4)
> +#ifdef RSEQ_COMPARE_TWICE
> +               RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, %l[error1])
> +               LONG_L " $r4, %[v]\n\t"
> +               "bne $r4, %[expect], %l[error2]\n\t"
> +#endif
> +               /* final store */
> +               LONG_S " %[newv], %[v]\n\t"
> +               "2:\n\t"
> +               RSEQ_INJECT_ASM(5)
> +               "b 5f\n\t"
> +               RSEQ_ASM_DEFINE_ABORT(3, 4, "", abort, 1b, 2b, 4f)
> +               "5:\n\t"
> +               : /* gcc asm goto does not allow outputs */
> +               : [cpu_id]              "r" (cpu),
> +                 [current_cpu_id]      "m" (rseq_get_abi()->RSEQ_TEMPLATE_CPU_ID_FIELD),
> +                 [rseq_cs]             "m" (rseq_get_abi()->rseq_cs.arch.ptr),
> +                 [v]                   "m" (*v),
> +                 [expect]              "r" (expect),
> +                 [newv]                "r" (newv)
> +                 RSEQ_INJECT_INPUT
> +               : "$r4", "memory"
> +                 RSEQ_INJECT_CLOBBER
> +               : abort, cmpfail
> +#ifdef RSEQ_COMPARE_TWICE
> +                 , error1, error2
> +#endif
> +       );
> +       return 0;
> +abort:
> +       RSEQ_INJECT_FAILED
> +       return -1;
> +cmpfail:
> +       return 1;
> +#ifdef RSEQ_COMPARE_TWICE
> +error1:
> +       rseq_bug("cpu_id comparison failed");
> +error2:
> +       rseq_bug("expected value comparison failed");
> +#endif
> +}
> +
> +static inline __attribute__((always_inline))
> +int RSEQ_TEMPLATE_IDENTIFIER(rseq_cmpnev_storeoffp_load)(intptr_t *v, intptr_t expectnot,
> +                              long voffp, intptr_t *load, int cpu)
> +{
> +       RSEQ_INJECT_C(9)
> +
> +       __asm__ __volatile__ goto (
> +               RSEQ_ASM_DEFINE_TABLE(9, 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, 3f, rseq_cs)
> +               RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
> +               RSEQ_INJECT_ASM(3)
> +               LONG_L " $r4, %[v]\n\t"
> +               "beq $r4, %[expectnot], %l[cmpfail]\n\t"
> +               RSEQ_INJECT_ASM(4)
> +#ifdef RSEQ_COMPARE_TWICE
> +               RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, %l[error1])
> +               LONG_L " $r4, %[v]\n\t"
> +               "beq $r4, %[expectnot], %l[error2]\n\t"
> +#endif
> +               LONG_S " $r4, %[load]\n\t"
> +               LONG_ADDI " $r4, $r4, %[voffp]\n\t"
> +               LONG_L " $r4, $r4, 0\n\t"
> +               /* final store */
> +               LONG_S " $r4, %[v]\n\t"
> +               "2:\n\t"
> +               RSEQ_INJECT_ASM(5)
> +               "b 5f\n\t"
> +               RSEQ_ASM_DEFINE_ABORT(3, 4, "", abort, 1b, 2b, 4f)
> +               "5:\n\t"
> +               : /* gcc asm goto does not allow outputs */
> +               : [cpu_id]              "r" (cpu),
> +                 [current_cpu_id]      "m" (rseq_get_abi()->RSEQ_TEMPLATE_CPU_ID_FIELD),
> +                 [rseq_cs]             "m" (rseq_get_abi()->rseq_cs.arch.ptr),
> +                 /* final store input */
> +                 [v]                   "m" (*v),
> +                 [expectnot]           "r" (expectnot),
> +                 [voffp]               "Ir" (voffp),
> +                 [load]                "m" (*load)
> +                 RSEQ_INJECT_INPUT
> +               : "$r4", "memory"
> +                 RSEQ_INJECT_CLOBBER
> +               : abort, cmpfail
> +#ifdef RSEQ_COMPARE_TWICE
> +                 , error1, error2
> +#endif
> +       );
> +       return 0;
> +abort:
> +       RSEQ_INJECT_FAILED
> +       return -1;
> +cmpfail:
> +       return 1;
> +#ifdef RSEQ_COMPARE_TWICE
> +error1:
> +       rseq_bug("cpu_id comparison failed");
> +error2:
> +       rseq_bug("expected value comparison failed");
> +#endif
> +}
> +
> +static inline __attribute__((always_inline))
> +int RSEQ_TEMPLATE_IDENTIFIER(rseq_addv)(intptr_t *v, intptr_t count, int cpu)
> +{
> +       RSEQ_INJECT_C(9)
> +
> +       __asm__ __volatile__ goto (
> +               RSEQ_ASM_DEFINE_TABLE(9, 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, 3f, rseq_cs)
> +               RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
> +               RSEQ_INJECT_ASM(3)
> +#ifdef RSEQ_COMPARE_TWICE
> +               RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, %l[error1])
> +#endif
> +               LONG_L " $r4, %[v]\n\t"
> +               LONG_ADDI " $r4, $r4, %[count]\n\t"
> +               /* final store */
> +               LONG_S " $r4, %[v]\n\t"
> +               "2:\n\t"
> +               RSEQ_INJECT_ASM(4)
> +               "b 5f\n\t"
> +               RSEQ_ASM_DEFINE_ABORT(3, 4, "", abort, 1b, 2b, 4f)
> +               "5:\n\t"
> +               : /* gcc asm goto does not allow outputs */
> +               : [cpu_id]              "r" (cpu),
> +                 [current_cpu_id]      "m" (rseq_get_abi()->RSEQ_TEMPLATE_CPU_ID_FIELD),
> +                 [rseq_cs]             "m" (rseq_get_abi()->rseq_cs.arch.ptr),
> +                 [v]                   "m" (*v),
> +                 [count]               "Ir" (count)
> +                 RSEQ_INJECT_INPUT
> +               : "$r4", "memory"
> +                 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_TEMPLATE_IDENTIFIER(rseq_cmpeqv_cmpeqv_storev)(intptr_t *v, intptr_t expect,
> +                             intptr_t *v2, intptr_t expect2,
> +                             intptr_t newv, int cpu)
> +{
> +       RSEQ_INJECT_C(9)
> +
> +       __asm__ __volatile__ goto (
> +               RSEQ_ASM_DEFINE_TABLE(9, 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, 3f, rseq_cs)
> +               RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
> +               RSEQ_INJECT_ASM(3)
> +               LONG_L " $r4, %[v]\n\t"
> +               "bne $r4, %[expect], %l[cmpfail]\n\t"
> +               RSEQ_INJECT_ASM(4)
> +               LONG_L " $r4, %[v2]\n\t"
> +               "bne $r4, %[expect2], %l[cmpfail]\n\t"
> +               RSEQ_INJECT_ASM(5)
> +#ifdef RSEQ_COMPARE_TWICE
> +               RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, %l[error1])
> +               LONG_L " $r4, %[v]\n\t"
> +               "bne $r4, %[expect], %l[error2]\n\t"
> +               LONG_L " $r4, %[v2]\n\t"
> +               "bne $r4, %[expect2], %l[error3]\n\t"
> +#endif
> +               /* final store */
> +               LONG_S " %[newv], %[v]\n\t"
> +               "2:\n\t"
> +               RSEQ_INJECT_ASM(6)
> +               "b 5f\n\t"
> +               RSEQ_ASM_DEFINE_ABORT(3, 4, "", abort, 1b, 2b, 4f)
> +               "5:\n\t"
> +               : /* gcc asm goto does not allow outputs */
> +               : [cpu_id]              "r" (cpu),
> +                 [current_cpu_id]      "m" (rseq_get_abi()->RSEQ_TEMPLATE_CPU_ID_FIELD),
> +                 [rseq_cs]             "m" (rseq_get_abi()->rseq_cs.arch.ptr),
> +                 /* cmp2 input */
> +                 [v2]                  "m" (*v2),
> +                 [expect2]             "r" (expect2),
> +                 /* final store input */
> +                 [v]                   "m" (*v),
> +                 [expect]              "r" (expect),
> +                 [newv]                "r" (newv)
> +                 RSEQ_INJECT_INPUT
> +               : "$r4", "memory"
> +                 RSEQ_INJECT_CLOBBER
> +               : abort, cmpfail
> +#ifdef RSEQ_COMPARE_TWICE
> +                 , error1, error2, error3
> +#endif
> +       );
> +       return 0;
> +abort:
> +       RSEQ_INJECT_FAILED
> +       return -1;
> +cmpfail:
> +       return 1;
> +#ifdef RSEQ_COMPARE_TWICE
> +error1:
> +       rseq_bug("cpu_id comparison failed");
> +error2:
> +       rseq_bug("1st expected value comparison failed");
> +error3:
> +       rseq_bug("2nd expected value comparison failed");
> +#endif
> +}
> +
> +#endif /* #if defined(RSEQ_TEMPLATE_MO_RELAXED) &&
> +       (defined(RSEQ_TEMPLATE_CPU_ID) || defined(RSEQ_TEMPLATE_MM_CID)) */
> +
> +#if (defined(RSEQ_TEMPLATE_MO_RELAXED) || defined(RSEQ_TEMPLATE_MO_RELEASE)) && \
> +       (defined(RSEQ_TEMPLATE_CPU_ID) || defined(RSEQ_TEMPLATE_MM_CID))
> +
> +static inline __attribute__((always_inline))
> +int RSEQ_TEMPLATE_IDENTIFIER(rseq_cmpeqv_trystorev_storev)(intptr_t *v, intptr_t expect,
> +                                intptr_t *v2, intptr_t newv2,
> +                                intptr_t newv, int cpu)
> +{
> +       RSEQ_INJECT_C(9)
> +
> +       __asm__ __volatile__ goto (
> +               RSEQ_ASM_DEFINE_TABLE(9, 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, 3f, rseq_cs)
> +               RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
> +               RSEQ_INJECT_ASM(3)
> +               LONG_L " $r4, %[v]\n\t"
> +               "bne $r4, %[expect], %l[cmpfail]\n\t"
> +               RSEQ_INJECT_ASM(4)
> +#ifdef RSEQ_COMPARE_TWICE
> +               RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, %l[error1])
> +               LONG_L " $r4, %[v]\n\t"
> +               "bne $r4, %[expect], %l[error2]\n\t"
> +#endif
> +               /* try store */
> +               LONG_S " %[newv2], %[v2]\n\t"
> +               RSEQ_INJECT_ASM(5)
> +#ifdef RSEQ_TEMPLATE_MO_RELEASE
> +               "dbar 0x12\n\t" /* store-release */
> +#endif
> +               /* final store */
> +               LONG_S " %[newv], %[v]\n\t"
> +               "2:\n\t"
> +               RSEQ_INJECT_ASM(6)
> +               "b 5f\n\t"
> +               RSEQ_ASM_DEFINE_ABORT(3, 4, "", abort, 1b, 2b, 4f)
> +               "5:\n\t"
> +               : /* gcc asm goto does not allow outputs */
> +               : [cpu_id]              "r" (cpu),
> +                 [current_cpu_id]      "m" (rseq_get_abi()->RSEQ_TEMPLATE_CPU_ID_FIELD),
> +                 [rseq_cs]             "m" (rseq_get_abi()->rseq_cs.arch.ptr),
> +                 /* try store input */
> +                 [v2]                  "m" (*v2),
> +                 [newv2]               "r" (newv2),
> +                 /* final store input */
> +                 [v]                   "m" (*v),
> +                 [expect]              "r" (expect),
> +                 [newv]                "r" (newv)
> +                 RSEQ_INJECT_INPUT
> +               : "$r4", "memory"
> +                 RSEQ_INJECT_CLOBBER
> +               : abort, cmpfail
> +#ifdef RSEQ_COMPARE_TWICE
> +                 , error1, error2
> +#endif
> +       );
> +       return 0;
> +abort:
> +       RSEQ_INJECT_FAILED
> +       return -1;
> +cmpfail:
> +       return 1;
> +#ifdef RSEQ_COMPARE_TWICE
> +error1:
> +       rseq_bug("cpu_id comparison failed");
> +error2:
> +       rseq_bug("expected value comparison failed");
> +#endif
> +}
> +
> +static inline __attribute__((always_inline))
> +int RSEQ_TEMPLATE_IDENTIFIER(rseq_cmpeqv_trymemcpy_storev)(intptr_t *v, intptr_t expect,
> +                                void *dst, void *src, size_t len,
> +                                intptr_t newv, int cpu)
> +{
> +       uintptr_t rseq_scratch[3];
> +
> +       RSEQ_INJECT_C(9)
> +
> +       __asm__ __volatile__ goto (
> +               RSEQ_ASM_DEFINE_TABLE(9, 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"
> +               /* Start rseq by storing table entry pointer into rseq_cs. */
> +               RSEQ_ASM_STORE_RSEQ_CS(1, 3f, rseq_cs)
> +               RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
> +               RSEQ_INJECT_ASM(3)
> +               LONG_L " $r4, %[v]\n\t"
> +               "bne $r4, %[expect], 5f\n\t"
> +               RSEQ_INJECT_ASM(4)
> +#ifdef RSEQ_COMPARE_TWICE
> +               RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 6f)
> +               LONG_L " $r4, %[v]\n\t"
> +               "bne $r4, %[expect], 7f\n\t"
> +#endif
> +               /* try memcpy */
> +               "beqz %[len], 333f\n\t" \
> +               "222:\n\t" \
> +               "ld.b  $r4, %[src], 0\n\t" \
> +               "st.b  $r4, %[dst], 0\n\t" \
> +               LONG_ADDI " %[src], %[src], 1\n\t" \
> +               LONG_ADDI " %[dst], %[dst], 1\n\t" \
> +               LONG_ADDI " %[len], %[len], -1\n\t" \
> +               "bnez %[len], 222b\n\t" \
> +               "333:\n\t" \
> +               RSEQ_INJECT_ASM(5)
> +#ifdef RSEQ_TEMPLATE_MO_RELEASE
> +               "dbar 0x12\n\t" /* store-release */
> +#endif
> +               /* final store */
> +               LONG_S " %[newv], %[v]\n\t"
> +               "2:\n\t"
> +               RSEQ_INJECT_ASM(6)
> +               /* teardown */
> +               LONG_L " %[len], %[rseq_scratch2]\n\t"
> +               LONG_L " %[dst], %[rseq_scratch1]\n\t"
> +               LONG_L " %[src], %[rseq_scratch0]\n\t"
> +               "b 8f\n\t"
> +               RSEQ_ASM_DEFINE_ABORT(3, 4,
> +                                     /* teardown */
> +                                     LONG_L " %[len], %[rseq_scratch2]\n\t"
> +                                     LONG_L " %[dst], %[rseq_scratch1]\n\t"
> +                                     LONG_L " %[src], %[rseq_scratch0]\n\t",
> +                                     abort, 1b, 2b, 4f)
> +               RSEQ_ASM_DEFINE_CMPFAIL(5,
> +                                       /* teardown */
> +                                       LONG_L " %[len], %[rseq_scratch2]\n\t"
> +                                       LONG_L " %[dst], %[rseq_scratch1]\n\t"
> +                                       LONG_L " %[src], %[rseq_scratch0]\n\t",
> +                                       cmpfail)
> +#ifdef RSEQ_COMPARE_TWICE
> +               RSEQ_ASM_DEFINE_CMPFAIL(6,
> +                                       /* teardown */
> +                                       LONG_L " %[len], %[rseq_scratch2]\n\t"
> +                                       LONG_L " %[dst], %[rseq_scratch1]\n\t"
> +                                       LONG_L " %[src], %[rseq_scratch0]\n\t",
> +                                       error1)
> +               RSEQ_ASM_DEFINE_CMPFAIL(7,
> +                                       /* teardown */
> +                                       LONG_L " %[len], %[rseq_scratch2]\n\t"
> +                                       LONG_L " %[dst], %[rseq_scratch1]\n\t"
> +                                       LONG_L " %[src], %[rseq_scratch0]\n\t",
> +                                       error2)
> +#endif
> +               "8:\n\t"
> +               : /* gcc asm goto does not allow outputs */
> +               : [cpu_id]              "r" (cpu),
> +                 [current_cpu_id]      "m" (rseq_get_abi()->RSEQ_TEMPLATE_CPU_ID_FIELD),
> +                 [rseq_cs]             "m" (rseq_get_abi()->rseq_cs.arch.ptr),
> +                 /* final store input */
> +                 [v]                   "m" (*v),
> +                 [expect]              "r" (expect),
> +                 [newv]                "r" (newv),
> +                 /* try memcpy input */
> +                 [dst]                 "r" (dst),
> +                 [src]                 "r" (src),
> +                 [len]                 "r" (len),
> +                 [rseq_scratch0]       "m" (rseq_scratch[0]),
> +                 [rseq_scratch1]       "m" (rseq_scratch[1]),
> +                 [rseq_scratch2]       "m" (rseq_scratch[2])
> +                 RSEQ_INJECT_INPUT
> +               : "$r4", "memory"
> +                 RSEQ_INJECT_CLOBBER
> +               : abort, cmpfail
> +#ifdef RSEQ_COMPARE_TWICE
> +                 , error1, error2
> +#endif
> +       );
> +       return 0;
> +abort:
> +       RSEQ_INJECT_FAILED
> +       return -1;
> +cmpfail:
> +       return 1;
> +#ifdef RSEQ_COMPARE_TWICE
> +error1:
> +       rseq_bug("cpu_id comparison failed");
> +error2:
> +       rseq_bug("expected value comparison failed");
> +#endif
> +}
> +
> +#endif /* #if (defined(RSEQ_TEMPLATE_MO_RELAXED) || defined(RSEQ_TEMPLATE_MO_RELEASE)) &&
> +       (defined(RSEQ_TEMPLATE_CPU_ID) || defined(RSEQ_TEMPLATE_MM_CID)) */
> +
> +#include "rseq-bits-reset.h"
> diff --git a/tools/testing/selftests/rseq/rseq-loongarch-thread-pointer.h b/tools/testing/selftests/rseq/rseq-loongarch-thread-pointer.h
> new file mode 100644
> index 000000000000..7dc990687982
> --- /dev/null
> +++ b/tools/testing/selftests/rseq/rseq-loongarch-thread-pointer.h
> @@ -0,0 +1,22 @@
> +/* SPDX-License-Identifier: MIT */
> +/* SPDX-FileCopyrightText: 2023 Huang Pei <huangpei@loongson.cn> */
> +
> +#ifndef _RSEQ_LOONGARCH_THREAD_POINTER
> +#define _RSEQ_LOONGARCH_THREAD_POINTER
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +static inline void *rseq_thread_pointer(void)
> +{
> +       register void *__result asm ("$2");
> +       asm ("" : "=r" (__result));
> +       return __result;
> +}
> +
> +#ifdef __cplusplus
> +}
> +#endif
> +
> +#endif
> diff --git a/tools/testing/selftests/rseq/rseq-loongarch.h b/tools/testing/selftests/rseq/rseq-loongarch.h
> new file mode 100644
> index 000000000000..37aae463edde
> --- /dev/null
> +++ b/tools/testing/selftests/rseq/rseq-loongarch.h
> @@ -0,0 +1,140 @@
> +/* SPDX-License-Identifier: LGPL-2.1 OR MIT */
> +/*
> + * Author: Huang Pei <huangpei@loongson.cn>
> + * (C) Copyright 2023 Loongson Technology Corporation Limited
> + * (C) Copyright 2016-2022 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
> + * (C) Copyright 2018 MIPS Tech LLC
> + * (C) Copyright 2018 - Paul Burton <paul.burton@mips.com>
> + */
> +
> +/*
> + * RSEQ_SIG use "break 0x10" instruction.
> + */
> +
> +# define RSEQ_SIG      0x002a0010
> +
> +
> +
> +#define rseq_smp_mb()  __asm__ __volatile__ ("dbar 0x10" ::: "memory")
> +#define rseq_smp_rmb() __asm__ __volatile__ ("dbar 0x15" ::: "memory")
> +#define rseq_smp_wmb() __asm__ __volatile__ ("dbar 0x1a" ::: "memory")
> +
> +#define rseq_smp_load_acquire(p)                                       \
> +__extension__ ({                                                       \
> +       rseq_unqual_scalar_typeof(*(p)) ____p1 = RSEQ_READ_ONCE(*(p));  \
> +       __asm__ __volatile__("dbar 0x14" :::  "memory");                \
> +       ____p1;                                                         \
> +})
> +
> +#define rseq_smp_acquire__after_ctrl_dep()     rseq_smp_rmb()
> +
> +#define rseq_smp_store_release(p, v)                                   \
> +do {                                                                   \
> +       __asm__ __volatile__("dbar 0x12" :::  "memory");                \
> +       RSEQ_WRITE_ONCE(*(p), v);                                       \
> +} while (0)
> +
> +# define LONG                  ".dword"
> +# define LONG_LA               "la.local"
> +# define LONG_L                        "ld.d"
> +# define LONG_S                        "st.d"
> +# define LONG_ADDI             "addi.d"
> +# define U32_U64_PAD(x)                x
> +
> +#define __RSEQ_ASM_DEFINE_TABLE(label, version, flags, start_ip, \
> +                               post_commit_offset, abort_ip) \
> +               ".pushsection __rseq_cs, \"aw\"\n\t" \
> +               ".balign 32\n\t" \
> +               __rseq_str(label) ":\n\t"                                       \
> +               ".word " __rseq_str(version) ", " __rseq_str(flags) "\n\t" \
> +               LONG " " U32_U64_PAD(__rseq_str(start_ip)) "\n\t" \
> +               LONG " " U32_U64_PAD(__rseq_str(post_commit_offset)) "\n\t" \
> +               LONG " " U32_U64_PAD(__rseq_str(abort_ip)) "\n\t" \
> +               ".popsection\n\t" \
> +               ".pushsection __rseq_cs_ptr_array, \"aw\"\n\t" \
> +               LONG " " U32_U64_PAD(__rseq_str(label) "b") "\n\t" \
> +               ".popsection\n\t"
> +
> +#define RSEQ_ASM_DEFINE_TABLE(label, start_ip, post_commit_ip, abort_ip) \
> +       __RSEQ_ASM_DEFINE_TABLE(label, 0x0, 0x0, start_ip, \
> +                               (post_commit_ip - start_ip), abort_ip)
> +/*
> + * 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 " " U32_U64_PAD(__rseq_str(start_ip)) "\n\t" \
> +               LONG " " U32_U64_PAD(__rseq_str(exit_ip)) "\n\t" \
> +               ".popsection\n\t"
> +
> +#define RSEQ_ASM_STORE_RSEQ_CS(label, cs_label, rseq_cs) \
> +               RSEQ_INJECT_ASM(1) \
> +               LONG_LA " $r4, " __rseq_str(cs_label) "\n\t" \
> +               LONG_S  " $r4, %[" __rseq_str(rseq_cs) "]\n\t" \
> +               __rseq_str(label) ":\n\t"
> +
> +#define RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, label) \
> +               RSEQ_INJECT_ASM(2) \
> +               "ld.w  $r4, %[" __rseq_str(current_cpu_id) "]\n\t" \
> +               "bne $r4, %[" __rseq_str(cpu_id) "], " __rseq_str(label) "\n\t"
> +
> +#define __RSEQ_ASM_DEFINE_ABORT(table_label, label, teardown, \
> +                               abort_label, version, flags, \
> +                               start_ip, post_commit_offset, abort_ip) \
> +               ".balign 32\n\t" \
> +               __rseq_str(table_label) ":\n\t" \
> +               ".word " __rseq_str(version) ", " __rseq_str(flags) "\n\t" \
> +               LONG " " U32_U64_PAD(__rseq_str(start_ip)) "\n\t" \
> +               LONG " " U32_U64_PAD(__rseq_str(post_commit_offset)) "\n\t" \
> +               LONG " " U32_U64_PAD(__rseq_str(abort_ip)) "\n\t" \
> +               ".word " __rseq_str(RSEQ_SIG) "\n\t" \
> +               __rseq_str(label) ":\n\t" \
> +               teardown \
> +               "b %l[" __rseq_str(abort_label) "]\n\t"
> +
> +#define RSEQ_ASM_DEFINE_ABORT(table_label, label, teardown, abort_label, \
> +                             start_ip, post_commit_ip, abort_ip) \
> +       __RSEQ_ASM_DEFINE_ABORT(table_label, label, teardown, \
> +                               abort_label, 0x0, 0x0, start_ip, \
> +                               (post_commit_ip - start_ip), abort_ip)
> +
> +#define RSEQ_ASM_DEFINE_CMPFAIL(label, teardown, cmpfail_label) \
> +               __rseq_str(label) ":\n\t" \
> +               teardown \
> +               "b %l[" __rseq_str(cmpfail_label) "]\n\t"
> +
> +/* Per-cpu-id indexing. */
> +#define RSEQ_TEMPLATE_CPU_ID
> +#define RSEQ_TEMPLATE_MO_RELAXED
> +#include "rseq-loongarch-bits.h"
> +#undef RSEQ_TEMPLATE_MO_RELAXED
> +
> +#define RSEQ_TEMPLATE_MO_RELEASE
> +#include "rseq-loongarch-bits.h"
> +#undef RSEQ_TEMPLATE_MO_RELEASE
> +#undef RSEQ_TEMPLATE_CPU_ID
> +
> +/* Per-mm-cid indexing. */
> +
> +#define RSEQ_TEMPLATE_MM_CID
> +#define RSEQ_TEMPLATE_MO_RELAXED
> +#include "rseq-loongarch-bits.h"
> +#undef RSEQ_TEMPLATE_MO_RELAXED
> +
> +#define RSEQ_TEMPLATE_MO_RELEASE
> +#include "rseq-loongarch-bits.h"
> +#undef RSEQ_TEMPLATE_MO_RELEASE
> +#undef RSEQ_TEMPLATE_MM_CID
> +
> +/* APIs which are not based on cpu ids. */
> +
> +#define RSEQ_TEMPLATE_CPU_ID_NONE
> +#define RSEQ_TEMPLATE_MO_RELAXED
> +#include "rseq-loongarch-bits.h"
> +#undef RSEQ_TEMPLATE_MO_RELAXED
> +#undef RSEQ_TEMPLATE_CPU_ID_NONE
> diff --git a/tools/testing/selftests/rseq/rseq-thread-pointer.h b/tools/testing/selftests/rseq/rseq-thread-pointer.h
> index 977c25d758b2..b9c8fe7c4683 100644
> --- a/tools/testing/selftests/rseq/rseq-thread-pointer.h
> +++ b/tools/testing/selftests/rseq/rseq-thread-pointer.h
> @@ -12,6 +12,8 @@
>  #include "rseq-x86-thread-pointer.h"
>  #elif defined(__PPC__)
>  #include "rseq-ppc-thread-pointer.h"
> +#elif defined(__loongarch__)
> +#include "rseq-loongarch-thread-pointer.h"
>  #else
>  #include "rseq-generic-thread-pointer.h"
>  #endif
> diff --git a/tools/testing/selftests/rseq/rseq.h b/tools/testing/selftests/rseq/rseq.h
> index d7364ea4d201..75c4bbe013d3 100644
> --- a/tools/testing/selftests/rseq/rseq.h
> +++ b/tools/testing/selftests/rseq/rseq.h
> @@ -128,6 +128,8 @@ static inline struct rseq_abi *rseq_get_abi(void)
>  #include <rseq-s390.h>
>  #elif defined(__riscv)
>  #include <rseq-riscv.h>
> +#elif defined(__loongarch__)
> +#include <rseq-loongarch.h>
>  #else
>  #error unsupported target
>  #endif
> --
> 2.20.1
>
>

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 2/3] LoongArch: Add RSEQ_SIG break code definition
  2023-10-26 11:44 ` [PATCH 2/3] LoongArch: Add RSEQ_SIG break code definition Huang Pei
@ 2023-10-26 18:07   ` Mathieu Desnoyers
  2023-10-27  1:40     ` Huacai Chen
  0 siblings, 1 reply; 5+ messages in thread
From: Mathieu Desnoyers @ 2023-10-26 18:07 UTC (permalink / raw)
  To: Huang Pei, Huacai Chen; +Cc: loongarch, linux-kernel

On 2023-10-26 07:44, Huang Pei wrote:
> Signed-off-by: Huang Pei <huangpei@loongson.cn>
> ---
>   arch/loongarch/include/uapi/asm/break.h | 2 ++

Why is this part of the uapi ? None of the other architecture has this 
as part of uapi. It's only defined in the rseq selftest arch-specific 
header file.

Thanks,

Mathieu

>   1 file changed, 2 insertions(+)
> 
> diff --git a/arch/loongarch/include/uapi/asm/break.h b/arch/loongarch/include/uapi/asm/break.h
> index bb9b82ba59f2..e0fcfc304834 100644
> --- a/arch/loongarch/include/uapi/asm/break.h
> +++ b/arch/loongarch/include/uapi/asm/break.h
> @@ -20,4 +20,6 @@
>   #define BRK_UPROBE_BP		12	/* See <asm/uprobes.h> */
>   #define BRK_UPROBE_XOLBP	13	/* See <asm/uprobes.h> */
>   
> +#define BRK_RSEQ_SIG		16	/* See rseq */
> +
>   #endif /* __UAPI_ASM_BREAK_H */

-- 
Mathieu Desnoyers
EfficiOS Inc.
https://www.efficios.com


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 2/3] LoongArch: Add RSEQ_SIG break code definition
  2023-10-26 18:07   ` Mathieu Desnoyers
@ 2023-10-27  1:40     ` Huacai Chen
  0 siblings, 0 replies; 5+ messages in thread
From: Huacai Chen @ 2023-10-27  1:40 UTC (permalink / raw)
  To: Mathieu Desnoyers; +Cc: Huang Pei, Huacai Chen, loongarch, linux-kernel

Hi, Mathieu,

On Fri, Oct 27, 2023 at 2:16 AM Mathieu Desnoyers
<mathieu.desnoyers@efficios.com> wrote:
>
> On 2023-10-26 07:44, Huang Pei wrote:
> > Signed-off-by: Huang Pei <huangpei@loongson.cn>
> > ---
> >   arch/loongarch/include/uapi/asm/break.h | 2 ++
>
> Why is this part of the uapi ? None of the other architecture has this
> as part of uapi. It's only defined in the rseq selftest arch-specific
> header file.
From my point of view, it makes sense to list the dedicated break code
in UAPI. It is harmless and can avoid potential conflict in future.

Huacai

>
> Thanks,
>
> Mathieu
>
> >   1 file changed, 2 insertions(+)
> >
> > diff --git a/arch/loongarch/include/uapi/asm/break.h b/arch/loongarch/include/uapi/asm/break.h
> > index bb9b82ba59f2..e0fcfc304834 100644
> > --- a/arch/loongarch/include/uapi/asm/break.h
> > +++ b/arch/loongarch/include/uapi/asm/break.h
> > @@ -20,4 +20,6 @@
> >   #define BRK_UPROBE_BP               12      /* See <asm/uprobes.h> */
> >   #define BRK_UPROBE_XOLBP    13      /* See <asm/uprobes.h> */
> >
> > +#define BRK_RSEQ_SIG         16      /* See rseq */
> > +
> >   #endif /* __UAPI_ASM_BREAK_H */
>
> --
> Mathieu Desnoyers
> EfficiOS Inc.
> https://www.efficios.com
>
>

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2023-10-27  1:40 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-10-26 11:44 [PATCH 1/3] selftests/rseq: Add 64bit LoongArch support Huang Pei
2023-10-26 11:44 ` [PATCH 2/3] LoongArch: Add RSEQ_SIG break code definition Huang Pei
2023-10-26 18:07   ` Mathieu Desnoyers
2023-10-27  1:40     ` Huacai Chen
2023-10-26 12:07 ` [PATCH 1/3] selftests/rseq: Add 64bit LoongArch support Huacai Chen

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.