1 |
From 7ae1f5508d9a33fd58ed3059bd2d569961e3b8bd Mon Sep 17 00:00:00 2001 |
2 |
From: Helge Deller <deller@gmx.de> |
3 |
Date: Sat, 20 Aug 2022 17:59:17 +0200 |
4 |
Subject: parisc: Fix exception handler for fldw and fstw instructions |
5 |
|
6 |
From: Helge Deller <deller@gmx.de> |
7 |
|
8 |
commit 7ae1f5508d9a33fd58ed3059bd2d569961e3b8bd upstream. |
9 |
|
10 |
The exception handler is broken for unaligned memory acceses with fldw |
11 |
and fstw instructions, because it trashes or uses randomly some other |
12 |
floating point register than the one specified in the instruction word |
13 |
on loads and stores. |
14 |
|
15 |
The instruction "fldw 0(addr),%fr22L" (and the other fldw/fstw |
16 |
instructions) encode the target register (%fr22) in the rightmost 5 bits |
17 |
of the instruction word. The 7th rightmost bit of the instruction word |
18 |
defines if the left or right half of %fr22 should be used. |
19 |
|
20 |
While processing unaligned address accesses, the FR3() define is used to |
21 |
extract the offset into the local floating-point register set. But the |
22 |
calculation in FR3() was buggy, so that for example instead of %fr22, |
23 |
register %fr12 [((22 * 2) & 0x1f) = 12] was used. |
24 |
|
25 |
This bug has been since forever in the parisc kernel and I wonder why it |
26 |
wasn't detected earlier. Interestingly I noticed this bug just because |
27 |
the libime debian package failed to build on *native* hardware, while it |
28 |
successfully built in qemu. |
29 |
|
30 |
This patch corrects the bitshift and masking calculation in FR3(). |
31 |
|
32 |
Signed-off-by: Helge Deller <deller@gmx.de> |
33 |
Cc: <stable@vger.kernel.org> |
34 |
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
35 |
--- |
36 |
arch/parisc/kernel/unaligned.c | 2 +- |
37 |
1 file changed, 1 insertion(+), 1 deletion(-) |
38 |
|
39 |
--- a/arch/parisc/kernel/unaligned.c |
40 |
+++ b/arch/parisc/kernel/unaligned.c |
41 |
@@ -93,7 +93,7 @@ |
42 |
#define R1(i) (((i)>>21)&0x1f) |
43 |
#define R2(i) (((i)>>16)&0x1f) |
44 |
#define R3(i) ((i)&0x1f) |
45 |
-#define FR3(i) ((((i)<<1)&0x1f)|(((i)>>6)&1)) |
46 |
+#define FR3(i) ((((i)&0x1f)<<1)|(((i)>>6)&1)) |
47 |
#define IM(i,n) (((i)>>1&((1<<(n-1))-1))|((i)&1?((0-1L)<<(n-1)):0)) |
48 |
#define IM5_2(i) IM((i)>>16,5) |
49 |
#define IM5_3(i) IM((i),5) |