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 @@ ...@@ -2,31 +2,40 @@
#ifndef __ASM_ASM_EXTABLE_H #ifndef __ASM_ASM_EXTABLE_H
#define __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__ #ifdef __ASSEMBLY__
#define __ASM_EXTABLE_RAW(insn, fixup) \ #define __ASM_EXTABLE_RAW(insn, fixup, type, data) \
.pushsection __ex_table, "a"; \ .pushsection __ex_table, "a"; \
.balign 4; \ .balign 4; \
.long ((insn) - .); \ .long ((insn) - .); \
.long ((fixup) - .); \ .long ((fixup) - .); \
.short (type); \
.short (data); \
.popsection; .popsection;
.macro _asm_extable, insn, fixup .macro _asm_extable, insn, fixup
__ASM_EXTABLE_RAW(\insn, \fixup) __ASM_EXTABLE_RAW(\insn, \fixup, EX_TYPE_FIXUP, 0)
.endm .endm
#else /* __ASSEMBLY__ */ #else /* __ASSEMBLY__ */
#include <linux/stringify.h> #include <linux/stringify.h>
#define __ASM_EXTABLE_RAW(insn, fixup) \ #define __ASM_EXTABLE_RAW(insn, fixup, type, data) \
".pushsection __ex_table, \"a\"\n" \ ".pushsection __ex_table, \"a\"\n" \
".balign 4\n" \ ".balign 4\n" \
".long ((" insn ") - .)\n" \ ".long ((" insn ") - .)\n" \
".long ((" fixup ") - .)\n" \ ".long ((" fixup ") - .)\n" \
".short (" type ")\n" \
".short (" data ")\n" \
".popsection\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__ */ #endif /* __ASSEMBLY__ */
......
...@@ -17,17 +17,28 @@ ...@@ -17,17 +17,28 @@
struct exception_table_entry { struct exception_table_entry {
int insn, fixup; int insn, fixup;
short type, data;
}; };
#define ARCH_HAS_RELATIVE_EXTABLE #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); bool fixup_exception(struct pt_regs *regs);
#if defined(CONFIG_BPF_JIT) && defined(CONFIG_ARCH_RV64I) #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 #else
static inline bool static inline bool
rv_bpf_fixup_exception(const struct exception_table_entry *ex, ex_handler_bpf(const struct exception_table_entry *ex,
struct pt_regs *regs) struct pt_regs *regs)
{ {
return false; return false;
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* Copyright (C) 2017 SiFive * Copyright (C) 2017 SiFive
*/ */
#define RO_EXCEPTION_TABLE_ALIGN 16 #define RO_EXCEPTION_TABLE_ALIGN 4
#ifdef CONFIG_XIP_KERNEL #ifdef CONFIG_XIP_KERNEL
#include "vmlinux-xip.lds.S" #include "vmlinux-xip.lds.S"
......
...@@ -10,6 +10,20 @@ ...@@ -10,6 +10,20 @@
#include <linux/extable.h> #include <linux/extable.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/uaccess.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) bool fixup_exception(struct pt_regs *regs)
{ {
...@@ -19,9 +33,12 @@ bool fixup_exception(struct pt_regs *regs) ...@@ -19,9 +33,12 @@ bool fixup_exception(struct pt_regs *regs)
if (!ex) if (!ex)
return false; return false;
if (regs->epc >= BPF_JIT_REGION_START && regs->epc < BPF_JIT_REGION_END) switch (ex->type) {
return rv_bpf_fixup_exception(ex, regs); 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; BUG();
return true;
} }
...@@ -459,7 +459,7 @@ static int emit_call(bool fixed, u64 addr, struct rv_jit_context *ctx) ...@@ -459,7 +459,7 @@ static int emit_call(bool fixed, u64 addr, struct rv_jit_context *ctx)
#define BPF_FIXUP_OFFSET_MASK GENMASK(26, 0) #define BPF_FIXUP_OFFSET_MASK GENMASK(26, 0)
#define BPF_FIXUP_REG_MASK GENMASK(31, 27) #define BPF_FIXUP_REG_MASK GENMASK(31, 27)
bool rv_bpf_fixup_exception(const struct exception_table_entry *ex, bool ex_handler_bpf(const struct exception_table_entry *ex,
struct pt_regs *regs) struct pt_regs *regs)
{ {
off_t offset = FIELD_GET(BPF_FIXUP_OFFSET_MASK, ex->fixup); off_t offset = FIELD_GET(BPF_FIXUP_OFFSET_MASK, ex->fixup);
...@@ -514,6 +514,7 @@ static int add_exception_handler(const struct bpf_insn *insn, ...@@ -514,6 +514,7 @@ static int add_exception_handler(const struct bpf_insn *insn,
ex->fixup = FIELD_PREP(BPF_FIXUP_OFFSET_MASK, offset) | ex->fixup = FIELD_PREP(BPF_FIXUP_OFFSET_MASK, offset) |
FIELD_PREP(BPF_FIXUP_REG_MASK, dst_reg); FIELD_PREP(BPF_FIXUP_REG_MASK, dst_reg);
ex->type = EX_TYPE_BPF;
ctx->nexentries++; ctx->nexentries++;
return 0; return 0;
......
...@@ -337,6 +337,7 @@ static int do_file(char const *const fname, void *addr) ...@@ -337,6 +337,7 @@ static int do_file(char const *const fname, void *addr)
switch (r2(&ehdr->e_machine)) { switch (r2(&ehdr->e_machine)) {
case EM_386: case EM_386:
case EM_AARCH64: case EM_AARCH64:
case EM_RISCV:
case EM_X86_64: case EM_X86_64:
custom_sort = sort_relative_table_with_data; custom_sort = sort_relative_table_with_data;
break; break;
...@@ -346,7 +347,6 @@ static int do_file(char const *const fname, void *addr) ...@@ -346,7 +347,6 @@ static int do_file(char const *const fname, void *addr)
case EM_PARISC: case EM_PARISC:
case EM_PPC: case EM_PPC:
case EM_PPC64: case EM_PPC64:
case EM_RISCV:
custom_sort = sort_relative_table; custom_sort = sort_relative_table;
break; break;
case EM_ARCOMPACT: 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