提交 82f69454 编写于 作者: Y Youling Tang 提交者: Hongchen Zhang

LoongArch: extable: Add `type` and `data` fields

mainline inclusion
from mainline-v6.2-rc1
commit 26bc8244
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I6BWFP
CVE: NA

--------------------------------

This is a LoongArch port of commit d6e2cc56 ("arm64: extable: add
`type` and `data` fields").

Subsequent patches will add specialized handlers for fixups, in addition
to the simple PC fixup we have today. In preparation, this patch adds a
new `type` field to struct exception_table_entry, and uses this to
distinguish the fixup and other cases. A `data` field is also added so
that subsequent patches can associate data specific to each exception
site (e.g. register numbers).

Handlers are named ex_handler_*() for consistency, following the example
of x86. At the same time, get_ex_fixup() is split out into a helper so
that it can be used by other ex_handler_*() functions in the subsequent
patches.
Signed-off-by: NYouling Tang <tangyouling@loongson.cn>
Signed-off-by: NHuacai Chen <chenhuacai@loongson.cn>
Change-Id: I95ac7a755a8a3389b63b92c1e98a851c1993c0aa
上级 a2603778
...@@ -2,17 +2,22 @@ ...@@ -2,17 +2,22 @@
#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
#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__ */
...@@ -20,15 +25,17 @@ ...@@ -20,15 +25,17 @@
#include <linux/bits.h> #include <linux/bits.h>
#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) \ #define _ASM_EXTABLE(insn, fixup) \
__ASM_EXTABLE_RAW(#insn, #fixup) __ASM_EXTABLE_RAW(#insn, #fixup, __stringify(EX_TYPE_FIXUP), "0")
#endif /* __ASSEMBLY__ */ #endif /* __ASSEMBLY__ */
......
...@@ -17,10 +17,21 @@ ...@@ -17,10 +17,21 @@
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);
#endif #endif
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include <asm/thread_info.h> #include <asm/thread_info.h>
#define PAGE_SIZE _PAGE_SIZE #define PAGE_SIZE _PAGE_SIZE
#define RO_EXCEPTION_TABLE_ALIGN 4
/* /*
* Put .bss..swapper_pg_dir as the first thing in .bss. This will * Put .bss..swapper_pg_dir as the first thing in .bss. This will
...@@ -53,8 +54,6 @@ SECTIONS ...@@ -53,8 +54,6 @@ SECTIONS
. = ALIGN(PECOFF_SEGMENT_ALIGN); . = ALIGN(PECOFF_SEGMENT_ALIGN);
_etext = .; _etext = .;
EXCEPTION_TABLE(16)
. = ALIGN(PECOFF_SEGMENT_ALIGN); . = ALIGN(PECOFF_SEGMENT_ALIGN);
__init_begin = .; __init_begin = .;
__inittext_begin = .; __inittext_begin = .;
......
...@@ -30,5 +30,10 @@ bool fixup_exception(struct pt_regs *regs) ...@@ -30,5 +30,10 @@ bool fixup_exception(struct pt_regs *regs)
if (!ex) if (!ex)
return false; return false;
return ex_handler_fixup(ex, regs); switch (ex->type) {
case EX_TYPE_FIXUP:
return ex_handler_fixup(ex, regs);
}
BUG();
} }
...@@ -231,6 +231,34 @@ static void sort_relative_table(char *extab_image, int image_size) ...@@ -231,6 +231,34 @@ static void sort_relative_table(char *extab_image, int image_size)
} }
} }
static void sort_relative_table_with_data(char *extab_image, int image_size)
{
int i = 0;
while (i < image_size) {
uint32_t *loc = (uint32_t *)(extab_image + i);
w(r(loc) + i, loc);
w(r(loc + 1) + i + 4, loc + 1);
/* Don't touch the fixup type or data */
i += sizeof(uint32_t) * 3;
}
qsort(extab_image, image_size / 12, 12, compare_relative_table);
i = 0;
while (i < image_size) {
uint32_t *loc = (uint32_t *)(extab_image + i);
w(r(loc) - i, loc);
w(r(loc + 1) - (i + 4), loc + 1);
/* Don't touch the fixup type or data */
i += sizeof(uint32_t) * 3;
}
}
static void x86_sort_relative_table(char *extab_image, int image_size) static void x86_sort_relative_table(char *extab_image, int image_size)
{ {
int i = 0; int i = 0;
...@@ -339,6 +367,9 @@ static int do_file(char const *const fname, void *addr) ...@@ -339,6 +367,9 @@ static int do_file(char const *const fname, void *addr)
case EM_X86_64: case EM_X86_64:
custom_sort = x86_sort_relative_table; custom_sort = x86_sort_relative_table;
break; break;
case EM_LOONGARCH:
custom_sort = sort_relative_table_with_data;
break;
case EM_S390: case EM_S390:
custom_sort = s390_sort_relative_table; custom_sort = s390_sort_relative_table;
break; break;
...@@ -347,7 +378,6 @@ static int do_file(char const *const fname, void *addr) ...@@ -347,7 +378,6 @@ static int do_file(char const *const fname, void *addr)
case EM_PPC: case EM_PPC:
case EM_ARM: case EM_ARM:
case EM_PPC64: case EM_PPC64:
case EM_LOONGARCH:
custom_sort = sort_relative_table; custom_sort = sort_relative_table;
break; break;
case EM_ARCOMPACT: case EM_ARCOMPACT:
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册