[Request for help] issue when add relative extable support to riscv64
Jisheng Zhang
jszhang3 at mail.ustc.edu.cn
Fri Sep 17 09:26:03 PDT 2021
On Fri, 17 Sep 2021 23:57:33 +0800 Jisheng Zhang wrote:
> Hi,
>
> Now the extable entry contains 16bytes for riscv64 -- 8bytes for the insn and
> another 8bytes for the fixup. This wastes mem a bit. I think we can add
> the relative extable support. A draft patch put at the end of this mail. But
> I met abnormal build errors:
>
> FATAL: modpost: The relocation at __ex_table+0x0 references
> section "__ex_table" which is not executable, IOW
> it is not possible for the kernel to fault
> at that address. Something is seriously wrong
> and should be fixed.
>
> I investigated this issue but didn't find any clue. Any suggestion
> is appreciated!
>
> Thanks
>
sorry, I missed two files, the completed patch is here:
diff --git a/arch/riscv/include/asm/Kbuild b/arch/riscv/include/asm/Kbuild
index 445ccc97305a..57b86fd9916c 100644
--- a/arch/riscv/include/asm/Kbuild
+++ b/arch/riscv/include/asm/Kbuild
@@ -1,6 +1,5 @@
# SPDX-License-Identifier: GPL-2.0
generic-y += early_ioremap.h
-generic-y += extable.h
generic-y += flat.h
generic-y += kvm_para.h
generic-y += user.h
diff --git a/arch/riscv/include/asm/extable.h b/arch/riscv/include/asm/extable.h
new file mode 100644
index 000000000000..3a055c7d6a5b
--- /dev/null
+++ b/arch/riscv/include/asm/extable.h
@@ -0,0 +1,12 @@
+#ifndef __ASM_EXTABLE_H
+#define __ASM_EXTABLE_H
+
+struct exception_table_entry
+{
+ int insn, fixup;
+};
+
+#define ARCH_HAS_RELATIVE_EXTABLE
+
+extern int fixup_exception(struct pt_regs *regs);
+#endif
diff --git a/arch/riscv/include/asm/futex.h b/arch/riscv/include/asm/futex.h
index 1b00badb9f87..b220b8387c9d 100644
--- a/arch/riscv/include/asm/futex.h
+++ b/arch/riscv/include/asm/futex.h
@@ -31,8 +31,8 @@
" jump 2b,%[t] \n" \
" .previous \n" \
" .section __ex_table,\"a\" \n" \
- " .balign " RISCV_SZPTR " \n" \
- " " RISCV_PTR " 1b, 3b \n" \
+ " .balign 4 \n" \
+ " .word (1b-.), (3b-.) \n" \
" .previous \n" \
: [r] "+r" (ret), [ov] "=&r" (oldval), \
[u] "+m" (*uaddr), [t] "=&r" (tmp) \
@@ -104,9 +104,9 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
" jump 3b,%[t] \n"
" .previous \n"
" .section __ex_table,\"a\" \n"
- " .balign " RISCV_SZPTR " \n"
- " " RISCV_PTR " 1b, 4b \n"
- " " RISCV_PTR " 2b, 4b \n"
+ " .balign 4 \n"
+ " .word (1b-.), (4b-.) \n"
+ " .word (2b-.), (4b-.) \n"
" .previous \n"
: [r] "+r" (ret), [v] "=&r" (val), [u] "+m" (*uaddr), [t] "=&r" (tmp)
: [ov] "Jr" (oldval), [nv] "Jr" (newval), [e] "i" (-EFAULT)
diff --git a/arch/riscv/include/asm/uaccess.h b/arch/riscv/include/asm/uaccess.h
index f314ff44c48d..097ed3df9b17 100644
--- a/arch/riscv/include/asm/uaccess.h
+++ b/arch/riscv/include/asm/uaccess.h
@@ -94,8 +94,8 @@ do { \
" jump 2b, %2\n" \
" .previous\n" \
" .section __ex_table,\"a\"\n" \
- " .balign " RISCV_SZPTR "\n" \
- " " RISCV_PTR " 1b, 3b\n" \
+ " .balign 4 \n" \
+ " .word (1b - .), (3b - .)\n" \
" .previous" \
: "+r" (err), "=&r" (__x), "=r" (__tmp) \
: "m" (*(ptr)), "i" (-EFAULT)); \
@@ -126,9 +126,9 @@ do { \
" jump 3b, %3\n" \
" .previous\n" \
" .section __ex_table,\"a\"\n" \
- " .balign " RISCV_SZPTR "\n" \
- " " RISCV_PTR " 1b, 4b\n" \
- " " RISCV_PTR " 2b, 4b\n" \
+ " .balign 4 \n" \
+ " .word (1b - .), (4b - .)\n" \
+ " .word (2b - .), (4b - .)\n" \
" .previous" \
: "+r" (err), "=&r" (__lo), "=r" (__hi), \
"=r" (__tmp) \
@@ -234,8 +234,8 @@ do { \
" jump 2b, %1\n" \
" .previous\n" \
" .section __ex_table,\"a\"\n" \
- " .balign " RISCV_SZPTR "\n" \
- " " RISCV_PTR " 1b, 3b\n" \
+ " .balign 4 \n" \
+ " .word (1b - .), (3b - .)\n" \
" .previous" \
: "+r" (err), "=r" (__tmp), "=m" (*(ptr)) \
: "rJ" (__x), "i" (-EFAULT)); \
@@ -263,9 +263,9 @@ do { \
" jump 3b, %1\n" \
" .previous\n" \
" .section __ex_table,\"a\"\n" \
- " .balign " RISCV_SZPTR "\n" \
- " " RISCV_PTR " 1b, 4b\n" \
- " " RISCV_PTR " 2b, 4b\n" \
+ " .balign 4 \n" \
+ " .word (1b - .), (4b - .)\n" \
+ " .word (2b - .), (4b - .)\n" \
" .previous" \
: "+r" (err), "=r" (__tmp), \
"=m" (__ptr[__LSW]), \
@@ -418,8 +418,8 @@ unsigned long __must_check clear_user(void __user *to, unsigned long n)
" jump 1b, %[rc]\n" \
".previous\n" \
".section __ex_table,\"a\"\n" \
- ".balign " RISCV_SZPTR "\n" \
- " " RISCV_PTR " 1b, 2b\n" \
+ ".balign 4 \n" \
+ ".word (1b-.), (2b-.)\n" \
".previous\n" \
: [ret] "=&r" (__ret), \
[rc] "=&r" (__rc), \
@@ -444,8 +444,8 @@ unsigned long __must_check clear_user(void __user *to, unsigned long n)
" jump 1b, %[rc]\n" \
".previous\n" \
".section __ex_table,\"a\"\n" \
- ".balign " RISCV_SZPTR "\n" \
- " " RISCV_PTR " 1b, 2b\n" \
+ ".balign 4 \n" \
+ ".word (1b-.), (2b-.)\n" \
".previous\n" \
: [ret] "=&r" (__ret), \
[rc] "=&r" (__rc), \
diff --git a/arch/riscv/lib/uaccess.S b/arch/riscv/lib/uaccess.S
index 63bc691cff91..b346ecb2a051 100644
--- a/arch/riscv/lib/uaccess.S
+++ b/arch/riscv/lib/uaccess.S
@@ -7,8 +7,8 @@
100:
\op \reg, \addr
.section __ex_table,"a"
- .balign RISCV_SZPTR
- RISCV_PTR 100b, \lbl
+ .balign 4
+ .word (100b - .), (\lbl - .)
.previous
.endm
diff --git a/arch/riscv/mm/extable.c b/arch/riscv/mm/extable.c
index 2fc729422151..6aa8ffac4be7 100644
--- a/arch/riscv/mm/extable.c
+++ b/arch/riscv/mm/extable.c
@@ -17,7 +17,7 @@ int fixup_exception(struct pt_regs *regs)
fixup = search_exception_tables(regs->epc);
if (fixup) {
- regs->epc = fixup->fixup;
+ regs->epc = (unsigned long)&fixup->fixup + fixup->fixup;
return 1;
}
return 0;
diff --git a/scripts/sorttable.c b/scripts/sorttable.c
index f355869c65cd..7c5f6a361946 100644
--- a/scripts/sorttable.c
+++ b/scripts/sorttable.c
@@ -342,6 +342,7 @@ static int do_file(char const *const fname, void *addr)
case EM_PARISC:
case EM_PPC:
case EM_PPC64:
+ case EM_RISCV:
custom_sort = sort_relative_table;
break;
case EM_ARCOMPACT:
@@ -349,7 +350,6 @@ static int do_file(char const *const fname, void *addr)
case EM_ARM:
case EM_MICROBLAZE:
case EM_MIPS:
- case EM_RISCV:
case EM_XTENSA:
break;
default:
> diff --git a/arch/riscv/include/asm/Kbuild b/arch/riscv/include/asm/Kbuild
> index 445ccc97305a..57b86fd9916c 100644
> --- a/arch/riscv/include/asm/Kbuild
> +++ b/arch/riscv/include/asm/Kbuild
> @@ -1,6 +1,5 @@
> # SPDX-License-Identifier: GPL-2.0
> generic-y += early_ioremap.h
> -generic-y += extable.h
> generic-y += flat.h
> generic-y += kvm_para.h
> generic-y += user.h
> diff --git a/arch/riscv/include/asm/futex.h b/arch/riscv/include/asm/futex.h
> index 1b00badb9f87..b220b8387c9d 100644
> --- a/arch/riscv/include/asm/futex.h
> +++ b/arch/riscv/include/asm/futex.h
> @@ -31,8 +31,8 @@
> " jump 2b,%[t] \n" \
> " .previous \n" \
> " .section __ex_table,\"a\" \n" \
> - " .balign " RISCV_SZPTR " \n" \
> - " " RISCV_PTR " 1b, 3b \n" \
> + " .balign 4 \n" \
> + " .word (1b-.), (3b-.) \n" \
> " .previous \n" \
> : [r] "+r" (ret), [ov] "=&r" (oldval), \
> [u] "+m" (*uaddr), [t] "=&r" (tmp) \
> @@ -104,9 +104,9 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
> " jump 3b,%[t] \n"
> " .previous \n"
> " .section __ex_table,\"a\" \n"
> - " .balign " RISCV_SZPTR " \n"
> - " " RISCV_PTR " 1b, 4b \n"
> - " " RISCV_PTR " 2b, 4b \n"
> + " .balign 4 \n"
> + " .word (1b-.), (4b-.) \n"
> + " .word (2b-.), (4b-.) \n"
> " .previous \n"
> : [r] "+r" (ret), [v] "=&r" (val), [u] "+m" (*uaddr), [t] "=&r" (tmp)
> : [ov] "Jr" (oldval), [nv] "Jr" (newval), [e] "i" (-EFAULT)
> diff --git a/arch/riscv/include/asm/uaccess.h b/arch/riscv/include/asm/uaccess.h
> index f314ff44c48d..097ed3df9b17 100644
> --- a/arch/riscv/include/asm/uaccess.h
> +++ b/arch/riscv/include/asm/uaccess.h
> @@ -94,8 +94,8 @@ do { \
> " jump 2b, %2\n" \
> " .previous\n" \
> " .section __ex_table,\"a\"\n" \
> - " .balign " RISCV_SZPTR "\n" \
> - " " RISCV_PTR " 1b, 3b\n" \
> + " .balign 4 \n" \
> + " .word (1b - .), (3b - .)\n" \
> " .previous" \
> : "+r" (err), "=&r" (__x), "=r" (__tmp) \
> : "m" (*(ptr)), "i" (-EFAULT)); \
> @@ -126,9 +126,9 @@ do { \
> " jump 3b, %3\n" \
> " .previous\n" \
> " .section __ex_table,\"a\"\n" \
> - " .balign " RISCV_SZPTR "\n" \
> - " " RISCV_PTR " 1b, 4b\n" \
> - " " RISCV_PTR " 2b, 4b\n" \
> + " .balign 4 \n" \
> + " .word (1b - .), (4b - .)\n" \
> + " .word (2b - .), (4b - .)\n" \
> " .previous" \
> : "+r" (err), "=&r" (__lo), "=r" (__hi), \
> "=r" (__tmp) \
> @@ -234,8 +234,8 @@ do { \
> " jump 2b, %1\n" \
> " .previous\n" \
> " .section __ex_table,\"a\"\n" \
> - " .balign " RISCV_SZPTR "\n" \
> - " " RISCV_PTR " 1b, 3b\n" \
> + " .balign 4 \n" \
> + " .word (1b - .), (3b - .)\n" \
> " .previous" \
> : "+r" (err), "=r" (__tmp), "=m" (*(ptr)) \
> : "rJ" (__x), "i" (-EFAULT)); \
> @@ -263,9 +263,9 @@ do { \
> " jump 3b, %1\n" \
> " .previous\n" \
> " .section __ex_table,\"a\"\n" \
> - " .balign " RISCV_SZPTR "\n" \
> - " " RISCV_PTR " 1b, 4b\n" \
> - " " RISCV_PTR " 2b, 4b\n" \
> + " .balign 4 \n" \
> + " .word (1b - .), (4b - .)\n" \
> + " .word (2b - .), (4b - .)\n" \
> " .previous" \
> : "+r" (err), "=r" (__tmp), \
> "=m" (__ptr[__LSW]), \
> @@ -418,8 +418,8 @@ unsigned long __must_check clear_user(void __user *to, unsigned long n)
> " jump 1b, %[rc]\n" \
> ".previous\n" \
> ".section __ex_table,\"a\"\n" \
> - ".balign " RISCV_SZPTR "\n" \
> - " " RISCV_PTR " 1b, 2b\n" \
> + ".balign 4 \n" \
> + ".word (1b-.), (2b-.)\n" \
> ".previous\n" \
> : [ret] "=&r" (__ret), \
> [rc] "=&r" (__rc), \
> @@ -444,8 +444,8 @@ unsigned long __must_check clear_user(void __user *to, unsigned long n)
> " jump 1b, %[rc]\n" \
> ".previous\n" \
> ".section __ex_table,\"a\"\n" \
> - ".balign " RISCV_SZPTR "\n" \
> - " " RISCV_PTR " 1b, 2b\n" \
> + ".balign 4 \n" \
> + ".word (1b-.), (2b-.)\n" \
> ".previous\n" \
> : [ret] "=&r" (__ret), \
> [rc] "=&r" (__rc), \
> diff --git a/arch/riscv/lib/uaccess.S b/arch/riscv/lib/uaccess.S
> index 63bc691cff91..b346ecb2a051 100644
> --- a/arch/riscv/lib/uaccess.S
> +++ b/arch/riscv/lib/uaccess.S
> @@ -7,8 +7,8 @@
> 100:
> \op \reg, \addr
> .section __ex_table,"a"
> - .balign RISCV_SZPTR
> - RISCV_PTR 100b, \lbl
> + .balign 4
> + .word (100b - .), (\lbl - .)
> .previous
> .endm
>
> diff --git a/arch/riscv/mm/extable.c b/arch/riscv/mm/extable.c
> index 2fc729422151..6aa8ffac4be7 100644
> --- a/arch/riscv/mm/extable.c
> +++ b/arch/riscv/mm/extable.c
> @@ -17,7 +17,7 @@ int fixup_exception(struct pt_regs *regs)
>
> fixup = search_exception_tables(regs->epc);
> if (fixup) {
> - regs->epc = fixup->fixup;
> + regs->epc = (unsigned long)&fixup->fixup + fixup->fixup;
> return 1;
> }
> return 0;
>
>
> _______________________________________________
> linux-riscv mailing list
> linux-riscv at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-riscv
More information about the linux-riscv
mailing list