riscv: extable: add `type` and `data` fields
authorJisheng Zhang <jszhang@kernel.org>
Thu, 18 Nov 2021 11:26:05 +0000 (19:26 +0800)
committerPalmer Dabbelt <palmer@rivosinc.com>
Thu, 6 Jan 2022 01:52:54 +0000 (17:52 -0800)
This is a riscv port of commit d6e2cc564775 ("arm64: extable: add `type`
and `data` fields").

Signed-off-by: Jisheng Zhang <jszhang@kernel.org>
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
arch/riscv/include/asm/asm-extable.h
arch/riscv/include/asm/extable.h
arch/riscv/kernel/vmlinux.lds.S
arch/riscv/mm/extable.c
arch/riscv/net/bpf_jit_comp64.c
scripts/sorttable.c

index b790c02..1b1f4ff 100644 (file)
@@ -2,31 +2,40 @@
 #ifndef __ASM_ASM_EXTABLE_H
 #define __ASM_ASM_EXTABLE_H
 
+#define EX_TYPE_NONE                   0
+#define EX_TYPE_FIXUP                  1
+#define EX_TYPE_BPF                    2
+
 #ifdef __ASSEMBLY__
 
-#define __ASM_EXTABLE_RAW(insn, fixup)         \
-       .pushsection    __ex_table, "a";        \
-       .balign         4;                      \
-       .long           ((insn) - .);           \
-       .long           ((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/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)
+#define _ASM_EXTABLE(insn, fixup)      \
+       __ASM_EXTABLE_RAW(#insn, #fixup, __stringify(EX_TYPE_FIXUP), "0")
 
 #endif /* __ASSEMBLY__ */
 
index e4374dd..512012d 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);
 
 #if defined(CONFIG_BPF_JIT) && defined(CONFIG_ARCH_RV64I)
-bool rv_bpf_fixup_exception(const struct exception_table_entry *ex, struct pt_regs *regs);
+bool ex_handler_bpf(const struct exception_table_entry *ex, struct pt_regs *regs);
 #else
 static inline bool
-rv_bpf_fixup_exception(const struct exception_table_entry *ex,
-                      struct pt_regs *regs)
+ex_handler_bpf(const struct exception_table_entry *ex,
+              struct pt_regs *regs)
 {
        return false;
 }
index 5104f3a..0e5ae85 100644 (file)
@@ -4,7 +4,7 @@
  * Copyright (C) 2017 SiFive
  */
 
-#define RO_EXCEPTION_TABLE_ALIGN       16
+#define RO_EXCEPTION_TABLE_ALIGN       4
 
 #ifdef CONFIG_XIP_KERNEL
 #include "vmlinux-xip.lds.S"
index 3c561f1..91e52c4 100644 (file)
 #include <linux/extable.h>
 #include <linux/module.h>
 #include <linux/uaccess.h>
+#include <asm/asm-extable.h>
+
+static inline unsigned long
+get_ex_fixup(const struct exception_table_entry *ex)
+{
+       return ((unsigned long)&ex->fixup + ex->fixup);
+}
+
+static bool ex_handler_fixup(const struct exception_table_entry *ex,
+                            struct pt_regs *regs)
+{
+       regs->epc = get_ex_fixup(ex);
+       return true;
+}
 
 bool fixup_exception(struct pt_regs *regs)
 {
@@ -19,9 +33,12 @@ bool fixup_exception(struct pt_regs *regs)
        if (!ex)
                return false;
 
-       if (regs->epc >= BPF_JIT_REGION_START && regs->epc < BPF_JIT_REGION_END)
-               return rv_bpf_fixup_exception(ex, regs);
+       switch (ex->type) {
+       case EX_TYPE_FIXUP:
+               return ex_handler_fixup(ex, regs);
+       case EX_TYPE_BPF:
+               return ex_handler_bpf(ex, regs);
+       }
 
-       regs->epc = (unsigned long)&ex->fixup + ex->fixup;
-       return true;
+       BUG();
 }
index 7714081..69bab7e 100644 (file)
@@ -459,8 +459,8 @@ static int emit_call(bool fixed, u64 addr, struct rv_jit_context *ctx)
 #define BPF_FIXUP_OFFSET_MASK   GENMASK(26, 0)
 #define BPF_FIXUP_REG_MASK      GENMASK(31, 27)
 
-bool rv_bpf_fixup_exception(const struct exception_table_entry *ex,
-                           struct pt_regs *regs)
+bool ex_handler_bpf(const struct exception_table_entry *ex,
+                   struct pt_regs *regs)
 {
        off_t offset = FIELD_GET(BPF_FIXUP_OFFSET_MASK, ex->fixup);
        int regs_offset = FIELD_GET(BPF_FIXUP_REG_MASK, ex->fixup);
@@ -514,6 +514,7 @@ static int add_exception_handler(const struct bpf_insn *insn,
 
        ex->fixup = FIELD_PREP(BPF_FIXUP_OFFSET_MASK, offset) |
                FIELD_PREP(BPF_FIXUP_REG_MASK, dst_reg);
+       ex->type = EX_TYPE_BPF;
 
        ctx->nexentries++;
        return 0;
index f4a8255..82b162b 100644 (file)
@@ -337,6 +337,7 @@ static int do_file(char const *const fname, void *addr)
        switch (r2(&ehdr->e_machine)) {
        case EM_386:
        case EM_AARCH64:
+       case EM_RISCV:
        case EM_X86_64:
                custom_sort = sort_relative_table_with_data;
                break;
@@ -346,7 +347,6 @@ 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: