]>
Commit | Line | Data |
---|---|---|
2cb7cef9 BS |
1 | From: Michael Neuling <mikey@neuling.org> |
2 | Subject: change giveup_fpu/altivec to disable VSX for current | |
3 | Patch-mainline: 2.6.30 | |
4 | References: bnc#492324 | |
5 | ||
6 | [PATCH] powerpc: change giveup_fpu/altivec to disable VSX for current | |
7 | ||
8 | When we call giveup_fpu, we need to need to turn off VSX in current. | |
9 | If we don't, on return to current it may execute a VSX instruction | |
10 | (before the next FP), and not have it's register state refreshed | |
11 | correctly from the thread_struct. Ditto for altivec. | |
12 | ||
13 | This caused a bug where an unaligned lfs or stfs (which calls | |
14 | giveup_fpu so it can use the FPRs) to return to userspace with FP off | |
15 | but VSX on. Then if a VSX instruction is executed, before another FP | |
16 | instruction, it will proceed without another exception and hence have | |
17 | the incorrect register state for VSX registers 0-31. | |
18 | ||
19 | lfs unaligned <- alignment exception turns FP off but leaves VSX on | |
20 | ||
21 | VSX instruction <- no exception since VSX on, hence we get the | |
22 | wrong VSX register values for VSX registers 0-31 | |
23 | (overlapping the FPRs) | |
24 | ||
25 | Signed-off-by: Michael Neuling <mikey@neuling.org> | |
26 | Acked-by: duwe@suse.de | |
27 | ||
28 | --- | |
29 | arch/powerpc/kernel/fpu.S | 5 +++++ | |
30 | arch/powerpc/kernel/misc_64.S | 8 ++++++++ | |
31 | 2 files changed, 13 insertions(+) | |
32 | ||
33 | Index: clone3/arch/powerpc/kernel/fpu.S | |
34 | =================================================================== | |
35 | --- clone3.orig/arch/powerpc/kernel/fpu.S | |
36 | +++ clone3/arch/powerpc/kernel/fpu.S | |
37 | @@ -145,6 +145,11 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX) | |
38 | beq 1f | |
39 | PPC_LL r4,_MSR-STACK_FRAME_OVERHEAD(r5) | |
40 | li r3,MSR_FP|MSR_FE0|MSR_FE1 | |
41 | +#ifdef CONFIG_VSX | |
42 | +BEGIN_FTR_SECTION | |
43 | + oris r3,r3,MSR_VSX@h | |
44 | +END_FTR_SECTION_IFSET(CPU_FTR_VSX) | |
45 | +#endif | |
46 | andc r4,r4,r3 /* disable FP for previous task */ | |
47 | PPC_STL r4,_MSR-STACK_FRAME_OVERHEAD(r5) | |
48 | 1: | |
49 | Index: clone3/arch/powerpc/kernel/misc_64.S | |
50 | =================================================================== | |
51 | --- clone3.orig/arch/powerpc/kernel/misc_64.S | |
52 | +++ clone3/arch/powerpc/kernel/misc_64.S | |
53 | @@ -493,7 +493,15 @@ _GLOBAL(giveup_altivec) | |
54 | stvx vr0,r4,r3 | |
55 | beq 1f | |
56 | ld r4,_MSR-STACK_FRAME_OVERHEAD(r5) | |
57 | +#ifdef CONFIG_VSX | |
58 | +BEGIN_FTR_SECTION | |
59 | + lis r3,(MSR_VEC|MSR_VSX)@h | |
60 | +FTR_SECTION_ELSE | |
61 | + lis r3,MSR_VEC@h | |
62 | +ALT_FTR_SECTION_END_IFSET(CPU_FTR_VSX) | |
63 | +#else | |
64 | lis r3,MSR_VEC@h | |
65 | +#endif | |
66 | andc r4,r4,r3 /* disable FP for previous task */ | |
67 | std r4,_MSR-STACK_FRAME_OVERHEAD(r5) | |
68 | 1: |