LoongArch: extable: Add `type` and `data` fields
authorYouling Tang <tangyouling@loongson.cn>
Sat, 10 Dec 2022 14:39:59 +0000 (22:39 +0800)
committerHuacai Chen <chenhuacai@loongson.cn>
Wed, 14 Dec 2022 00:36:11 +0000 (08:36 +0800)
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 in the subsequent
patches.

Signed-off-by: Youling Tang <tangyouling@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
arch/loongarch/include/asm/asm-extable.h
arch/loongarch/include/asm/extable.h
arch/loongarch/kernel/vmlinux.lds.S
arch/loongarch/mm/extable.c
scripts/sorttable.c

index 74f8bc7..634bd77 100644 (file)
@@ -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__ */
 #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__ */
 
index b571c89..92612b4 100644 (file)
 
 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
index b3309a5..efecda0 100644 (file)
@@ -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) }
index 08a9a7d..fd23952 100644 (file)
@@ -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();
 }
index 0f2beda..83cdb84 100644 (file)
@@ -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: