diff mbox series

[09/12] riscv: extable: add `type` and `data` fields

Message ID 20211118192605.57e06d6b@xhacker (mailing list archive)
State Not Applicable
Delegated to: Netdev Maintainers
Headers show
Series riscv: switch to relative extable and other improvements | expand

Checks

Context Check Description
netdev/tree_selection success Not a local patch

Commit Message

Jisheng Zhang Nov. 18, 2021, 11:26 a.m. UTC
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(-)

Comments

Jisheng Zhang Nov. 18, 2021, 11:42 a.m. UTC | #1
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:
Mark Rutland Nov. 18, 2021, 3:21 p.m. UTC | #2
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.
Tong Tiangen Nov. 19, 2021, 2:35 a.m. UTC | #3
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:
>
Palmer Dabbelt Jan. 6, 2022, 3:21 a.m. UTC | #4
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!
Mark Rutland Jan. 6, 2022, 10:23 a.m. UTC | #5
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 mbox series

Patch

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: