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
77 */77 */
78struct exception_data {78struct exception_data {
79 unsigned long fault_ip;79 unsigned long fault_ip;
80 unsigned long fault_gp;
80 unsigned long fault_space;81 unsigned long fault_space;
81 unsigned long fault_addr;82 unsigned long fault_addr;
82};83};
arch/parisc/kernel/asm-offsets.c+1−0
@@ -299,6 +299,7 @@ int main(void) · 298 unmodified lines
299#endif299#endif
300 BLANK();300 BLANK();
301 DEFINE(EXCDATA_IP, offsetof(struct exception_data, fault_ip));301 DEFINE(EXCDATA_IP, offsetof(struct exception_data, fault_ip));
302 DEFINE(EXCDATA_GP, offsetof(struct exception_data, fault_gp));
302 DEFINE(EXCDATA_SPACE, offsetof(struct exception_data, fault_space));303 DEFINE(EXCDATA_SPACE, offsetof(struct exception_data, fault_space));
303 DEFINE(EXCDATA_ADDR, offsetof(struct exception_data, fault_addr));304 DEFINE(EXCDATA_ADDR, offsetof(struct exception_data, fault_addr));
304 BLANK();305 BLANK();
arch/parisc/lib/fixup.S+6−0
@@ -26,6 +26,7 @@ · 25 unmodified lines
26 26
27#ifdef CONFIG_SMP27#ifdef CONFIG_SMP
28 .macro get_fault_ip t1 t228 .macro get_fault_ip t1 t2
29 loadgp
29 addil LT%__per_cpu_offset,%r2730 addil LT%__per_cpu_offset,%r27
30 LDREG RT%__per_cpu_offset(%r1),\t131 LDREG RT%__per_cpu_offset(%r1),\t1
31 /* t2 = smp_processor_id() */32 /* t2 = smp_processor_id() */
@@ -40,14 +41,19 @@ · 8 unmodified lines
40 LDREG RT%exception_data(%r1),\t141 LDREG RT%exception_data(%r1),\t1
41 /* t1 = this_cpu_ptr(&exception_data) */42 /* t1 = this_cpu_ptr(&exception_data) */
42 add,l \t1,\t2,\t143 add,l \t1,\t2,\t1
44 /* %r27 = t1->fault_gp - restore gp */
45 LDREG EXCDATA_GP(\t1), %r27
43 /* t1 = t1->fault_ip */46 /* t1 = t1->fault_ip */
44 LDREG EXCDATA_IP(\t1), \t147 LDREG EXCDATA_IP(\t1), \t1
45 .endm48 .endm
46#else49#else
47 .macro get_fault_ip t1 t250 .macro get_fault_ip t1 t2
51 loadgp
48 /* t1 = this_cpu_ptr(&exception_data) */52 /* t1 = this_cpu_ptr(&exception_data) */
49 addil LT%exception_data,%r2753 addil LT%exception_data,%r27
50 LDREG RT%exception_data(%r1),\t254 LDREG RT%exception_data(%r1),\t2
55 /* %r27 = t2->fault_gp - restore gp */
56 LDREG EXCDATA_GP(\t2), %r27
51 /* t1 = t2->fault_ip */57 /* t1 = t2->fault_ip */
52 LDREG EXCDATA_IP(\t2), \t158 LDREG EXCDATA_IP(\t2), \t1
53 .endm59 .endm
arch/parisc/mm/fault.c+1−0
@@ -145,6 +145,7 @@ int fixup_exception(struct pt_regs *regs) · 144 unmodified lines
145 struct exception_data *d;145 struct exception_data *d;
146 d = this_cpu_ptr(&exception_data);146 d = this_cpu_ptr(&exception_data);
147 d->fault_ip = regs->iaoq[0];147 d->fault_ip = regs->iaoq[0];
148 d->fault_gp = regs->gr[27];
148 d->fault_space = regs->isr;149 d->fault_space = regs->isr;
149 d->fault_addr = regs->ior;150 d->fault_addr = regs->ior;
150 151