On Thu, 18 Nov 2021 19:26:05 +0800 Jisheng Zhang wrote: > From: Jisheng Zhang <jszhang@xxxxxxxxxx> > > This is a riscv port of commit d6e2cc564775("arm64: extable: add `type` > and `data` fields"). > > We will add specialized handlers for fixups, the `type` field is for > fixup handler type, the `data` field is used to pass specific data to > each handler, for example register numbers. > > Signed-off-by: Jisheng Zhang <jszhang@xxxxxxxxxx> > --- > arch/riscv/include/asm/asm-extable.h | 25 +++++++++++++++++-------- > arch/riscv/include/asm/extable.h | 17 ++++++++++++++--- > arch/riscv/kernel/vmlinux.lds.S | 2 +- > arch/riscv/mm/extable.c | 25 +++++++++++++++++++++---- > arch/riscv/net/bpf_jit_comp64.c | 5 +++-- > scripts/sorttable.c | 4 +++- > 6 files changed, 59 insertions(+), 19 deletions(-) > > diff --git a/arch/riscv/include/asm/asm-extable.h b/arch/riscv/include/asm/asm-extable.h > index b790c02dbdda..1b1f4ffd8d37 100644 > --- a/arch/riscv/include/asm/asm-extable.h > +++ b/arch/riscv/include/asm/asm-extable.h > @@ -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__ */ > > diff --git a/arch/riscv/include/asm/extable.h b/arch/riscv/include/asm/extable.h > index e4374dde02b4..512012d193dc 100644 > --- a/arch/riscv/include/asm/extable.h > +++ b/arch/riscv/include/asm/extable.h > @@ -17,18 +17,29 @@ > > 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; > } > diff --git a/arch/riscv/kernel/vmlinux.lds.S b/arch/riscv/kernel/vmlinux.lds.S > index 5104f3a871e3..0e5ae851929e 100644 > --- a/arch/riscv/kernel/vmlinux.lds.S > +++ b/arch/riscv/kernel/vmlinux.lds.S > @@ -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" > diff --git a/arch/riscv/mm/extable.c b/arch/riscv/mm/extable.c > index 3c561f1d0115..91e52c4bb33a 100644 > --- a/arch/riscv/mm/extable.c > +++ b/arch/riscv/mm/extable.c > @@ -10,6 +10,20 @@ > #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(); > } > diff --git a/arch/riscv/net/bpf_jit_comp64.c b/arch/riscv/net/bpf_jit_comp64.c > index 7714081cbb64..69bab7e28f91 100644 > --- a/arch/riscv/net/bpf_jit_comp64.c > +++ b/arch/riscv/net/bpf_jit_comp64.c > @@ -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; > diff --git a/scripts/sorttable.c b/scripts/sorttable.c > index 0c031e47a419..5b5472b543f5 100644 > --- a/scripts/sorttable.c > +++ b/scripts/sorttable.c > @@ -376,9 +376,11 @@ 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_RISCV: > + custom_sort = arm64_sort_relative_table; Hi Mark, Thomas, x86 and arm64 version of sort_relative_table routine are the same, I want to unify them, and then use the common function for riscv, but I'm not sure which name is better. Could you please suggest? Thanks > + break; > case EM_ARCOMPACT: > case EM_ARCV2: > case EM_ARM: