Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2ef4dfd9 authored by Helge Deller's avatar Helge Deller
Browse files

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.

Noticed-by: default avatarMikulas Patocka <mpatocka@redhat.com>
Signed-off-by: default avatarHelge Deller <deller@gmx.de>
Cc: stable@vger.kernel.org
parent ef72f311
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -77,6 +77,7 @@ struct exception_table_entry {
 */
 */
struct exception_data {
struct exception_data {
	unsigned long fault_ip;
	unsigned long fault_ip;
	unsigned long fault_gp;
	unsigned long fault_space;
	unsigned long fault_space;
	unsigned long fault_addr;
	unsigned long fault_addr;
};
};
+1 −0
Original line number Original line Diff line number Diff line
@@ -299,6 +299,7 @@ int main(void)
#endif
#endif
	BLANK();
	BLANK();
	DEFINE(EXCDATA_IP, offsetof(struct exception_data, fault_ip));
	DEFINE(EXCDATA_IP, offsetof(struct exception_data, fault_ip));
	DEFINE(EXCDATA_GP, offsetof(struct exception_data, fault_gp));
	DEFINE(EXCDATA_SPACE, offsetof(struct exception_data, fault_space));
	DEFINE(EXCDATA_SPACE, offsetof(struct exception_data, fault_space));
	DEFINE(EXCDATA_ADDR, offsetof(struct exception_data, fault_addr));
	DEFINE(EXCDATA_ADDR, offsetof(struct exception_data, fault_addr));
	BLANK();
	BLANK();
+6 −0
Original line number Original line Diff line number Diff line
@@ -26,6 +26,7 @@


#ifdef CONFIG_SMP
#ifdef CONFIG_SMP
	.macro  get_fault_ip t1 t2
	.macro  get_fault_ip t1 t2
	loadgp
	addil LT%__per_cpu_offset,%r27
	addil LT%__per_cpu_offset,%r27
	LDREG RT%__per_cpu_offset(%r1),\t1
	LDREG RT%__per_cpu_offset(%r1),\t1
	/* t2 = smp_processor_id() */
	/* t2 = smp_processor_id() */
@@ -40,14 +41,19 @@
	LDREG RT%exception_data(%r1),\t1
	LDREG RT%exception_data(%r1),\t1
	/* t1 = this_cpu_ptr(&exception_data) */
	/* t1 = this_cpu_ptr(&exception_data) */
	add,l \t1,\t2,\t1
	add,l \t1,\t2,\t1
	/* %r27 = t1->fault_gp - restore gp */
	LDREG EXCDATA_GP(\t1), %r27
	/* t1 = t1->fault_ip */
	/* t1 = t1->fault_ip */
	LDREG EXCDATA_IP(\t1), \t1
	LDREG EXCDATA_IP(\t1), \t1
	.endm
	.endm
#else
#else
	.macro  get_fault_ip t1 t2
	.macro  get_fault_ip t1 t2
	loadgp
	/* t1 = this_cpu_ptr(&exception_data) */
	/* t1 = this_cpu_ptr(&exception_data) */
	addil LT%exception_data,%r27
	addil LT%exception_data,%r27
	LDREG RT%exception_data(%r1),\t2
	LDREG RT%exception_data(%r1),\t2
	/* %r27 = t2->fault_gp - restore gp */
	LDREG EXCDATA_GP(\t2), %r27
	/* t1 = t2->fault_ip */
	/* t1 = t2->fault_ip */
	LDREG EXCDATA_IP(\t2), \t1
	LDREG EXCDATA_IP(\t2), \t1
	.endm
	.endm
+1 −0
Original line number Original line Diff line number Diff line
@@ -145,6 +145,7 @@ int fixup_exception(struct pt_regs *regs)
		struct exception_data *d;
		struct exception_data *d;
		d = this_cpu_ptr(&exception_data);
		d = this_cpu_ptr(&exception_data);
		d->fault_ip = regs->iaoq[0];
		d->fault_ip = regs->iaoq[0];
		d->fault_gp = regs->gr[27];
		d->fault_space = regs->isr;
		d->fault_space = regs->isr;
		d->fault_addr = regs->ior;
		d->fault_addr = regs->ior;