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

Commit b783ef3e authored by Helge Deller's avatar Helge Deller Committed by Greg Kroah-Hartman
Browse files

parisc/unaligned: Fix fldd and fstd unaligned handlers on 32-bit kernel



commit dd2288f4a020d693360e3e8d72f8b9d9c25f5ef6 upstream.

Usually the kernel provides fixup routines to emulate the fldd and fstd
floating-point instructions if they load or store 8-byte from/to a not
natuarally aligned memory location.

On a 32-bit kernel I noticed that those unaligned handlers didn't worked and
instead the application got a SEGV.
While checking the code I found two problems:

First, the OPCODE_FLDD_L and OPCODE_FSTD_L cases were ifdef'ed out by the
CONFIG_PA20 option, and as such those weren't built on a pure 32-bit kernel.
This is now fixed by moving the CONFIG_PA20 #ifdef to prevent the compilation
of OPCODE_LDD_L and OPCODE_FSTD_L only, and handling the fldd and fstd
instructions.

The second problem are two bugs in the 32-bit inline assembly code, where the
wrong registers where used. The calculation of the natural alignment used %2
(vall) instead of %3 (ior), and the first word was stored back to address %1
(valh) instead of %3 (ior).

Signed-off-by: default avatarHelge Deller <deller@gmx.de>
Cc: stable@vger.kernel.org
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 0b608b33
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -397,7 +397,7 @@ static int emulate_std(struct pt_regs *regs, int frreg, int flop)
	__asm__ __volatile__ (
"	mtsp	%4, %%sr1\n"
"	zdep	%2, 29, 2, %%r19\n"
"	dep	%%r0, 31, 2, %2\n"
"	dep	%%r0, 31, 2, %3\n"
"	mtsar	%%r19\n"
"	zvdepi	-2, 32, %%r19\n"
"1:	ldw	0(%%sr1,%3),%%r20\n"
@@ -409,7 +409,7 @@ static int emulate_std(struct pt_regs *regs, int frreg, int flop)
"	andcm	%%r21, %%r19, %%r21\n"
"	or	%1, %%r20, %1\n"
"	or	%2, %%r21, %2\n"
"3:	stw	%1,0(%%sr1,%1)\n"
"3:	stw	%1,0(%%sr1,%3)\n"
"4:	stw	%%r1,4(%%sr1,%3)\n"
"5:	stw	%2,8(%%sr1,%3)\n"
"	copy	%%r0, %0\n"
@@ -596,7 +596,6 @@ void handle_unaligned(struct pt_regs *regs)
		ret = ERR_NOTHANDLED;	/* "undefined", but lets kill them. */
		break;
	}
#ifdef CONFIG_PA20
	switch (regs->iir & OPCODE2_MASK)
	{
	case OPCODE_FLDD_L:
@@ -607,14 +606,15 @@ void handle_unaligned(struct pt_regs *regs)
		flop=1;
		ret = emulate_std(regs, R2(regs->iir),1);
		break;
#ifdef CONFIG_PA20
	case OPCODE_LDD_L:
		ret = emulate_ldd(regs, R2(regs->iir),0);
		break;
	case OPCODE_STD_L:
		ret = emulate_std(regs, R2(regs->iir),0);
		break;
	}
#endif
	}
	switch (regs->iir & OPCODE3_MASK)
	{
	case OPCODE_FLDW_L: