Skip to content

Commit

Permalink
riscv: extable: add type and data fields
Browse files Browse the repository at this point in the history
This is a riscv port of commit d6e2cc5 ("arm64: extable: add `type`
and `data` fields").

Signed-off-by: Jisheng Zhang <jszhang@kernel.org>
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
  • Loading branch information
xhackerustc authored and palmer-dabbelt committed Jan 6, 2022
1 parent 6dd10d9 commit 2bf847d
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 19 deletions.
25 changes: 17 additions & 8 deletions arch/riscv/include/asm/asm-extable.h
Original file line number Diff line number Diff line change
Expand Up @@ -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__ */

Expand Down
17 changes: 14 additions & 3 deletions arch/riscv/include/asm/extable.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
2 changes: 1 addition & 1 deletion arch/riscv/kernel/vmlinux.lds.S
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
25 changes: 21 additions & 4 deletions arch/riscv/mm/extable.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -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();
}
5 changes: 3 additions & 2 deletions arch/riscv/net/bpf_jit_comp64.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion scripts/sorttable.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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:
Expand Down

0 comments on commit 2bf847d

Please sign in to comment.