bpf.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/7] LoongArch: Switch to relative extable and other improvements
@ 2022-10-10  9:32 Youling Tang
  2022-10-10  9:32 ` [PATCH 1/7] LoongArch: Consolidate __ex_table construction Youling Tang
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Youling Tang @ 2022-10-10  9:32 UTC (permalink / raw)
  To: Huacai Chen, Masahiro Yamada, Michal Marek
  Cc: WANG Xuerui, Nick Desaulniers, Daniel Borkmann,
	Alexei Starovoitov, loongarch, linux-kernel, linux-kbuild, bpf

Similar as other architectures such as arm64, x86 and so on, use
offsets relative to the exception table entry values rather than
absolute addresses for both the exception locationand the fixup.
And recently, arm64 and x86 remove anonymous out-of-line fixups, we
want to acchieve the same result.

Implementing the relative extable will facilitate subsequent kernel
relocation support, which can reduce relocation operations to the
extable (thanks to Jinyang for the suggestion).

At the same time, add BPF exception tables handling.


Youling Tang (7):
  LoongArch: Consolidate __ex_table construction
  LoongArch: Switch to relative exception tables
  LoongArch: extable: Add `type` and `data` fields
  LoongArch: Add gpr-num.h
  LoongArch: extable: Add a dedicated uaccess handler
  LoongArch: vmlinux.lds.S: Remove `.fixup` section
  LoongArch: bpf: Add BPF exception tables

 arch/loongarch/include/asm/asm-extable.h | 65 ++++++++++++++++++
 arch/loongarch/include/asm/extable.h     | 49 ++++++++++++++
 arch/loongarch/include/asm/futex.h       | 27 ++------
 arch/loongarch/include/asm/gpr-num.h     | 22 +++++++
 arch/loongarch/include/asm/uaccess.h     | 24 ++-----
 arch/loongarch/kernel/fpu.S              |  5 +-
 arch/loongarch/kernel/vmlinux.lds.S      |  4 +-
 arch/loongarch/lib/clear_user.S          | 17 ++---
 arch/loongarch/lib/copy_user.S           | 19 ++----
 arch/loongarch/mm/extable.c              | 60 ++++++++++++++---
 arch/loongarch/net/bpf_jit.c             | 84 ++++++++++++++++++++++--
 arch/loongarch/net/bpf_jit.h             |  2 +
 scripts/mod/modpost.c                    | 13 ++++
 scripts/sorttable.c                      |  2 +-
 14 files changed, 312 insertions(+), 81 deletions(-)
 create mode 100644 arch/loongarch/include/asm/asm-extable.h
 create mode 100644 arch/loongarch/include/asm/extable.h
 create mode 100644 arch/loongarch/include/asm/gpr-num.h

-- 
2.36.1


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

* [PATCH 1/7] LoongArch: Consolidate __ex_table construction
  2022-10-10  9:32 [PATCH 0/7] LoongArch: Switch to relative extable and other improvements Youling Tang
@ 2022-10-10  9:32 ` Youling Tang
  2022-10-10  9:32 ` [PATCH 2/7] LoongArch: Switch to relative exception tables Youling Tang
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Youling Tang @ 2022-10-10  9:32 UTC (permalink / raw)
  To: Huacai Chen, Masahiro Yamada, Michal Marek
  Cc: WANG Xuerui, Nick Desaulniers, Daniel Borkmann,
	Alexei Starovoitov, loongarch, linux-kernel, linux-kbuild, bpf

Consolidate all the __ex_table constuction code with a _ASM_EXTABLE
or _asm_extable helper.

There should be no functional change as a result of this patch.

Signed-off-by: Youling Tang <tangyouling@loongson.cn>
---
 arch/loongarch/include/asm/asm-extable.h | 35 ++++++++++++++++++++++++
 arch/loongarch/include/asm/futex.h       | 13 ++++-----
 arch/loongarch/include/asm/uaccess.h     |  9 ++----
 arch/loongarch/kernel/fpu.S              |  5 ++--
 arch/loongarch/lib/clear_user.S          |  5 ++--
 arch/loongarch/lib/copy_user.S           |  5 ++--
 6 files changed, 49 insertions(+), 23 deletions(-)
 create mode 100644 arch/loongarch/include/asm/asm-extable.h

diff --git a/arch/loongarch/include/asm/asm-extable.h b/arch/loongarch/include/asm/asm-extable.h
new file mode 100644
index 000000000000..5aef0c41bdad
--- /dev/null
+++ b/arch/loongarch/include/asm/asm-extable.h
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef __ASM_ASM_EXTABLE_H
+#define __ASM_ASM_EXTABLE_H
+
+#ifdef __ASSEMBLY__
+
+#define __ASM_EXTABLE_RAW(insn, fixup)			\
+	.pushsection	__ex_table, "a";		\
+	.balign		8;				\
+	.long		(insn);				\
+	.long		(fixup);			\
+	.popsection;
+
+	.macro		_asm_extable, insn, fixup
+	__ASM_EXTABLE_RAW(\insn, \fixup)
+	.endm
+
+#else /* __ASSEMBLY__ */
+
+#include <linux/bits.h>
+#include <linux/stringify.h>
+
+#define __ASM_EXTABLE_RAW(insn, fixup)			\
+	".pushsection	__ex_table, \"a\"\n"		\
+	".balign	8\n"				\
+	".long		((" insn "))\n"			\
+	".long		((" fixup "))\n"		\
+	".popsection\n"
+
+#define _ASM_EXTABLE(insn, fixup)	\
+	__ASM_EXTABLE_RAW(#insn, #fixup)
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __ASM_ASM_EXTABLE_H */
diff --git a/arch/loongarch/include/asm/futex.h b/arch/loongarch/include/asm/futex.h
index feb6658c84ff..bdcd1c613299 100644
--- a/arch/loongarch/include/asm/futex.h
+++ b/arch/loongarch/include/asm/futex.h
@@ -7,6 +7,7 @@
 
 #include <linux/futex.h>
 #include <linux/uaccess.h>
+#include <asm/asm-extable.h>
 #include <asm/barrier.h>
 #include <asm/errno.h>
 
@@ -22,10 +23,8 @@
 	"4:	li.w	%0, %6				\n"	\
 	"	b	3b				\n"	\
 	"	.previous				\n"	\
-	"	.section __ex_table,\"a\"		\n"	\
-	"	"__UA_ADDR "\t1b, 4b			\n"	\
-	"	"__UA_ADDR "\t2b, 4b			\n"	\
-	"	.previous				\n"	\
+	_ASM_EXTABLE(1b, 4b)					\
+	_ASM_EXTABLE(2b, 4b)					\
 	: "=r" (ret), "=&r" (oldval),				\
 	  "=ZC" (*uaddr)					\
 	: "0" (0), "ZC" (*uaddr), "Jr" (oparg),			\
@@ -90,10 +89,8 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, u32 oldval, u32 newv
 	"4:	li.d	%0, %6					\n"
 	"	b	3b					\n"
 	"	.previous					\n"
-	"	.section __ex_table,\"a\"			\n"
-	"	"__UA_ADDR "\t1b, 4b				\n"
-	"	"__UA_ADDR "\t2b, 4b				\n"
-	"	.previous					\n"
+	_ASM_EXTABLE(1b, 4b)
+	_ASM_EXTABLE(2b, 4b)
 	: "+r" (ret), "=&r" (val), "=ZC" (*uaddr)
 	: "ZC" (*uaddr), "Jr" (oldval), "Jr" (newval),
 	  "i" (-EFAULT)
diff --git a/arch/loongarch/include/asm/uaccess.h b/arch/loongarch/include/asm/uaccess.h
index a8ae2af4025a..bf9a4e218ac0 100644
--- a/arch/loongarch/include/asm/uaccess.h
+++ b/arch/loongarch/include/asm/uaccess.h
@@ -15,6 +15,7 @@
 #include <linux/string.h>
 #include <linux/extable.h>
 #include <asm/pgtable.h>
+#include <asm/asm-extable.h>
 #include <asm-generic/extable.h>
 #include <asm-generic/access_ok.h>
 
@@ -165,9 +166,7 @@ do {									\
 	"	move	%1, $zero				\n"	\
 	"	b	2b					\n"	\
 	"	.previous					\n"	\
-	"	.section __ex_table,\"a\"			\n"	\
-	"	"__UA_ADDR "\t1b, 3b				\n"	\
-	"	.previous					\n"	\
+	_ASM_EXTABLE(1b, 3b)						\
 	: "+r" (__gu_err), "=r" (__gu_tmp)				\
 	: "m" (__m(ptr)), "i" (-EFAULT));				\
 									\
@@ -196,9 +195,7 @@ do {									\
 	"3:	li.w	%0, %3					\n"	\
 	"	b	2b					\n"	\
 	"	.previous					\n"	\
-	"	.section	__ex_table,\"a\"		\n"	\
-	"	" __UA_ADDR "	1b, 3b				\n"	\
-	"	.previous					\n"	\
+	_ASM_EXTABLE(1b, 3b)						\
 	: "+r" (__pu_err), "=m" (__m(ptr))				\
 	: "Jr" (__pu_val), "i" (-EFAULT));				\
 }
diff --git a/arch/loongarch/kernel/fpu.S b/arch/loongarch/kernel/fpu.S
index 576b3370a296..ccde94140c89 100644
--- a/arch/loongarch/kernel/fpu.S
+++ b/arch/loongarch/kernel/fpu.S
@@ -8,6 +8,7 @@
  */
 #include <asm/asm.h>
 #include <asm/asmmacro.h>
+#include <asm/asm-extable.h>
 #include <asm/asm-offsets.h>
 #include <asm/errno.h>
 #include <asm/export.h>
@@ -21,9 +22,7 @@
 
 	.macro	EX insn, reg, src, offs
 .ex\@:	\insn	\reg, \src, \offs
-	.section __ex_table,"a"
-	PTR	.ex\@, fault
-	.previous
+	_asm_extable .ex\@, fault
 	.endm
 
 	.macro sc_save_fp base
diff --git a/arch/loongarch/lib/clear_user.S b/arch/loongarch/lib/clear_user.S
index 16ba2b8dd68a..7a066d6a41b8 100644
--- a/arch/loongarch/lib/clear_user.S
+++ b/arch/loongarch/lib/clear_user.S
@@ -5,6 +5,7 @@
 
 #include <asm/asm.h>
 #include <asm/asmmacro.h>
+#include <asm/asm-extable.h>
 #include <asm/export.h>
 #include <asm/regdef.h>
 
@@ -15,9 +16,7 @@
 	jr	ra
 	.previous
 .endif
-	.section __ex_table, "a"
-	PTR	\from\()b, \to\()b
-	.previous
+	_asm_extable \from\()b, \to\()b
 .endm
 
 /*
diff --git a/arch/loongarch/lib/copy_user.S b/arch/loongarch/lib/copy_user.S
index 97d20327a69e..f8ace04586c2 100644
--- a/arch/loongarch/lib/copy_user.S
+++ b/arch/loongarch/lib/copy_user.S
@@ -5,6 +5,7 @@
 
 #include <asm/asm.h>
 #include <asm/asmmacro.h>
+#include <asm/asm-extable.h>
 #include <asm/export.h>
 #include <asm/regdef.h>
 
@@ -15,9 +16,7 @@
 	jr	ra
 	.previous
 .endif
-	.section __ex_table, "a"
-	PTR	\from\()b, \to\()b
-	.previous
+	_asm_extable \from\()b, \to\()b
 .endm
 
 /*
-- 
2.36.1


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

* [PATCH 2/7] LoongArch: Switch to relative exception tables
  2022-10-10  9:32 [PATCH 0/7] LoongArch: Switch to relative extable and other improvements Youling Tang
  2022-10-10  9:32 ` [PATCH 1/7] LoongArch: Consolidate __ex_table construction Youling Tang
@ 2022-10-10  9:32 ` Youling Tang
  2022-10-10  9:32 ` [PATCH 3/7] LoongArch: extable: Add `type` and `data` fields Youling Tang
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Youling Tang @ 2022-10-10  9:32 UTC (permalink / raw)
  To: Huacai Chen, Masahiro Yamada, Michal Marek
  Cc: WANG Xuerui, Nick Desaulniers, Daniel Borkmann,
	Alexei Starovoitov, loongarch, linux-kernel, linux-kbuild, bpf

Similar as other architectures such as arm64, x86, riscv and so on, use
offsets relative to the exception table entry values rather than absolute
addresses for both the exception locationand the fixup.

However, LoongArch label difference will actually produce two relocations,
a pair of R_LARCH_ADD32 and R_LARCH_SUB32. Take below simple code for
example:

$ cat test_ex_table.S
.section .text
1:
        nop
.section __ex_table,"a"
        .balign 4
        .long (1b - .)
.previous

$ loongarch64-unknown-linux-gnu-gcc -c test_ex_table.S
$ loongarch64-unknown-linux-gnu-readelf -Wr test_ex_table.o

Relocation section '.rela__ex_table' at offset 0x100 contains 2 entries:
    Offset             Info             Type               Symbol's Value  Symbol's Name + Addend
0000000000000000  0000000600000032 R_LARCH_ADD32          0000000000000000 .L1^B1 + 0
0000000000000000  0000000500000037 R_LARCH_SUB32          0000000000000000 L0^A + 0

The modpost will complain the R_LARCH_SUB32 relocation, so we need to
patch modpost.c to skip this relocation for .rela__ex_table section.

Signed-off-by: Youling Tang <tangyouling@loongson.cn>
---
 arch/loongarch/include/asm/asm-extable.h | 12 +++++-----
 arch/loongarch/include/asm/extable.h     | 26 ++++++++++++++++++++++
 arch/loongarch/include/asm/uaccess.h     |  2 +-
 arch/loongarch/mm/extable.c              | 28 +++++++++++++++++-------
 scripts/mod/modpost.c                    | 13 +++++++++++
 scripts/sorttable.c                      |  2 +-
 6 files changed, 67 insertions(+), 16 deletions(-)
 create mode 100644 arch/loongarch/include/asm/extable.h

diff --git a/arch/loongarch/include/asm/asm-extable.h b/arch/loongarch/include/asm/asm-extable.h
index 5aef0c41bdad..74f8bc75472a 100644
--- a/arch/loongarch/include/asm/asm-extable.h
+++ b/arch/loongarch/include/asm/asm-extable.h
@@ -6,9 +6,9 @@
 
 #define __ASM_EXTABLE_RAW(insn, fixup)			\
 	.pushsection	__ex_table, "a";		\
-	.balign		8;				\
-	.long		(insn);				\
-	.long		(fixup);			\
+	.balign		4;				\
+	.long		((insn) - .);			\
+	.long		((fixup) - .);			\
 	.popsection;
 
 	.macro		_asm_extable, insn, fixup
@@ -22,9 +22,9 @@
 
 #define __ASM_EXTABLE_RAW(insn, fixup)			\
 	".pushsection	__ex_table, \"a\"\n"		\
-	".balign	8\n"				\
-	".long		((" insn "))\n"			\
-	".long		((" fixup "))\n"		\
+	".balign	4\n"				\
+	".long		((" insn ") - .)\n"		\
+	".long		((" fixup ") - .)\n"		\
 	".popsection\n"
 
 #define _ASM_EXTABLE(insn, fixup)	\
diff --git a/arch/loongarch/include/asm/extable.h b/arch/loongarch/include/asm/extable.h
new file mode 100644
index 000000000000..b571c89705d1
--- /dev/null
+++ b/arch/loongarch/include/asm/extable.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_LOONGARCH_EXTABLE_H
+#define _ASM_LOONGARCH_EXTABLE_H
+
+/*
+ * The exception table consists of pairs of relative offsets: the first
+ * is the relative offset to an instruction that is allowed to fault,
+ * and the second is the relative offset at which the program should
+ * continue. No registers are modified, so it is entirely up to the
+ * continuation code to figure out what to do.
+ *
+ * All the routines below use bits of fixup code that are out of line
+ * with the main instruction path.  This means when everything is well,
+ * we don't even have to jump over them.  Further, they do not intrude
+ * on our cache or tlb entries.
+ */
+
+struct exception_table_entry {
+	int insn, fixup;
+};
+
+#define ARCH_HAS_RELATIVE_EXTABLE
+
+bool fixup_exception(struct pt_regs *regs);
+
+#endif
diff --git a/arch/loongarch/include/asm/uaccess.h b/arch/loongarch/include/asm/uaccess.h
index bf9a4e218ac0..e33282e0bdef 100644
--- a/arch/loongarch/include/asm/uaccess.h
+++ b/arch/loongarch/include/asm/uaccess.h
@@ -15,8 +15,8 @@
 #include <linux/string.h>
 #include <linux/extable.h>
 #include <asm/pgtable.h>
+#include <asm/extable.h>
 #include <asm/asm-extable.h>
-#include <asm-generic/extable.h>
 #include <asm-generic/access_ok.h>
 
 extern u64 __ua_limit;
diff --git a/arch/loongarch/mm/extable.c b/arch/loongarch/mm/extable.c
index bc20988f2b87..fb2b5a0268f0 100644
--- a/arch/loongarch/mm/extable.c
+++ b/arch/loongarch/mm/extable.c
@@ -4,19 +4,31 @@
  */
 #include <linux/extable.h>
 #include <linux/spinlock.h>
+#include <asm/asm-extable.h>
 #include <asm/branch.h>
 #include <linux/uaccess.h>
 
-int fixup_exception(struct pt_regs *regs)
+static inline unsigned long
+get_ex_fixup(const struct exception_table_entry *ex)
 {
-	const struct exception_table_entry *fixup;
+	return ((unsigned long)&ex->fixup + ex->fixup);
+}
+
+static bool ex_handler_fixup(const struct exception_table_entry *ex,
+			     struct pt_regs *regs)
+{
+	regs->csr_era = get_ex_fixup(ex);
+	return true;
+}
+
 
-	fixup = search_exception_tables(exception_era(regs));
-	if (fixup) {
-		regs->csr_era = fixup->fixup;
+bool fixup_exception(struct pt_regs *regs)
+{
+	const struct exception_table_entry *ex;
 
-		return 1;
-	}
+	ex = search_exception_tables(exception_era(regs));
+	if (!ex)
+		return false;
 
-	return 0;
+	return ex_handler_fixup(ex, regs);
 }
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 2c80da0220c3..9321c0a05ffd 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -1523,6 +1523,14 @@ static int addend_mips_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
 #define R_RISCV_SUB32		39
 #endif
 
+#ifndef EM_LOONGARCH
+#define EM_LOONGARCH		258
+#endif
+
+#ifndef R_LARCH_SUB32
+#define R_LARCH_SUB32		55
+#endif
+
 static void section_rela(const char *modname, struct elf_info *elf,
 			 Elf_Shdr *sechdr)
 {
@@ -1564,6 +1572,11 @@ static void section_rela(const char *modname, struct elf_info *elf,
 			    ELF_R_TYPE(r.r_info) == R_RISCV_SUB32)
 				continue;
 			break;
+		case EM_LOONGARCH:
+			if (!strcmp("__ex_table", fromsec) &&
+			    ELF_R_TYPE(r.r_info) == R_LARCH_SUB32)
+				continue;
+			break;
 		}
 		sym = elf->symtab_start + r_sym;
 		/* Skip special sections */
diff --git a/scripts/sorttable.c b/scripts/sorttable.c
index fba40e99f354..0f2beda80478 100644
--- a/scripts/sorttable.c
+++ b/scripts/sorttable.c
@@ -312,12 +312,12 @@ static int do_file(char const *const fname, void *addr)
 	case EM_PARISC:
 	case EM_PPC:
 	case EM_PPC64:
+	case EM_LOONGARCH:
 		custom_sort = sort_relative_table;
 		break;
 	case EM_ARCOMPACT:
 	case EM_ARCV2:
 	case EM_ARM:
-	case EM_LOONGARCH:
 	case EM_MICROBLAZE:
 	case EM_MIPS:
 	case EM_XTENSA:
-- 
2.36.1


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

* [PATCH 3/7] LoongArch: extable: Add `type` and `data` fields
  2022-10-10  9:32 [PATCH 0/7] LoongArch: Switch to relative extable and other improvements Youling Tang
  2022-10-10  9:32 ` [PATCH 1/7] LoongArch: Consolidate __ex_table construction Youling Tang
  2022-10-10  9:32 ` [PATCH 2/7] LoongArch: Switch to relative exception tables Youling Tang
@ 2022-10-10  9:32 ` Youling Tang
  2022-10-10  9:32 ` [PATCH 4/7] LoongArch: Add gpr-num.h Youling Tang
  2022-10-10  9:32 ` [PATCH 5/7] LoongArch: extable: Add a dedicated uaccess handler Youling Tang
  4 siblings, 0 replies; 6+ messages in thread
From: Youling Tang @ 2022-10-10  9:32 UTC (permalink / raw)
  To: Huacai Chen, Masahiro Yamada, Michal Marek
  Cc: WANG Xuerui, Nick Desaulniers, Daniel Borkmann,
	Alexei Starovoitov, loongarch, linux-kernel, linux-kbuild, bpf

This is a LoongArch port of commit d6e2cc564775 ("arm64: extable: add
`type` and `data` fields").

Subsequent patches will add specialized handlers for fixups, in addition
to the simple PC fixup we have today. In preparation, this patch adds a
new `type` field to struct exception_table_entry, and uses this to
distinguish the fixup and other cases. A `data` field is also added so
that subsequent patches can associate data specific to each exception
site (e.g. register numbers).

Handlers are named ex_handler_*() for consistency, following the example
of x86. At the same time, get_ex_fixup() is split out into a helper so
that it can be used by other ex_handler_*() functions ins subsequent
patches.

Signed-off-by: Youling Tang <tangyouling@loongson.cn>
---
 arch/loongarch/include/asm/asm-extable.h | 15 +++++++++++----
 arch/loongarch/include/asm/extable.h     | 11 +++++++++++
 arch/loongarch/kernel/vmlinux.lds.S      |  3 +--
 arch/loongarch/mm/extable.c              |  7 ++++++-
 scripts/sorttable.c                      |  2 +-
 5 files changed, 30 insertions(+), 8 deletions(-)

diff --git a/arch/loongarch/include/asm/asm-extable.h b/arch/loongarch/include/asm/asm-extable.h
index 74f8bc75472a..634bd770e3c4 100644
--- a/arch/loongarch/include/asm/asm-extable.h
+++ b/arch/loongarch/include/asm/asm-extable.h
@@ -2,17 +2,22 @@
 #ifndef __ASM_ASM_EXTABLE_H
 #define __ASM_ASM_EXTABLE_H
 
+#define EX_TYPE_NONE			0
+#define EX_TYPE_FIXUP			1
+
 #ifdef __ASSEMBLY__
 
-#define __ASM_EXTABLE_RAW(insn, fixup)			\
+#define __ASM_EXTABLE_RAW(insn, fixup, type, data)	\
 	.pushsection	__ex_table, "a";		\
 	.balign		4;				\
 	.long		((insn) - .);			\
 	.long		((fixup) - .);			\
+	.short		(type);				\
+	.short		(data);				\
 	.popsection;
 
 	.macro		_asm_extable, insn, fixup
-	__ASM_EXTABLE_RAW(\insn, \fixup)
+	__ASM_EXTABLE_RAW(\insn, \fixup, EX_TYPE_FIXUP, 0)
 	.endm
 
 #else /* __ASSEMBLY__ */
@@ -20,15 +25,17 @@
 #include <linux/bits.h>
 #include <linux/stringify.h>
 
-#define __ASM_EXTABLE_RAW(insn, fixup)			\
+#define __ASM_EXTABLE_RAW(insn, fixup, type, data)	\
 	".pushsection	__ex_table, \"a\"\n"		\
 	".balign	4\n"				\
 	".long		((" insn ") - .)\n"		\
 	".long		((" fixup ") - .)\n"		\
+	".short		(" type ")\n"			\
+	".short		(" data ")\n"			\
 	".popsection\n"
 
 #define _ASM_EXTABLE(insn, fixup)	\
-	__ASM_EXTABLE_RAW(#insn, #fixup)
+	__ASM_EXTABLE_RAW(#insn, #fixup, __stringify(EX_TYPE_FIXUP), "0")
 
 #endif /* __ASSEMBLY__ */
 
diff --git a/arch/loongarch/include/asm/extable.h b/arch/loongarch/include/asm/extable.h
index b571c89705d1..92612b4364a1 100644
--- a/arch/loongarch/include/asm/extable.h
+++ b/arch/loongarch/include/asm/extable.h
@@ -17,10 +17,21 @@
 
 struct exception_table_entry {
 	int insn, fixup;
+	short type, data;
 };
 
 #define ARCH_HAS_RELATIVE_EXTABLE
 
+#define swap_ex_entry_fixup(a, b, tmp, delta)		\
+do {							\
+	(a)->fixup = (b)->fixup + (delta);		\
+	(b)->fixup = (tmp).fixup - (delta);		\
+	(a)->type = (b)->type;				\
+	(b)->type = (tmp).type;				\
+	(a)->data = (b)->data;				\
+	(b)->data = (tmp).data;				\
+} while (0)
+
 bool fixup_exception(struct pt_regs *regs);
 
 #endif
diff --git a/arch/loongarch/kernel/vmlinux.lds.S b/arch/loongarch/kernel/vmlinux.lds.S
index b3309a5e695b..efecda0c2361 100644
--- a/arch/loongarch/kernel/vmlinux.lds.S
+++ b/arch/loongarch/kernel/vmlinux.lds.S
@@ -4,6 +4,7 @@
 #include <asm/thread_info.h>
 
 #define PAGE_SIZE _PAGE_SIZE
+#define RO_EXCEPTION_TABLE_ALIGN	4
 
 /*
  * Put .bss..swapper_pg_dir as the first thing in .bss. This will
@@ -53,8 +54,6 @@ SECTIONS
 	. = ALIGN(PECOFF_SEGMENT_ALIGN);
 	_etext = .;
 
-	EXCEPTION_TABLE(16)
-
 	.got : ALIGN(16) { *(.got) }
 	.plt : ALIGN(16) { *(.plt) }
 	.got.plt : ALIGN(16) { *(.got.plt) }
diff --git a/arch/loongarch/mm/extable.c b/arch/loongarch/mm/extable.c
index fb2b5a0268f0..56b7250fc65e 100644
--- a/arch/loongarch/mm/extable.c
+++ b/arch/loongarch/mm/extable.c
@@ -30,5 +30,10 @@ bool fixup_exception(struct pt_regs *regs)
 	if (!ex)
 		return false;
 
-	return ex_handler_fixup(ex, regs);
+	switch (ex->type) {
+	case EX_TYPE_FIXUP:
+		return ex_handler_fixup(ex, regs);
+	}
+
+	BUG();
 }
diff --git a/scripts/sorttable.c b/scripts/sorttable.c
index 0f2beda80478..83cdb843d92f 100644
--- a/scripts/sorttable.c
+++ b/scripts/sorttable.c
@@ -304,6 +304,7 @@ static int do_file(char const *const fname, void *addr)
 	switch (r2(&ehdr->e_machine)) {
 	case EM_386:
 	case EM_AARCH64:
+	case EM_LOONGARCH:
 	case EM_RISCV:
 	case EM_S390:
 	case EM_X86_64:
@@ -312,7 +313,6 @@ static int do_file(char const *const fname, void *addr)
 	case EM_PARISC:
 	case EM_PPC:
 	case EM_PPC64:
-	case EM_LOONGARCH:
 		custom_sort = sort_relative_table;
 		break;
 	case EM_ARCOMPACT:
-- 
2.36.1


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

* [PATCH 4/7] LoongArch: Add gpr-num.h
  2022-10-10  9:32 [PATCH 0/7] LoongArch: Switch to relative extable and other improvements Youling Tang
                   ` (2 preceding siblings ...)
  2022-10-10  9:32 ` [PATCH 3/7] LoongArch: extable: Add `type` and `data` fields Youling Tang
@ 2022-10-10  9:32 ` Youling Tang
  2022-10-10  9:32 ` [PATCH 5/7] LoongArch: extable: Add a dedicated uaccess handler Youling Tang
  4 siblings, 0 replies; 6+ messages in thread
From: Youling Tang @ 2022-10-10  9:32 UTC (permalink / raw)
  To: Huacai Chen, Masahiro Yamada, Michal Marek
  Cc: WANG Xuerui, Nick Desaulniers, Daniel Borkmann,
	Alexei Starovoitov, loongarch, linux-kernel, linux-kbuild, bpf

In subsequent patches we'll need to map the same GPR names to integer
constants so that we can use this to build metadata for exception
fixups.

The compiler treats gpr 0 as zero, not $r0, so set it separately to
.L__gpr_num_zero, otherwise the following assembly error will occur,

{standard input}: Assembler messages:
{standard input}:1074: Error: invalid operands (*UND* and *ABS* sections) for `<<'
{standard input}:1160: Error: invalid operands (*UND* and *ABS* sections) for `<<'
make[1]: *** [scripts/Makefile.build:249: fs/fcntl.o] Error 1

Signed-off-by: Youling Tang <tangyouling@loongson.cn>
---
 arch/loongarch/include/asm/gpr-num.h | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)
 create mode 100644 arch/loongarch/include/asm/gpr-num.h

diff --git a/arch/loongarch/include/asm/gpr-num.h b/arch/loongarch/include/asm/gpr-num.h
new file mode 100644
index 000000000000..e0941af20c7e
--- /dev/null
+++ b/arch/loongarch/include/asm/gpr-num.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef __ASM_GPR_NUM_H
+#define __ASM_GPR_NUM_H
+
+#ifdef __ASSEMBLY__
+
+	.equ	.L__gpr_num_zero, 0
+	.irp	num,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31
+	.equ	.L__gpr_num_$r\num, \num
+	.endr
+
+#else /* __ASSEMBLY__ */
+
+#define __DEFINE_ASM_GPR_NUMS					\
+"	.equ	.L__gpr_num_zero, 0\n"				\
+"	.irp	num,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31\n" \
+"	.equ	.L__gpr_num_$r\\num, \\num\n"			\
+"	.endr\n"						\
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __ASM_GPR_NUM_H */
-- 
2.36.1


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

* [PATCH 5/7] LoongArch: extable: Add a dedicated uaccess handler
  2022-10-10  9:32 [PATCH 0/7] LoongArch: Switch to relative extable and other improvements Youling Tang
                   ` (3 preceding siblings ...)
  2022-10-10  9:32 ` [PATCH 4/7] LoongArch: Add gpr-num.h Youling Tang
@ 2022-10-10  9:32 ` Youling Tang
  4 siblings, 0 replies; 6+ messages in thread
From: Youling Tang @ 2022-10-10  9:32 UTC (permalink / raw)
  To: Huacai Chen, Masahiro Yamada, Michal Marek
  Cc: WANG Xuerui, Nick Desaulniers, Daniel Borkmann,
	Alexei Starovoitov, loongarch, linux-kernel, linux-kbuild, bpf

Inspired by commit 2e77a62cb3a6("arm64: extable: add a dedicated uaccess
handler"), do similar to LoongArch to add a dedicated uaccess exception
handler to update registers in exception context and subsequently return
back into the function which faulted, so we remove the need for fixups
specialized to each faulting instruction.

Signed-off-by: Youling Tang <tangyouling@loongson.cn>
---
 arch/loongarch/include/asm/asm-extable.h | 22 +++++++++++++++++++
 arch/loongarch/include/asm/futex.h       | 22 ++++++-------------
 arch/loongarch/include/asm/uaccess.h     | 17 ++++-----------
 arch/loongarch/mm/extable.c              | 27 +++++++++++++++++++++++-
 4 files changed, 58 insertions(+), 30 deletions(-)

diff --git a/arch/loongarch/include/asm/asm-extable.h b/arch/loongarch/include/asm/asm-extable.h
index 634bd770e3c4..f5502cb50c6e 100644
--- a/arch/loongarch/include/asm/asm-extable.h
+++ b/arch/loongarch/include/asm/asm-extable.h
@@ -4,6 +4,7 @@
 
 #define EX_TYPE_NONE			0
 #define EX_TYPE_FIXUP			1
+#define EX_TYPE_UACCESS_ERR_ZERO	2
 
 #ifdef __ASSEMBLY__
 
@@ -24,6 +25,7 @@
 
 #include <linux/bits.h>
 #include <linux/stringify.h>
+#include <asm/gpr-num.h>
 
 #define __ASM_EXTABLE_RAW(insn, fixup, type, data)	\
 	".pushsection	__ex_table, \"a\"\n"		\
@@ -37,6 +39,26 @@
 #define _ASM_EXTABLE(insn, fixup)	\
 	__ASM_EXTABLE_RAW(#insn, #fixup, __stringify(EX_TYPE_FIXUP), "0")
 
+#define EX_DATA_REG_ERR_SHIFT	0
+#define EX_DATA_REG_ERR		GENMASK(4, 0)
+#define EX_DATA_REG_ZERO_SHIFT	5
+#define EX_DATA_REG_ZERO	GENMASK(9, 5)
+
+#define EX_DATA_REG(reg, gpr)						\
+	"((.L__gpr_num_" #gpr ") << " __stringify(EX_DATA_REG_##reg##_SHIFT) ")"
+
+#define _ASM_EXTABLE_UACCESS_ERR_ZERO(insn, fixup, err, zero)		\
+	__DEFINE_ASM_GPR_NUMS						\
+	__ASM_EXTABLE_RAW(#insn, #fixup, 				\
+			  __stringify(EX_TYPE_UACCESS_ERR_ZERO),	\
+			  "("						\
+			    EX_DATA_REG(ERR, err) " | "			\
+			    EX_DATA_REG(ZERO, zero)			\
+			  ")")
+
+#define _ASM_EXTABLE_UACCESS_ERR(insn, fixup, err)			\
+	_ASM_EXTABLE_UACCESS_ERR_ZERO(insn, fixup, err, zero)
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* __ASM_ASM_EXTABLE_H */
diff --git a/arch/loongarch/include/asm/futex.h b/arch/loongarch/include/asm/futex.h
index bdcd1c613299..042ca4448e4d 100644
--- a/arch/loongarch/include/asm/futex.h
+++ b/arch/loongarch/include/asm/futex.h
@@ -19,16 +19,11 @@
 	"2:	sc.w	$t0, %2				\n"	\
 	"	beqz	$t0, 1b				\n"	\
 	"3:						\n"	\
-	"	.section .fixup,\"ax\"			\n"	\
-	"4:	li.w	%0, %6				\n"	\
-	"	b	3b				\n"	\
-	"	.previous				\n"	\
-	_ASM_EXTABLE(1b, 4b)					\
-	_ASM_EXTABLE(2b, 4b)					\
+	_ASM_EXTABLE_UACCESS_ERR(1b, 3b, %0)			\
+	_ASM_EXTABLE_UACCESS_ERR(2b, 3b, %0)			\
 	: "=r" (ret), "=&r" (oldval),				\
 	  "=ZC" (*uaddr)					\
-	: "0" (0), "ZC" (*uaddr), "Jr" (oparg),			\
-	  "i" (-EFAULT)						\
+	: "0" (0), "ZC" (*uaddr), "Jr" (oparg)			\
 	: "memory", "t0");					\
 }
 
@@ -85,15 +80,10 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, u32 oldval, u32 newv
 	"	beqz	$t0, 1b					\n"
 	"3:							\n"
 	__WEAK_LLSC_MB
-	"	.section .fixup,\"ax\"				\n"
-	"4:	li.d	%0, %6					\n"
-	"	b	3b					\n"
-	"	.previous					\n"
-	_ASM_EXTABLE(1b, 4b)
-	_ASM_EXTABLE(2b, 4b)
+	_ASM_EXTABLE_UACCESS_ERR(1b, 3b, %0)
+	_ASM_EXTABLE_UACCESS_ERR(2b, 3b, %0)
 	: "+r" (ret), "=&r" (val), "=ZC" (*uaddr)
-	: "ZC" (*uaddr), "Jr" (oldval), "Jr" (newval),
-	  "i" (-EFAULT)
+	: "ZC" (*uaddr), "Jr" (oldval), "Jr" (newval)
 	: "memory", "t0");
 
 	*uval = val;
diff --git a/arch/loongarch/include/asm/uaccess.h b/arch/loongarch/include/asm/uaccess.h
index e33282e0bdef..255899d4a7c3 100644
--- a/arch/loongarch/include/asm/uaccess.h
+++ b/arch/loongarch/include/asm/uaccess.h
@@ -161,14 +161,9 @@ do {									\
 	__asm__ __volatile__(						\
 	"1:	" insn "	%1, %2				\n"	\
 	"2:							\n"	\
-	"	.section .fixup,\"ax\"				\n"	\
-	"3:	li.w	%0, %3					\n"	\
-	"	move	%1, $zero				\n"	\
-	"	b	2b					\n"	\
-	"	.previous					\n"	\
-	_ASM_EXTABLE(1b, 3b)						\
+	_ASM_EXTABLE_UACCESS_ERR_ZERO(1b, 2b, %0, %1)			\
 	: "+r" (__gu_err), "=r" (__gu_tmp)				\
-	: "m" (__m(ptr)), "i" (-EFAULT));				\
+	: "m" (__m(ptr)));						\
 									\
 	(val) = (__typeof__(*(ptr))) __gu_tmp;				\
 }
@@ -191,13 +186,9 @@ do {									\
 	__asm__ __volatile__(						\
 	"1:	" insn "	%z2, %1		# __put_user_asm\n"	\
 	"2:							\n"	\
-	"	.section	.fixup,\"ax\"			\n"	\
-	"3:	li.w	%0, %3					\n"	\
-	"	b	2b					\n"	\
-	"	.previous					\n"	\
-	_ASM_EXTABLE(1b, 3b)						\
+	_ASM_EXTABLE_UACCESS_ERR(1b, 2b, %0)				\
 	: "+r" (__pu_err), "=m" (__m(ptr))				\
-	: "Jr" (__pu_val), "i" (-EFAULT));				\
+	: "Jr" (__pu_val));						\
 }
 
 #define __get_kernel_nofault(dst, src, type, err_label)			\
diff --git a/arch/loongarch/mm/extable.c b/arch/loongarch/mm/extable.c
index 56b7250fc65e..e6871edd0631 100644
--- a/arch/loongarch/mm/extable.c
+++ b/arch/loongarch/mm/extable.c
@@ -2,11 +2,12 @@
 /*
  * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
  */
+#include <linux/bitfield.h>
 #include <linux/extable.h>
 #include <linux/spinlock.h>
+#include <linux/uaccess.h>
 #include <asm/asm-extable.h>
 #include <asm/branch.h>
-#include <linux/uaccess.h>
 
 static inline unsigned long
 get_ex_fixup(const struct exception_table_entry *ex)
@@ -21,6 +22,28 @@ static bool ex_handler_fixup(const struct exception_table_entry *ex,
 	return true;
 }
 
+static inline void regs_set_gpr(struct pt_regs *regs, unsigned int offset,
+				unsigned long val)
+{
+	if (unlikely(offset > MAX_REG_OFFSET))
+		return;
+
+	if (offset)
+		*(unsigned long *)((unsigned long)regs + offset) = val;
+}
+
+static bool ex_handler_uaccess_err_zero(const struct exception_table_entry *ex,
+					struct pt_regs *regs)
+{
+	int reg_err = FIELD_GET(EX_DATA_REG_ERR, ex->data);
+	int reg_zero = FIELD_GET(EX_DATA_REG_ZERO, ex->data);
+
+	regs_set_gpr(regs, reg_err * sizeof(unsigned long), -EFAULT);
+	regs_set_gpr(regs, reg_zero * sizeof(unsigned long), 0);
+
+	regs->csr_era = get_ex_fixup(ex);
+	return true;
+}
 
 bool fixup_exception(struct pt_regs *regs)
 {
@@ -33,6 +56,8 @@ bool fixup_exception(struct pt_regs *regs)
 	switch (ex->type) {
 	case EX_TYPE_FIXUP:
 		return ex_handler_fixup(ex, regs);
+	case EX_TYPE_UACCESS_ERR_ZERO:
+		return ex_handler_uaccess_err_zero(ex, regs);
 	}
 
 	BUG();
-- 
2.36.1


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

end of thread, other threads:[~2022-10-10  9:32 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-10-10  9:32 [PATCH 0/7] LoongArch: Switch to relative extable and other improvements Youling Tang
2022-10-10  9:32 ` [PATCH 1/7] LoongArch: Consolidate __ex_table construction Youling Tang
2022-10-10  9:32 ` [PATCH 2/7] LoongArch: Switch to relative exception tables Youling Tang
2022-10-10  9:32 ` [PATCH 3/7] LoongArch: extable: Add `type` and `data` fields Youling Tang
2022-10-10  9:32 ` [PATCH 4/7] LoongArch: Add gpr-num.h Youling Tang
2022-10-10  9:32 ` [PATCH 5/7] LoongArch: extable: Add a dedicated uaccess handler Youling Tang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).