提交 61dbbaeb 编写于 作者: H Helge Deller

parisc: provide macro to create exception table entries

Provide a macro ASM_EXCEPTIONTABLE_ENTRY() to create exception table
entries and convert all open-coded places to use that macro.

This patch is a first step toward creating a exception table which only
holds 32bit pointers even on a 64bit kernel. That way in my own kernel
I was able to reduce the in-kernel exception table from 44kB to 22kB.
Signed-off-by: NHelge Deller <deller@gmx.de>
上级 5e01dc7b
...@@ -515,5 +515,17 @@ ...@@ -515,5 +515,17 @@
nop /* 7 */ nop /* 7 */
.endm .endm
/*
* ASM_EXCEPTIONTABLE_ENTRY
*
* Creates an exception table entry.
* Do not convert to a assembler macro. This won't work.
*/
#define ASM_EXCEPTIONTABLE_ENTRY(fault_addr, except_addr) \
.section __ex_table,"aw" ! \
ASM_ULONG_INSN fault_addr, except_addr ! \
.previous
#endif /* __ASSEMBLY__ */ #endif /* __ASSEMBLY__ */
#endif #endif
...@@ -59,12 +59,13 @@ static inline long access_ok(int type, const void __user * addr, ...@@ -59,12 +59,13 @@ static inline long access_ok(int type, const void __user * addr,
/* /*
* The exception table contains two values: the first is an address * The exception table contains two values: the first is an address
* for an instruction that is allowed to fault, and the second is * for an instruction that is allowed to fault, and the second is
* the address to the fixup routine. * the address to the fixup routine. Even on a 64bit kernel we could
* use a 32bit (unsigned int) address here.
*/ */
struct exception_table_entry { struct exception_table_entry {
unsigned long insn; /* address of insn that is allowed to fault. */ unsigned long insn; /* address of insn that is allowed to fault. */
long fixup; /* fixup routine */ unsigned long fixup; /* fixup routine */
}; };
#define ASM_EXCEPTIONTABLE_ENTRY( fault_addr, except_addr )\ #define ASM_EXCEPTIONTABLE_ENTRY( fault_addr, except_addr )\
......
...@@ -649,10 +649,8 @@ cas_action: ...@@ -649,10 +649,8 @@ cas_action:
/* Two exception table entries, one for the load, /* Two exception table entries, one for the load,
the other for the store. Either return -EFAULT. the other for the store. Either return -EFAULT.
Each of the entries must be relocated. */ Each of the entries must be relocated. */
.section __ex_table,"aw" ASM_EXCEPTIONTABLE_ENTRY(1b-linux_gateway_page, 3b-linux_gateway_page)
ASM_ULONG_INSN (1b - linux_gateway_page), (3b - linux_gateway_page) ASM_EXCEPTIONTABLE_ENTRY(2b-linux_gateway_page, 3b-linux_gateway_page)
ASM_ULONG_INSN (2b - linux_gateway_page), (3b - linux_gateway_page)
.previous
/* Make sure nothing else is placed on this page */ /* Make sure nothing else is placed on this page */
......
...@@ -88,9 +88,7 @@ ENDPROC(lclear_user) ...@@ -88,9 +88,7 @@ ENDPROC(lclear_user)
ldo 1(%r25),%r25 ldo 1(%r25),%r25
.previous .previous
.section __ex_table,"aw" ASM_EXCEPTIONTABLE_ENTRY(1b,2b)
ASM_ULONG_INSN 1b,2b
.previous
.procend .procend
...@@ -129,10 +127,8 @@ ENDPROC(lstrnlen_user) ...@@ -129,10 +127,8 @@ ENDPROC(lstrnlen_user)
copy %r24,%r26 /* reset r26 so 0 is returned on fault */ copy %r24,%r26 /* reset r26 so 0 is returned on fault */
.previous .previous
.section __ex_table,"aw" ASM_EXCEPTIONTABLE_ENTRY(1b,3b)
ASM_ULONG_INSN 1b,3b ASM_EXCEPTIONTABLE_ENTRY(2b,3b)
ASM_ULONG_INSN 2b,3b
.previous
.procend .procend
......
...@@ -142,6 +142,12 @@ int fixup_exception(struct pt_regs *regs) ...@@ -142,6 +142,12 @@ int fixup_exception(struct pt_regs *regs)
{ {
const struct exception_table_entry *fix; const struct exception_table_entry *fix;
/* If we only stored 32bit addresses in the exception table we can drop
* out if we faulted on a 64bit address. */
if ((sizeof(regs->iaoq[0]) > sizeof(fix->insn))
&& (regs->iaoq[0] >> 32))
return 0;
fix = search_exception_tables(regs->iaoq[0]); fix = search_exception_tables(regs->iaoq[0]);
if (fix) { if (fix) {
struct exception_data *d; struct exception_data *d;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册