History

parisc: Unbreak handling exceptions from kernel modules

Handling exceptions from modules never worked on parisc. It was just masked by the fact that exceptions from modules don't happen during normal use. When a module triggers an exception in get_user() we need to load the main kernel dp value before accessing the exception_data structure, and afterwards restore the original dp value of the module on exit.

Helge Deller committed 10 years ago

Commit 2ef4dfd1 parent ef72f314 files · +9 −0Browse files

Unified · Split

4 files
  1. arch/parisc/include/asm/uaccess.h +1 −0
  2. arch/parisc/kernel/asm-offsets.c +1 −0
  3. arch/parisc/lib/fixup.S +6 −0
  4. arch/parisc/mm/fault.c +1 −0
arch/parisc/include/asm/uaccess.h+1−0
@@ -77,6 +77,7 @@ struct exception_table_entry { · 76 unmodified lines
7777 */
7878 struct exception_data {
7979 unsigned long fault_ip;
80+ unsigned long fault_gp;
8081 unsigned long fault_space;
8182 unsigned long fault_addr;
8283 };
arch/parisc/kernel/asm-offsets.c+1−0
@@ -299,6 +299,7 @@ int main(void) · 298 unmodified lines
299299 #endif
300300 BLANK();
301301 DEFINE(EXCDATA_IP, offsetof(struct exception_data, fault_ip));
302+ DEFINE(EXCDATA_GP, offsetof(struct exception_data, fault_gp));
302303 DEFINE(EXCDATA_SPACE, offsetof(struct exception_data, fault_space));
303304 DEFINE(EXCDATA_ADDR, offsetof(struct exception_data, fault_addr));
304305 BLANK();
arch/parisc/lib/fixup.S+6−0
@@ -26,6 +26,7 @@ · 25 unmodified lines
2626
2727 #ifdef CONFIG_SMP
2828 .macro get_fault_ip t1 t2
29+ loadgp
2930 addil LT%__per_cpu_offset,%r27
3031 LDREG RT%__per_cpu_offset(%r1),\t1
3132 /* t2 = smp_processor_id() */
@@ -40,14 +41,19 @@ · 8 unmodified lines
4041 LDREG RT%exception_data(%r1),\t1
4142 /* t1 = this_cpu_ptr(&exception_data) */
4243 add,l \t1,\t2,\t1
44+ /* %r27 = t1->fault_gp - restore gp */
45+ LDREG EXCDATA_GP(\t1), %r27
4346 /* t1 = t1->fault_ip */
4447 LDREG EXCDATA_IP(\t1), \t1
4548 .endm
4649 #else
4750 .macro get_fault_ip t1 t2
51+ loadgp
4852 /* t1 = this_cpu_ptr(&exception_data) */
4953 addil LT%exception_data,%r27
5054 LDREG RT%exception_data(%r1),\t2
55+ /* %r27 = t2->fault_gp - restore gp */
56+ LDREG EXCDATA_GP(\t2), %r27
5157 /* t1 = t2->fault_ip */
5258 LDREG EXCDATA_IP(\t2), \t1
5359 .endm
arch/parisc/mm/fault.c+1−0
@@ -145,6 +145,7 @@ int fixup_exception(struct pt_regs *regs) · 144 unmodified lines
145145 struct exception_data *d;
146146 d = this_cpu_ptr(&exception_data);
147147 d->fault_ip = regs->iaoq[0];
148+ d->fault_gp = regs->gr[27];
148149 d->fault_space = regs->isr;
149150 d->fault_addr = regs->ior;
150151