Commit 61dbbaeb86c2181c79efae2d186193e0f8008af1
1 parent
5e01dc7b26
Exists in
master
and in
16 other branches
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: Helge Deller <deller@gmx.de>
Showing 5 changed files with 27 additions and 14 deletions Side-by-side Diff
arch/parisc/include/asm/assembly.h
... | ... | @@ -515,6 +515,18 @@ |
515 | 515 | nop /* 7 */ |
516 | 516 | .endm |
517 | 517 | |
518 | + /* | |
519 | + * ASM_EXCEPTIONTABLE_ENTRY | |
520 | + * | |
521 | + * Creates an exception table entry. | |
522 | + * Do not convert to a assembler macro. This won't work. | |
523 | + */ | |
524 | +#define ASM_EXCEPTIONTABLE_ENTRY(fault_addr, except_addr) \ | |
525 | + .section __ex_table,"aw" ! \ | |
526 | + ASM_ULONG_INSN fault_addr, except_addr ! \ | |
527 | + .previous | |
528 | + | |
529 | + | |
518 | 530 | #endif /* __ASSEMBLY__ */ |
519 | 531 | #endif |
arch/parisc/include/asm/uaccess.h
... | ... | @@ -59,12 +59,13 @@ |
59 | 59 | /* |
60 | 60 | * The exception table contains two values: the first is an address |
61 | 61 | * for an instruction that is allowed to fault, and the second is |
62 | - * the address to the fixup routine. | |
62 | + * the address to the fixup routine. Even on a 64bit kernel we could | |
63 | + * use a 32bit (unsigned int) address here. | |
63 | 64 | */ |
64 | 65 | |
65 | 66 | struct exception_table_entry { |
66 | - unsigned long insn; /* address of insn that is allowed to fault. */ | |
67 | - long fixup; /* fixup routine */ | |
67 | + unsigned long insn; /* address of insn that is allowed to fault. */ | |
68 | + unsigned long fixup; /* fixup routine */ | |
68 | 69 | }; |
69 | 70 | |
70 | 71 | #define ASM_EXCEPTIONTABLE_ENTRY( fault_addr, except_addr )\ |
arch/parisc/kernel/syscall.S
... | ... | @@ -649,10 +649,8 @@ |
649 | 649 | /* Two exception table entries, one for the load, |
650 | 650 | the other for the store. Either return -EFAULT. |
651 | 651 | Each of the entries must be relocated. */ |
652 | - .section __ex_table,"aw" | |
653 | - ASM_ULONG_INSN (1b - linux_gateway_page), (3b - linux_gateway_page) | |
654 | - ASM_ULONG_INSN (2b - linux_gateway_page), (3b - linux_gateway_page) | |
655 | - .previous | |
652 | + ASM_EXCEPTIONTABLE_ENTRY(1b-linux_gateway_page, 3b-linux_gateway_page) | |
653 | + ASM_EXCEPTIONTABLE_ENTRY(2b-linux_gateway_page, 3b-linux_gateway_page) | |
656 | 654 | |
657 | 655 | |
658 | 656 | /* Make sure nothing else is placed on this page */ |
arch/parisc/lib/lusercopy.S
... | ... | @@ -88,9 +88,7 @@ |
88 | 88 | ldo 1(%r25),%r25 |
89 | 89 | .previous |
90 | 90 | |
91 | - .section __ex_table,"aw" | |
92 | - ASM_ULONG_INSN 1b,2b | |
93 | - .previous | |
91 | + ASM_EXCEPTIONTABLE_ENTRY(1b,2b) | |
94 | 92 | |
95 | 93 | .procend |
96 | 94 | |
... | ... | @@ -129,10 +127,8 @@ |
129 | 127 | copy %r24,%r26 /* reset r26 so 0 is returned on fault */ |
130 | 128 | .previous |
131 | 129 | |
132 | - .section __ex_table,"aw" | |
133 | - ASM_ULONG_INSN 1b,3b | |
134 | - ASM_ULONG_INSN 2b,3b | |
135 | - .previous | |
130 | + ASM_EXCEPTIONTABLE_ENTRY(1b,3b) | |
131 | + ASM_EXCEPTIONTABLE_ENTRY(2b,3b) | |
136 | 132 | |
137 | 133 | .procend |
138 | 134 |
arch/parisc/mm/fault.c
... | ... | @@ -142,6 +142,12 @@ |
142 | 142 | { |
143 | 143 | const struct exception_table_entry *fix; |
144 | 144 | |
145 | + /* If we only stored 32bit addresses in the exception table we can drop | |
146 | + * out if we faulted on a 64bit address. */ | |
147 | + if ((sizeof(regs->iaoq[0]) > sizeof(fix->insn)) | |
148 | + && (regs->iaoq[0] >> 32)) | |
149 | + return 0; | |
150 | + | |
145 | 151 | fix = search_exception_tables(regs->iaoq[0]); |
146 | 152 | if (fix) { |
147 | 153 | struct exception_data *d; |