Commit 2bf847db authored by Jisheng Zhang's avatar Jisheng Zhang Committed by Palmer Dabbelt

riscv: extable: add `type` and `data` fields

This is a riscv port of commit d6e2cc56 ("arm64: extable: add `type`
and `data` fields").
Signed-off-by: default avatarJisheng Zhang <jszhang@kernel.org>
Signed-off-by: default avatarPalmer Dabbelt <palmer@rivosinc.com>
parent 6dd10d91
......@@ -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__ */
......
......@@ -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;
}
......
......@@ -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"
......
......@@ -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();
}
......@@ -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;
......
......@@ -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:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment