powerpc: Put FP/VSX and VR state into structures

This creates new 'thread_fp_state' and 'thread_vr_state' structures
to store FP/VSX state (including FPSCR) and Altivec/VSX state
(including VSCR), and uses them in the thread_struct.  In the
thread_fp_state, the FPRs and VSRs are represented as u64 rather
than double, since we rarely perform floating-point computations
on the values, and this will enable the structures to be used
in KVM code as well.  Similarly FPSCR is now a u64 rather than
a structure of two 32-bit values.

This takes the offsets out of the macros such as SAVE_32FPRS,
REST_32FPRS, etc.  This enables the same macros to be used for normal
and transactional state, enabling us to delete the transactional
versions of the macros.   This also removes the unused do_load_up_fpu
and do_load_up_altivec, which were in fact buggy since they didn't
create large enough stack frames to account for the fact that
load_up_fpu and load_up_altivec are not designed to be called from C
and assume that their caller's stack frame is an interrupt frame.

Signed-off-by: Paul Mackerras <paulus@samba.org>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
This commit is contained in:
Paul Mackerras
2013-09-10 20:20:42 +10:00
committed by Benjamin Herrenschmidt
parent 8e0a1611cb
commit de79f7b9f6
17 changed files with 200 additions and 358 deletions

View File

@@ -8,29 +8,6 @@
#include <asm/ptrace.h>
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
/*
* Wrapper to call load_up_altivec from C.
* void do_load_up_altivec(struct pt_regs *regs);
*/
_GLOBAL(do_load_up_altivec)
mflr r0
std r0, 16(r1)
stdu r1, -112(r1)
subi r6, r3, STACK_FRAME_OVERHEAD
/* load_up_altivec expects r12=MSR, r13=PACA, and returns
* with r12 = new MSR.
*/
ld r12,_MSR(r6)
GET_PACA(r13)
bl load_up_altivec
std r12,_MSR(r6)
ld r0, 112+16(r1)
addi r1, r1, 112
mtlr r0
blr
/* void do_load_up_transact_altivec(struct thread_struct *thread)
*
* This is similar to load_up_altivec but for the transactional version of the
@@ -46,10 +23,11 @@ _GLOBAL(do_load_up_transact_altivec)
li r4,1
stw r4,THREAD_USED_VR(r3)
li r10,THREAD_TRANSACT_VSCR
li r10,THREAD_TRANSACT_VRSTATE+VRSTATE_VSCR
lvx vr0,r10,r3
mtvscr vr0
REST_32VRS_TRANSACT(0,r4,r3)
addi r10,r3,THREAD_TRANSACT_VRSTATE
REST_32VRS(0,r4,r10)
/* Disable VEC again. */
MTMSRD(r6)
@@ -59,7 +37,6 @@ _GLOBAL(do_load_up_transact_altivec)
#endif
/*
* load_up_altivec(unused, unused, tsk)
* Disable VMX for the task which had it previously,
* and save its vector registers in its thread_struct.
* Enables the VMX for use in the kernel on return.
@@ -90,10 +67,11 @@ _GLOBAL(load_up_altivec)
/* Save VMX state to last_task_used_altivec's THREAD struct */
toreal(r4)
addi r4,r4,THREAD
SAVE_32VRS(0,r5,r4)
addi r7,r4,THREAD_VRSTATE
SAVE_32VRS(0,r5,r7)
mfvscr vr0
li r10,THREAD_VSCR
stvx vr0,r10,r4
li r10,VRSTATE_VSCR
stvx vr0,r10,r7
/* Disable VMX for last_task_used_altivec */
PPC_LL r5,PT_REGS(r4)
toreal(r5)
@@ -125,12 +103,13 @@ _GLOBAL(load_up_altivec)
oris r12,r12,MSR_VEC@h
std r12,_MSR(r1)
#endif
addi r7,r5,THREAD_VRSTATE
li r4,1
li r10,THREAD_VSCR
li r10,VRSTATE_VSCR
stw r4,THREAD_USED_VR(r5)
lvx vr0,r10,r5
lvx vr0,r10,r7
mtvscr vr0
REST_32VRS(0,r4,r5)
REST_32VRS(0,r4,r7)
#ifndef CONFIG_SMP
/* Update last_task_used_altivec to 'current' */
subi r4,r5,THREAD /* Back to 'current' */
@@ -165,12 +144,13 @@ _GLOBAL(giveup_altivec)
PPC_LCMPI 0,r3,0
beqlr /* if no previous owner, done */
addi r3,r3,THREAD /* want THREAD of task */
addi r7,r3,THREAD_VRSTATE
PPC_LL r5,PT_REGS(r3)
PPC_LCMPI 0,r5,0
SAVE_32VRS(0,r4,r3)
SAVE_32VRS(0,r4,r7)
mfvscr vr0
li r4,THREAD_VSCR
stvx vr0,r4,r3
li r4,VRSTATE_VSCR
stvx vr0,r4,r7
beq 1f
PPC_LL r4,_MSR-STACK_FRAME_OVERHEAD(r5)
#ifdef CONFIG_VSX