Message ID | 20211118192605.57e06d6b@xhacker (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | riscv: switch to relative extable and other improvements | expand |
On Thu, 18 Nov 2021 19:26:05 +0800 Jisheng Zhang wrote: > From: Jisheng Zhang <jszhang@kernel.org> > > 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@kernel.org> > --- > 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:
On Thu, Nov 18, 2021 at 07:42:49PM +0800, Jisheng Zhang wrote: > On Thu, 18 Nov 2021 19:26:05 +0800 Jisheng Zhang wrote: > > > From: Jisheng Zhang <jszhang@kernel.org> > > > > 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@kernel.org> > > 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? I sent a patch last week which unifies them as sort_relative_table_with_data(): https://lore.kernel.org/linux-arm-kernel/20211108114220.32796-1-mark.rutland@arm.com/ Thomas, are you happy with that patch? With your ack it could go via the riscv tree for v5.17 as a preparatory cleanup in this series. Maybe we could get it in as a cleanup for v5.16-rc{2,3} ? Thanks, Mark.
On 2021/11/18 19:26, Jisheng Zhang wrote: > From: Jisheng Zhang <jszhang@kernel.org> > > 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@kernel.org> > --- > 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; looks good to me. Reviewed-by:Tong Tiangen <tongtiangen@huawei.com> > > 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; > + break; > case EM_ARCOMPACT: > case EM_ARCV2: > case EM_ARM: >
On Thu, 18 Nov 2021 07:21:55 PST (-0800), mark.rutland@arm.com wrote: > On Thu, Nov 18, 2021 at 07:42:49PM +0800, Jisheng Zhang wrote: >> On Thu, 18 Nov 2021 19:26:05 +0800 Jisheng Zhang wrote: >> >> > From: Jisheng Zhang <jszhang@kernel.org> >> > >> > 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@kernel.org> > >> > 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? > > I sent a patch last week which unifies them as > sort_relative_table_with_data(): > > https://lore.kernel.org/linux-arm-kernel/20211108114220.32796-1-mark.rutland@arm.com/ > > Thomas, are you happy with that patch? > > With your ack it could go via the riscv tree for v5.17 as a preparatory > cleanup in this series. > > Maybe we could get it in as a cleanup for v5.16-rc{2,3} ? I don't see anything on that thread, and looks like last time I had to touch sorttable I just took it via the RISC-V tree. I went ahead and put Mark's patch, along with this patch set, on my for-next. I had to fix up a few minor issues, so LMK if anything went off the rails. Thanks!
On Wed, Jan 05, 2022 at 07:21:26PM -0800, Palmer Dabbelt wrote: > On Thu, 18 Nov 2021 07:21:55 PST (-0800), mark.rutland@arm.com wrote: > > On Thu, Nov 18, 2021 at 07:42:49PM +0800, Jisheng Zhang wrote: > > > On Thu, 18 Nov 2021 19:26:05 +0800 Jisheng Zhang wrote: > > > 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? > > > > I sent a patch last week which unifies them as > > sort_relative_table_with_data(): > > > > https://lore.kernel.org/linux-arm-kernel/20211108114220.32796-1-mark.rutland@arm.com/ > > > > Thomas, are you happy with that patch? > > > > With your ack it could go via the riscv tree for v5.17 as a preparatory > > cleanup in this series. > > > > Maybe we could get it in as a cleanup for v5.16-rc{2,3} ? > > I don't see anything on that thread, and looks like last time I had to touch > sorttable I just took it via the RISC-V tree. I went ahead and put Mark's > patch, along with this patch set, on my for-next. FWIW, that sounds good to me. Thanks for picking that up! > I had to fix up a few minor issues, so LMK if anything went off the rails. I assume that was just for this patch set, as I couldn't spot any change to my patch in the riscv for-next branch. Thanks, Mark.
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; + break; case EM_ARCOMPACT: case EM_ARCV2: case EM_ARM: