diff options
author | Paul Mackerras <paulus@samba.org> | 2013-08-05 06:13:16 +0200 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2013-08-14 06:57:18 +0200 |
commit | 408a7e08b2112faf687dd629212e42998a7dbe48 (patch) | |
tree | 9c616a8507bd5451bd845c18a5442e2e3adf8814 /arch/powerpc/kernel/tm.S | |
parent | powerpc: Implement __get_user_pages_fast() (diff) | |
download | linux-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.S | 4 |
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 |