Commit 61dbbaeb86c2181c79efae2d186193e0f8008af1

Authored by Helge Deller
1 parent 5e01dc7b26

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;