summaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/tm.S
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2013-08-05 06:13:16 +0200
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2013-08-14 06:57:18 +0200
commit408a7e08b2112faf687dd629212e42998a7dbe48 (patch)
tree9c616a8507bd5451bd845c18a5442e2e3adf8814 /arch/powerpc/kernel/tm.S
parentpowerpc: Implement __get_user_pages_fast() (diff)
downloadlinux-408a7e08b2112faf687dd629212e42998a7dbe48.tar.xz
linux-408a7e08b2112faf687dd629212e42998a7dbe48.zip
powerpc: Fix VRSAVE handling
Since 2002, the kernel has not saved VRSAVE on exception entry and restored it on exit; rather, VRSAVE gets context-switched in _switch. This means that when executing in process context in the kernel, the userspace VRSAVE value is live in the VRSAVE register. However, the signal code assumes that current->thread.vrsave holds the current VRSAVE value, which is incorrect. Therefore, this commit changes it to use the actual VRSAVE register instead. (It still uses current->thread.vrsave as a temporary location to store it in, as __get_user and __put_user can only transfer to/from a variable, not an SPR.) This also modifies the transactional memory code to save and restore VRSAVE regardless of whether VMX is enabled in the MSR. This is because accesses to VRSAVE are not controlled by the MSR.VEC bit, but can happen at any time. Signed-off-by: Paul Mackerras <paulus@samba.org> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/kernel/tm.S')
-rw-r--r--arch/powerpc/kernel/tm.S4
1 files changed, 2 insertions, 2 deletions
diff --git a/arch/powerpc/kernel/tm.S b/arch/powerpc/kernel/tm.S
index 51be8fb24803..e2145b222f83 100644
--- a/arch/powerpc/kernel/tm.S
+++ b/arch/powerpc/kernel/tm.S
@@ -155,10 +155,10 @@ _GLOBAL(tm_reclaim)
mfvscr vr0
li r6, THREAD_TRANSACT_VSCR
stvx vr0, r3, r6
+dont_backup_vec:
mfspr r0, SPRN_VRSAVE
std r0, THREAD_TRANSACT_VRSAVE(r3)
-dont_backup_vec:
andi. r0, r4, MSR_FP
beq dont_backup_fp
@@ -331,11 +331,11 @@ _GLOBAL(tm_recheckpoint)
lvx vr0, r3, r5
mtvscr vr0
REST_32VRS(0, r5, r3) /* r5 scratch, r3 THREAD ptr */
+dont_restore_vec:
ld r5, THREAD_VRSAVE(r3)
mtspr SPRN_VRSAVE, r5
#endif
-dont_restore_vec:
andi. r0, r4, MSR_FP
beq dont_restore_fp