mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-04 04:04:19 +00:00
riscv: extable: add type
and data
fields
This is a riscv port of commit d6e2cc5647
("arm64: extable: add `type`
and `data` fields").
Signed-off-by: Jisheng Zhang <jszhang@kernel.org>
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
This commit is contained in:
parent
6dd10d9166
commit
2bf847db0c
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user