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

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
Loading
Loading
Loading
Loading
+17 −8
Original line number Diff line number Diff line
@@ -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)		\
#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__ */

+14 −3
Original line number Diff line number Diff line
@@ -17,17 +17,28 @@

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,
ex_handler_bpf(const struct exception_table_entry *ex,
	       struct pt_regs *regs)
{
	return false;
+1 −1
Original line number Diff line number Diff line
@@ -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"
+21 −4
Original line number Diff line number Diff line
@@ -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();
}
+3 −2
Original line number Diff line number Diff line
@@ -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_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)
{
	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,

	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;
Loading