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

Commit 9bd5af84 authored by Helge Deller's avatar Helge Deller Committed by Sasha Levin
Browse files

parisc: Unbreak handling exceptions from kernel modules



[ Upstream commit 2ef4dfd9d9f288943e249b78365a69e3ea3ec072 ]

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
Signed-off-by: default avatarSasha Levin <sasha.levin@oracle.com>
parent e69ea046
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -76,6 +76,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
@@ -292,6 +292,7 @@ int main(void)
	DEFINE(ASM_PT_INITIAL, PT_INITIAL);
	DEFINE(ASM_PT_INITIAL, PT_INITIAL);
	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
@@ -151,6 +151,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;