aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2013-10-11 03:23:53 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2013-10-11 03:23:53 -0400
commit3ad26e5c4459d3793ad65bc8929037c70515df83 (patch)
tree434327df7942878383e372988eb5f3bccb25de12 /arch/powerpc/kernel
parent5293bf97a27e1be8ac6096aa198ff6a9e3e6837c (diff)
parent18461960cbf50bf345ef0667d45d5f64de8fb893 (diff)
Merge branch 'for-kvm' into next
Topic branch for commits that the KVM tree might want to pull in separately. Hand merged a few files due to conflicts with the LE stuff Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r--arch/powerpc/kernel/align.c8
-rw-r--r--arch/powerpc/kernel/asm-offsets.c27
-rw-r--r--arch/powerpc/kernel/fpu.S84
-rw-r--r--arch/powerpc/kernel/ppc_ksyms.c4
-rw-r--r--arch/powerpc/kernel/process.c15
-rw-r--r--arch/powerpc/kernel/ptrace.c49
-rw-r--r--arch/powerpc/kernel/ptrace32.c11
-rw-r--r--arch/powerpc/kernel/signal_32.c72
-rw-r--r--arch/powerpc/kernel/signal_64.c29
-rw-r--r--arch/powerpc/kernel/tm.S41
-rw-r--r--arch/powerpc/kernel/traps.c10
-rw-r--r--arch/powerpc/kernel/vecemu.c6
-rw-r--r--arch/powerpc/kernel/vector.S77
13 files changed, 215 insertions, 218 deletions
diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c
index 59f70adcbcd9..6e3f9772aaba 100644
--- a/arch/powerpc/kernel/align.c
+++ b/arch/powerpc/kernel/align.c
@@ -652,9 +652,9 @@ static int emulate_vsx(unsigned char __user *addr, unsigned int reg,
652 flush_vsx_to_thread(current); 652 flush_vsx_to_thread(current);
653 653
654 if (reg < 32) 654 if (reg < 32)
655 ptr = (char *) &current->thread.fpr[reg][0]; 655 ptr = (char *) &current->thread.fp_state.fpr[reg][0];
656 else 656 else
657 ptr = (char *) &current->thread.vr[reg - 32]; 657 ptr = (char *) &current->thread.vr_state.vr[reg - 32];
658 658
659 lptr = (unsigned long *) ptr; 659 lptr = (unsigned long *) ptr;
660 660
@@ -944,7 +944,7 @@ int fix_alignment(struct pt_regs *regs)
944 return -EFAULT; 944 return -EFAULT;
945 945
946 } else if (flags & F) { 946 } else if (flags & F) {
947 data.dd = current->thread.TS_FPR(reg); 947 data.ll = current->thread.TS_FPR(reg);
948 if (flags & S) { 948 if (flags & S) {
949 /* Single-precision FP store requires conversion... */ 949 /* Single-precision FP store requires conversion... */
950#ifdef CONFIG_PPC_FPU 950#ifdef CONFIG_PPC_FPU
@@ -1021,7 +1021,7 @@ int fix_alignment(struct pt_regs *regs)
1021 if (unlikely(ret)) 1021 if (unlikely(ret))
1022 return -EFAULT; 1022 return -EFAULT;
1023 } else if (flags & F) 1023 } else if (flags & F)
1024 current->thread.TS_FPR(reg) = data.dd; 1024 current->thread.TS_FPR(reg) = data.ll;
1025 else 1025 else
1026 regs->gpr[reg] = data.ll; 1026 regs->gpr[reg] = data.ll;
1027 1027
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 502c7a4e73f7..6278edddc3f8 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -90,16 +90,17 @@ int main(void)
90 DEFINE(THREAD_NORMSAVES, offsetof(struct thread_struct, normsave[0])); 90 DEFINE(THREAD_NORMSAVES, offsetof(struct thread_struct, normsave[0]));
91#endif 91#endif
92 DEFINE(THREAD_FPEXC_MODE, offsetof(struct thread_struct, fpexc_mode)); 92 DEFINE(THREAD_FPEXC_MODE, offsetof(struct thread_struct, fpexc_mode));
93 DEFINE(THREAD_FPR0, offsetof(struct thread_struct, fpr[0])); 93 DEFINE(THREAD_FPSTATE, offsetof(struct thread_struct, fp_state));
94 DEFINE(THREAD_FPSCR, offsetof(struct thread_struct, fpscr)); 94 DEFINE(THREAD_FPSAVEAREA, offsetof(struct thread_struct, fp_save_area));
95 DEFINE(FPSTATE_FPSCR, offsetof(struct thread_fp_state, fpscr));
95#ifdef CONFIG_ALTIVEC 96#ifdef CONFIG_ALTIVEC
96 DEFINE(THREAD_VR0, offsetof(struct thread_struct, vr[0])); 97 DEFINE(THREAD_VRSTATE, offsetof(struct thread_struct, vr_state));
98 DEFINE(THREAD_VRSAVEAREA, offsetof(struct thread_struct, vr_save_area));
97 DEFINE(THREAD_VRSAVE, offsetof(struct thread_struct, vrsave)); 99 DEFINE(THREAD_VRSAVE, offsetof(struct thread_struct, vrsave));
98 DEFINE(THREAD_VSCR, offsetof(struct thread_struct, vscr));
99 DEFINE(THREAD_USED_VR, offsetof(struct thread_struct, used_vr)); 100 DEFINE(THREAD_USED_VR, offsetof(struct thread_struct, used_vr));
101 DEFINE(VRSTATE_VSCR, offsetof(struct thread_vr_state, vscr));
100#endif /* CONFIG_ALTIVEC */ 102#endif /* CONFIG_ALTIVEC */
101#ifdef CONFIG_VSX 103#ifdef CONFIG_VSX
102 DEFINE(THREAD_VSR0, offsetof(struct thread_struct, fpr));
103 DEFINE(THREAD_USED_VSR, offsetof(struct thread_struct, used_vsr)); 104 DEFINE(THREAD_USED_VSR, offsetof(struct thread_struct, used_vsr));
104#endif /* CONFIG_VSX */ 105#endif /* CONFIG_VSX */
105#ifdef CONFIG_PPC64 106#ifdef CONFIG_PPC64
@@ -143,20 +144,12 @@ int main(void)
143 DEFINE(THREAD_TM_PPR, offsetof(struct thread_struct, tm_ppr)); 144 DEFINE(THREAD_TM_PPR, offsetof(struct thread_struct, tm_ppr));
144 DEFINE(THREAD_TM_DSCR, offsetof(struct thread_struct, tm_dscr)); 145 DEFINE(THREAD_TM_DSCR, offsetof(struct thread_struct, tm_dscr));
145 DEFINE(PT_CKPT_REGS, offsetof(struct thread_struct, ckpt_regs)); 146 DEFINE(PT_CKPT_REGS, offsetof(struct thread_struct, ckpt_regs));
146 DEFINE(THREAD_TRANSACT_VR0, offsetof(struct thread_struct, 147 DEFINE(THREAD_TRANSACT_VRSTATE, offsetof(struct thread_struct,
147 transact_vr[0])); 148 transact_vr));
148 DEFINE(THREAD_TRANSACT_VSCR, offsetof(struct thread_struct,
149 transact_vscr));
150 DEFINE(THREAD_TRANSACT_VRSAVE, offsetof(struct thread_struct, 149 DEFINE(THREAD_TRANSACT_VRSAVE, offsetof(struct thread_struct,
151 transact_vrsave)); 150 transact_vrsave));
152 DEFINE(THREAD_TRANSACT_FPR0, offsetof(struct thread_struct, 151 DEFINE(THREAD_TRANSACT_FPSTATE, offsetof(struct thread_struct,
153 transact_fpr[0])); 152 transact_fp));
154 DEFINE(THREAD_TRANSACT_FPSCR, offsetof(struct thread_struct,
155 transact_fpscr));
156#ifdef CONFIG_VSX
157 DEFINE(THREAD_TRANSACT_VSR0, offsetof(struct thread_struct,
158 transact_fpr[0]));
159#endif
160 /* Local pt_regs on stack for Transactional Memory funcs. */ 153 /* Local pt_regs on stack for Transactional Memory funcs. */
161 DEFINE(TM_FRAME_SIZE, STACK_FRAME_OVERHEAD + 154 DEFINE(TM_FRAME_SIZE, STACK_FRAME_OVERHEAD +
162 sizeof(struct pt_regs) + 16); 155 sizeof(struct pt_regs) + 16);
diff --git a/arch/powerpc/kernel/fpu.S b/arch/powerpc/kernel/fpu.S
index caeaabf11a2f..4dca05e91e95 100644
--- a/arch/powerpc/kernel/fpu.S
+++ b/arch/powerpc/kernel/fpu.S
@@ -35,15 +35,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX); \
352: REST_32VSRS(n,c,base); \ 352: REST_32VSRS(n,c,base); \
363: 363:
37 37
38#define __REST_32FPVSRS_TRANSACT(n,c,base) \
39BEGIN_FTR_SECTION \
40 b 2f; \
41END_FTR_SECTION_IFSET(CPU_FTR_VSX); \
42 REST_32FPRS_TRANSACT(n,base); \
43 b 3f; \
442: REST_32VSRS_TRANSACT(n,c,base); \
453:
46
47#define __SAVE_32FPVSRS(n,c,base) \ 38#define __SAVE_32FPVSRS(n,c,base) \
48BEGIN_FTR_SECTION \ 39BEGIN_FTR_SECTION \
49 b 2f; \ 40 b 2f; \
@@ -54,40 +45,12 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX); \
543: 453:
55#else 46#else
56#define __REST_32FPVSRS(n,b,base) REST_32FPRS(n, base) 47#define __REST_32FPVSRS(n,b,base) REST_32FPRS(n, base)
57#define __REST_32FPVSRS_TRANSACT(n,b,base) REST_32FPRS(n, base)
58#define __SAVE_32FPVSRS(n,b,base) SAVE_32FPRS(n, base) 48#define __SAVE_32FPVSRS(n,b,base) SAVE_32FPRS(n, base)
59#endif 49#endif
60#define REST_32FPVSRS(n,c,base) __REST_32FPVSRS(n,__REG_##c,__REG_##base) 50#define REST_32FPVSRS(n,c,base) __REST_32FPVSRS(n,__REG_##c,__REG_##base)
61#define REST_32FPVSRS_TRANSACT(n,c,base) \
62 __REST_32FPVSRS_TRANSACT(n,__REG_##c,__REG_##base)
63#define SAVE_32FPVSRS(n,c,base) __SAVE_32FPVSRS(n,__REG_##c,__REG_##base) 51#define SAVE_32FPVSRS(n,c,base) __SAVE_32FPVSRS(n,__REG_##c,__REG_##base)
64 52
65#ifdef CONFIG_PPC_TRANSACTIONAL_MEM 53#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
66/*
67 * Wrapper to call load_up_fpu from C.
68 * void do_load_up_fpu(struct pt_regs *regs);
69 */
70_GLOBAL(do_load_up_fpu)
71 mflr r0
72 std r0, 16(r1)
73 stdu r1, -112(r1)
74
75 subi r6, r3, STACK_FRAME_OVERHEAD
76 /* load_up_fpu expects r12=MSR, r13=PACA, and returns
77 * with r12 = new MSR.
78 */
79 ld r12,_MSR(r6)
80 GET_PACA(r13)
81
82 bl load_up_fpu
83 std r12,_MSR(r6)
84
85 ld r0, 112+16(r1)
86 addi r1, r1, 112
87 mtlr r0
88 blr
89
90
91/* void do_load_up_transact_fpu(struct thread_struct *thread) 54/* void do_load_up_transact_fpu(struct thread_struct *thread)
92 * 55 *
93 * This is similar to load_up_fpu but for the transactional version of the FP 56 * This is similar to load_up_fpu but for the transactional version of the FP
@@ -105,9 +68,10 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX)
105 SYNC 68 SYNC
106 MTMSRD(r5) 69 MTMSRD(r5)
107 70
108 lfd fr0,THREAD_TRANSACT_FPSCR(r3) 71 addi r7,r3,THREAD_TRANSACT_FPSTATE
72 lfd fr0,FPSTATE_FPSCR(r7)
109 MTFSF_L(fr0) 73 MTFSF_L(fr0)
110 REST_32FPVSRS_TRANSACT(0, R4, R3) 74 REST_32FPVSRS(0, R4, R7)
111 75
112 /* FP/VSX off again */ 76 /* FP/VSX off again */
113 MTMSRD(r6) 77 MTMSRD(r6)
@@ -117,6 +81,26 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX)
117#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ 81#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
118 82
119/* 83/*
84 * Load state from memory into FP registers including FPSCR.
85 * Assumes the caller has enabled FP in the MSR.
86 */
87_GLOBAL(load_fp_state)
88 lfd fr0,FPSTATE_FPSCR(r3)
89 MTFSF_L(fr0)
90 REST_32FPVSRS(0, R4, R3)
91 blr
92
93/*
94 * Store FP state into memory, including FPSCR
95 * Assumes the caller has enabled FP in the MSR.
96 */
97_GLOBAL(store_fp_state)
98 SAVE_32FPVSRS(0, R4, R3)
99 mffs fr0
100 stfd fr0,FPSTATE_FPSCR(r3)
101 blr
102
103/*
120 * This task wants to use the FPU now. 104 * This task wants to use the FPU now.
121 * On UP, disable FP for the task which had the FPU previously, 105 * On UP, disable FP for the task which had the FPU previously,
122 * and save its floating-point registers in its thread_struct. 106 * and save its floating-point registers in its thread_struct.
@@ -147,9 +131,10 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX)
147 beq 1f 131 beq 1f
148 toreal(r4) 132 toreal(r4)
149 addi r4,r4,THREAD /* want last_task_used_math->thread */ 133 addi r4,r4,THREAD /* want last_task_used_math->thread */
150 SAVE_32FPVSRS(0, R5, R4) 134 addi r8,r4,THREAD_FPSTATE
135 SAVE_32FPVSRS(0, R5, R8)
151 mffs fr0 136 mffs fr0
152 stfd fr0,THREAD_FPSCR(r4) 137 stfd fr0,FPSTATE_FPSCR(r8)
153 PPC_LL r5,PT_REGS(r4) 138 PPC_LL r5,PT_REGS(r4)
154 toreal(r5) 139 toreal(r5)
155 PPC_LL r4,_MSR-STACK_FRAME_OVERHEAD(r5) 140 PPC_LL r4,_MSR-STACK_FRAME_OVERHEAD(r5)
@@ -160,7 +145,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX)
160#endif /* CONFIG_SMP */ 145#endif /* CONFIG_SMP */
161 /* enable use of FP after return */ 146 /* enable use of FP after return */
162#ifdef CONFIG_PPC32 147#ifdef CONFIG_PPC32
163 mfspr r5,SPRN_SPRG_THREAD /* current task's THREAD (phys) */ 148 mfspr r5,SPRN_SPRG_THREAD /* current task's THREAD (phys) */
164 lwz r4,THREAD_FPEXC_MODE(r5) 149 lwz r4,THREAD_FPEXC_MODE(r5)
165 ori r9,r9,MSR_FP /* enable FP for current */ 150 ori r9,r9,MSR_FP /* enable FP for current */
166 or r9,r9,r4 151 or r9,r9,r4
@@ -172,9 +157,10 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX)
172 or r12,r12,r4 157 or r12,r12,r4
173 std r12,_MSR(r1) 158 std r12,_MSR(r1)
174#endif 159#endif
175 lfd fr0,THREAD_FPSCR(r5) 160 addi r7,r5,THREAD_FPSTATE
161 lfd fr0,FPSTATE_FPSCR(r7)
176 MTFSF_L(fr0) 162 MTFSF_L(fr0)
177 REST_32FPVSRS(0, R4, R5) 163 REST_32FPVSRS(0, R4, R7)
178#ifndef CONFIG_SMP 164#ifndef CONFIG_SMP
179 subi r4,r5,THREAD 165 subi r4,r5,THREAD
180 fromreal(r4) 166 fromreal(r4)
@@ -206,11 +192,15 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX)
206 PPC_LCMPI 0,r3,0 192 PPC_LCMPI 0,r3,0
207 beqlr- /* if no previous owner, done */ 193 beqlr- /* if no previous owner, done */
208 addi r3,r3,THREAD /* want THREAD of task */ 194 addi r3,r3,THREAD /* want THREAD of task */
195 PPC_LL r6,THREAD_FPSAVEAREA(r3)
209 PPC_LL r5,PT_REGS(r3) 196 PPC_LL r5,PT_REGS(r3)
210 PPC_LCMPI 0,r5,0 197 PPC_LCMPI 0,r6,0
211 SAVE_32FPVSRS(0, R4 ,R3) 198 bne 2f
199 addi r6,r3,THREAD_FPSTATE
2002: PPC_LCMPI 0,r5,0
201 SAVE_32FPVSRS(0, R4, R6)
212 mffs fr0 202 mffs fr0
213 stfd fr0,THREAD_FPSCR(r3) 203 stfd fr0,FPSTATE_FPSCR(r6)
214 beq 1f 204 beq 1f
215 PPC_LL r4,_MSR-STACK_FRAME_OVERHEAD(r5) 205 PPC_LL r4,_MSR-STACK_FRAME_OVERHEAD(r5)
216 li r3,MSR_FP|MSR_FE0|MSR_FE1 206 li r3,MSR_FP|MSR_FE0|MSR_FE1
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c
index d8c34073b42a..3bd77edd7610 100644
--- a/arch/powerpc/kernel/ppc_ksyms.c
+++ b/arch/powerpc/kernel/ppc_ksyms.c
@@ -100,9 +100,13 @@ EXPORT_SYMBOL(start_thread);
100 100
101#ifdef CONFIG_PPC_FPU 101#ifdef CONFIG_PPC_FPU
102EXPORT_SYMBOL(giveup_fpu); 102EXPORT_SYMBOL(giveup_fpu);
103EXPORT_SYMBOL(load_fp_state);
104EXPORT_SYMBOL(store_fp_state);
103#endif 105#endif
104#ifdef CONFIG_ALTIVEC 106#ifdef CONFIG_ALTIVEC
105EXPORT_SYMBOL(giveup_altivec); 107EXPORT_SYMBOL(giveup_altivec);
108EXPORT_SYMBOL(load_vr_state);
109EXPORT_SYMBOL(store_vr_state);
106#endif /* CONFIG_ALTIVEC */ 110#endif /* CONFIG_ALTIVEC */
107#ifdef CONFIG_VSX 111#ifdef CONFIG_VSX
108EXPORT_SYMBOL(giveup_vsx); 112EXPORT_SYMBOL(giveup_vsx);
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 96d2fdf3aa9e..8649a3d629e1 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -1008,6 +1008,11 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
1008 p->thread.ptrace_bps[0] = NULL; 1008 p->thread.ptrace_bps[0] = NULL;
1009#endif 1009#endif
1010 1010
1011 p->thread.fp_save_area = NULL;
1012#ifdef CONFIG_ALTIVEC
1013 p->thread.vr_save_area = NULL;
1014#endif
1015
1011#ifdef CONFIG_PPC_STD_MMU_64 1016#ifdef CONFIG_PPC_STD_MMU_64
1012 if (mmu_has_feature(MMU_FTR_SLB)) { 1017 if (mmu_has_feature(MMU_FTR_SLB)) {
1013 unsigned long sp_vsid; 1018 unsigned long sp_vsid;
@@ -1113,12 +1118,12 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp)
1113#ifdef CONFIG_VSX 1118#ifdef CONFIG_VSX
1114 current->thread.used_vsr = 0; 1119 current->thread.used_vsr = 0;
1115#endif 1120#endif
1116 memset(current->thread.fpr, 0, sizeof(current->thread.fpr)); 1121 memset(&current->thread.fp_state, 0, sizeof(current->thread.fp_state));
1117 current->thread.fpscr.val = 0; 1122 current->thread.fp_save_area = NULL;
1118#ifdef CONFIG_ALTIVEC 1123#ifdef CONFIG_ALTIVEC
1119 memset(current->thread.vr, 0, sizeof(current->thread.vr)); 1124 memset(&current->thread.vr_state, 0, sizeof(current->thread.vr_state));
1120 memset(&current->thread.vscr, 0, sizeof(current->thread.vscr)); 1125 current->thread.vr_state.vscr.u[3] = 0x00010000; /* Java mode disabled */
1121 current->thread.vscr.u[3] = 0x00010000; /* Java mode disabled */ 1126 current->thread.vr_save_area = NULL;
1122 current->thread.vrsave = 0; 1127 current->thread.vrsave = 0;
1123 current->thread.used_vr = 0; 1128 current->thread.used_vr = 0;
1124#endif /* CONFIG_ALTIVEC */ 1129#endif /* CONFIG_ALTIVEC */
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 8d5d4e921a5e..1ca589c9ec6d 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -362,7 +362,7 @@ static int fpr_get(struct task_struct *target, const struct user_regset *regset,
362 void *kbuf, void __user *ubuf) 362 void *kbuf, void __user *ubuf)
363{ 363{
364#ifdef CONFIG_VSX 364#ifdef CONFIG_VSX
365 double buf[33]; 365 u64 buf[33];
366 int i; 366 int i;
367#endif 367#endif
368 flush_fp_to_thread(target); 368 flush_fp_to_thread(target);
@@ -371,15 +371,15 @@ static int fpr_get(struct task_struct *target, const struct user_regset *regset,
371 /* copy to local buffer then write that out */ 371 /* copy to local buffer then write that out */
372 for (i = 0; i < 32 ; i++) 372 for (i = 0; i < 32 ; i++)
373 buf[i] = target->thread.TS_FPR(i); 373 buf[i] = target->thread.TS_FPR(i);
374 memcpy(&buf[32], &target->thread.fpscr, sizeof(double)); 374 buf[32] = target->thread.fp_state.fpscr;
375 return user_regset_copyout(&pos, &count, &kbuf, &ubuf, buf, 0, -1); 375 return user_regset_copyout(&pos, &count, &kbuf, &ubuf, buf, 0, -1);
376 376
377#else 377#else
378 BUILD_BUG_ON(offsetof(struct thread_struct, fpscr) != 378 BUILD_BUG_ON(offsetof(struct thread_fp_state, fpscr) !=
379 offsetof(struct thread_struct, TS_FPR(32))); 379 offsetof(struct thread_fp_state, fpr[32][0]));
380 380
381 return user_regset_copyout(&pos, &count, &kbuf, &ubuf, 381 return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
382 &target->thread.fpr, 0, -1); 382 &target->thread.fp_state, 0, -1);
383#endif 383#endif
384} 384}
385 385
@@ -388,7 +388,7 @@ static int fpr_set(struct task_struct *target, const struct user_regset *regset,
388 const void *kbuf, const void __user *ubuf) 388 const void *kbuf, const void __user *ubuf)
389{ 389{
390#ifdef CONFIG_VSX 390#ifdef CONFIG_VSX
391 double buf[33]; 391 u64 buf[33];
392 int i; 392 int i;
393#endif 393#endif
394 flush_fp_to_thread(target); 394 flush_fp_to_thread(target);
@@ -400,14 +400,14 @@ static int fpr_set(struct task_struct *target, const struct user_regset *regset,
400 return i; 400 return i;
401 for (i = 0; i < 32 ; i++) 401 for (i = 0; i < 32 ; i++)
402 target->thread.TS_FPR(i) = buf[i]; 402 target->thread.TS_FPR(i) = buf[i];
403 memcpy(&target->thread.fpscr, &buf[32], sizeof(double)); 403 target->thread.fp_state.fpscr = buf[32];
404 return 0; 404 return 0;
405#else 405#else
406 BUILD_BUG_ON(offsetof(struct thread_struct, fpscr) != 406 BUILD_BUG_ON(offsetof(struct thread_fp_state, fpscr) !=
407 offsetof(struct thread_struct, TS_FPR(32))); 407 offsetof(struct thread_fp_state, fpr[32][0]));
408 408
409 return user_regset_copyin(&pos, &count, &kbuf, &ubuf, 409 return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
410 &target->thread.fpr, 0, -1); 410 &target->thread.fp_state, 0, -1);
411#endif 411#endif
412} 412}
413 413
@@ -440,11 +440,11 @@ static int vr_get(struct task_struct *target, const struct user_regset *regset,
440 440
441 flush_altivec_to_thread(target); 441 flush_altivec_to_thread(target);
442 442
443 BUILD_BUG_ON(offsetof(struct thread_struct, vscr) != 443 BUILD_BUG_ON(offsetof(struct thread_vr_state, vscr) !=
444 offsetof(struct thread_struct, vr[32])); 444 offsetof(struct thread_vr_state, vr[32]));
445 445
446 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, 446 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
447 &target->thread.vr, 0, 447 &target->thread.vr_state, 0,
448 33 * sizeof(vector128)); 448 33 * sizeof(vector128));
449 if (!ret) { 449 if (!ret) {
450 /* 450 /*
@@ -471,11 +471,12 @@ static int vr_set(struct task_struct *target, const struct user_regset *regset,
471 471
472 flush_altivec_to_thread(target); 472 flush_altivec_to_thread(target);
473 473
474 BUILD_BUG_ON(offsetof(struct thread_struct, vscr) != 474 BUILD_BUG_ON(offsetof(struct thread_vr_state, vscr) !=
475 offsetof(struct thread_struct, vr[32])); 475 offsetof(struct thread_vr_state, vr[32]));
476 476
477 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, 477 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
478 &target->thread.vr, 0, 33 * sizeof(vector128)); 478 &target->thread.vr_state, 0,
479 33 * sizeof(vector128));
479 if (!ret && count > 0) { 480 if (!ret && count > 0) {
480 /* 481 /*
481 * We use only the first word of vrsave. 482 * We use only the first word of vrsave.
@@ -514,13 +515,13 @@ static int vsr_get(struct task_struct *target, const struct user_regset *regset,
514 unsigned int pos, unsigned int count, 515 unsigned int pos, unsigned int count,
515 void *kbuf, void __user *ubuf) 516 void *kbuf, void __user *ubuf)
516{ 517{
517 double buf[32]; 518 u64 buf[32];
518 int ret, i; 519 int ret, i;
519 520
520 flush_vsx_to_thread(target); 521 flush_vsx_to_thread(target);
521 522
522 for (i = 0; i < 32 ; i++) 523 for (i = 0; i < 32 ; i++)
523 buf[i] = target->thread.fpr[i][TS_VSRLOWOFFSET]; 524 buf[i] = target->thread.fp_state.fpr[i][TS_VSRLOWOFFSET];
524 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, 525 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
525 buf, 0, 32 * sizeof(double)); 526 buf, 0, 32 * sizeof(double));
526 527
@@ -531,7 +532,7 @@ static int vsr_set(struct task_struct *target, const struct user_regset *regset,
531 unsigned int pos, unsigned int count, 532 unsigned int pos, unsigned int count,
532 const void *kbuf, const void __user *ubuf) 533 const void *kbuf, const void __user *ubuf)
533{ 534{
534 double buf[32]; 535 u64 buf[32];
535 int ret,i; 536 int ret,i;
536 537
537 flush_vsx_to_thread(target); 538 flush_vsx_to_thread(target);
@@ -539,7 +540,7 @@ static int vsr_set(struct task_struct *target, const struct user_regset *regset,
539 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, 540 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
540 buf, 0, 32 * sizeof(double)); 541 buf, 0, 32 * sizeof(double));
541 for (i = 0; i < 32 ; i++) 542 for (i = 0; i < 32 ; i++)
542 target->thread.fpr[i][TS_VSRLOWOFFSET] = buf[i]; 543 target->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = buf[i];
543 544
544 545
545 return ret; 546 return ret;
@@ -1554,10 +1555,10 @@ long arch_ptrace(struct task_struct *child, long request,
1554 1555
1555 flush_fp_to_thread(child); 1556 flush_fp_to_thread(child);
1556 if (fpidx < (PT_FPSCR - PT_FPR0)) 1557 if (fpidx < (PT_FPSCR - PT_FPR0))
1557 memcpy(&tmp, &child->thread.TS_FPR(fpidx), 1558 memcpy(&tmp, &child->thread.fp_state.fpr,
1558 sizeof(long)); 1559 sizeof(long));
1559 else 1560 else
1560 tmp = child->thread.fpscr.val; 1561 tmp = child->thread.fp_state.fpscr;
1561 } 1562 }
1562 ret = put_user(tmp, datalp); 1563 ret = put_user(tmp, datalp);
1563 break; 1564 break;
@@ -1587,10 +1588,10 @@ long arch_ptrace(struct task_struct *child, long request,
1587 1588
1588 flush_fp_to_thread(child); 1589 flush_fp_to_thread(child);
1589 if (fpidx < (PT_FPSCR - PT_FPR0)) 1590 if (fpidx < (PT_FPSCR - PT_FPR0))
1590 memcpy(&child->thread.TS_FPR(fpidx), &data, 1591 memcpy(&child->thread.fp_state.fpr, &data,
1591 sizeof(long)); 1592 sizeof(long));
1592 else 1593 else
1593 child->thread.fpscr.val = data; 1594 child->thread.fp_state.fpscr = data;
1594 ret = 0; 1595 ret = 0;
1595 } 1596 }
1596 break; 1597 break;
diff --git a/arch/powerpc/kernel/ptrace32.c b/arch/powerpc/kernel/ptrace32.c
index f51599e941c7..097f8dc426a0 100644
--- a/arch/powerpc/kernel/ptrace32.c
+++ b/arch/powerpc/kernel/ptrace32.c
@@ -43,7 +43,6 @@
43#define FPRNUMBER(i) (((i) - PT_FPR0) >> 1) 43#define FPRNUMBER(i) (((i) - PT_FPR0) >> 1)
44#define FPRHALF(i) (((i) - PT_FPR0) & 1) 44#define FPRHALF(i) (((i) - PT_FPR0) & 1)
45#define FPRINDEX(i) TS_FPRWIDTH * FPRNUMBER(i) * 2 + FPRHALF(i) 45#define FPRINDEX(i) TS_FPRWIDTH * FPRNUMBER(i) * 2 + FPRHALF(i)
46#define FPRINDEX_3264(i) (TS_FPRWIDTH * ((i) - PT_FPR0))
47 46
48long compat_arch_ptrace(struct task_struct *child, compat_long_t request, 47long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
49 compat_ulong_t caddr, compat_ulong_t cdata) 48 compat_ulong_t caddr, compat_ulong_t cdata)
@@ -105,7 +104,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
105 * to be an array of unsigned int (32 bits) - the 104 * to be an array of unsigned int (32 bits) - the
106 * index passed in is based on this assumption. 105 * index passed in is based on this assumption.
107 */ 106 */
108 tmp = ((unsigned int *)child->thread.fpr) 107 tmp = ((unsigned int *)child->thread.fp_state.fpr)
109 [FPRINDEX(index)]; 108 [FPRINDEX(index)];
110 } 109 }
111 ret = put_user((unsigned int)tmp, (u32 __user *)data); 110 ret = put_user((unsigned int)tmp, (u32 __user *)data);
@@ -147,8 +146,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
147 if (numReg >= PT_FPR0) { 146 if (numReg >= PT_FPR0) {
148 flush_fp_to_thread(child); 147 flush_fp_to_thread(child);
149 /* get 64 bit FPR */ 148 /* get 64 bit FPR */
150 tmp = ((u64 *)child->thread.fpr) 149 tmp = child->thread.fp_state.fpr[numReg - PT_FPR0][0];
151 [FPRINDEX_3264(numReg)];
152 } else { /* register within PT_REGS struct */ 150 } else { /* register within PT_REGS struct */
153 unsigned long tmp2; 151 unsigned long tmp2;
154 ret = ptrace_get_reg(child, numReg, &tmp2); 152 ret = ptrace_get_reg(child, numReg, &tmp2);
@@ -207,7 +205,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
207 * to be an array of unsigned int (32 bits) - the 205 * to be an array of unsigned int (32 bits) - the
208 * index passed in is based on this assumption. 206 * index passed in is based on this assumption.
209 */ 207 */
210 ((unsigned int *)child->thread.fpr) 208 ((unsigned int *)child->thread.fp_state.fpr)
211 [FPRINDEX(index)] = data; 209 [FPRINDEX(index)] = data;
212 ret = 0; 210 ret = 0;
213 } 211 }
@@ -251,8 +249,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
251 u64 *tmp; 249 u64 *tmp;
252 flush_fp_to_thread(child); 250 flush_fp_to_thread(child);
253 /* get 64 bit FPR ... */ 251 /* get 64 bit FPR ... */
254 tmp = &(((u64 *)child->thread.fpr) 252 tmp = &child->thread.fp_state.fpr[numReg - PT_FPR0][0];
255 [FPRINDEX_3264(numReg)]);
256 /* ... write the 32 bit part we want */ 253 /* ... write the 32 bit part we want */
257 ((u32 *)tmp)[index % 2] = data; 254 ((u32 *)tmp)[index % 2] = data;
258 ret = 0; 255 ret = 0;
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index b386b0be8d02..c094e28b3f10 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -265,27 +265,27 @@ struct rt_sigframe {
265unsigned long copy_fpr_to_user(void __user *to, 265unsigned long copy_fpr_to_user(void __user *to,
266 struct task_struct *task) 266 struct task_struct *task)
267{ 267{
268 double buf[ELF_NFPREG]; 268 u64 buf[ELF_NFPREG];
269 int i; 269 int i;
270 270
271 /* save FPR copy to local buffer then write to the thread_struct */ 271 /* save FPR copy to local buffer then write to the thread_struct */
272 for (i = 0; i < (ELF_NFPREG - 1) ; i++) 272 for (i = 0; i < (ELF_NFPREG - 1) ; i++)
273 buf[i] = task->thread.TS_FPR(i); 273 buf[i] = task->thread.TS_FPR(i);
274 memcpy(&buf[i], &task->thread.fpscr, sizeof(double)); 274 buf[i] = task->thread.fp_state.fpscr;
275 return __copy_to_user(to, buf, ELF_NFPREG * sizeof(double)); 275 return __copy_to_user(to, buf, ELF_NFPREG * sizeof(double));
276} 276}
277 277
278unsigned long copy_fpr_from_user(struct task_struct *task, 278unsigned long copy_fpr_from_user(struct task_struct *task,
279 void __user *from) 279 void __user *from)
280{ 280{
281 double buf[ELF_NFPREG]; 281 u64 buf[ELF_NFPREG];
282 int i; 282 int i;
283 283
284 if (__copy_from_user(buf, from, ELF_NFPREG * sizeof(double))) 284 if (__copy_from_user(buf, from, ELF_NFPREG * sizeof(double)))
285 return 1; 285 return 1;
286 for (i = 0; i < (ELF_NFPREG - 1) ; i++) 286 for (i = 0; i < (ELF_NFPREG - 1) ; i++)
287 task->thread.TS_FPR(i) = buf[i]; 287 task->thread.TS_FPR(i) = buf[i];
288 memcpy(&task->thread.fpscr, &buf[i], sizeof(double)); 288 task->thread.fp_state.fpscr = buf[i];
289 289
290 return 0; 290 return 0;
291} 291}
@@ -293,25 +293,25 @@ unsigned long copy_fpr_from_user(struct task_struct *task,
293unsigned long copy_vsx_to_user(void __user *to, 293unsigned long copy_vsx_to_user(void __user *to,
294 struct task_struct *task) 294 struct task_struct *task)
295{ 295{
296 double buf[ELF_NVSRHALFREG]; 296 u64 buf[ELF_NVSRHALFREG];
297 int i; 297 int i;
298 298
299 /* save FPR copy to local buffer then write to the thread_struct */ 299 /* save FPR copy to local buffer then write to the thread_struct */
300 for (i = 0; i < ELF_NVSRHALFREG; i++) 300 for (i = 0; i < ELF_NVSRHALFREG; i++)
301 buf[i] = task->thread.fpr[i][TS_VSRLOWOFFSET]; 301 buf[i] = task->thread.fp_state.fpr[i][TS_VSRLOWOFFSET];
302 return __copy_to_user(to, buf, ELF_NVSRHALFREG * sizeof(double)); 302 return __copy_to_user(to, buf, ELF_NVSRHALFREG * sizeof(double));
303} 303}
304 304
305unsigned long copy_vsx_from_user(struct task_struct *task, 305unsigned long copy_vsx_from_user(struct task_struct *task,
306 void __user *from) 306 void __user *from)
307{ 307{
308 double buf[ELF_NVSRHALFREG]; 308 u64 buf[ELF_NVSRHALFREG];
309 int i; 309 int i;
310 310
311 if (__copy_from_user(buf, from, ELF_NVSRHALFREG * sizeof(double))) 311 if (__copy_from_user(buf, from, ELF_NVSRHALFREG * sizeof(double)))
312 return 1; 312 return 1;
313 for (i = 0; i < ELF_NVSRHALFREG ; i++) 313 for (i = 0; i < ELF_NVSRHALFREG ; i++)
314 task->thread.fpr[i][TS_VSRLOWOFFSET] = buf[i]; 314 task->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = buf[i];
315 return 0; 315 return 0;
316} 316}
317 317
@@ -319,27 +319,27 @@ unsigned long copy_vsx_from_user(struct task_struct *task,
319unsigned long copy_transact_fpr_to_user(void __user *to, 319unsigned long copy_transact_fpr_to_user(void __user *to,
320 struct task_struct *task) 320 struct task_struct *task)
321{ 321{
322 double buf[ELF_NFPREG]; 322 u64 buf[ELF_NFPREG];
323 int i; 323 int i;
324 324
325 /* save FPR copy to local buffer then write to the thread_struct */ 325 /* save FPR copy to local buffer then write to the thread_struct */
326 for (i = 0; i < (ELF_NFPREG - 1) ; i++) 326 for (i = 0; i < (ELF_NFPREG - 1) ; i++)
327 buf[i] = task->thread.TS_TRANS_FPR(i); 327 buf[i] = task->thread.TS_TRANS_FPR(i);
328 memcpy(&buf[i], &task->thread.transact_fpscr, sizeof(double)); 328 buf[i] = task->thread.transact_fp.fpscr;
329 return __copy_to_user(to, buf, ELF_NFPREG * sizeof(double)); 329 return __copy_to_user(to, buf, ELF_NFPREG * sizeof(double));
330} 330}
331 331
332unsigned long copy_transact_fpr_from_user(struct task_struct *task, 332unsigned long copy_transact_fpr_from_user(struct task_struct *task,
333 void __user *from) 333 void __user *from)
334{ 334{
335 double buf[ELF_NFPREG]; 335 u64 buf[ELF_NFPREG];
336 int i; 336 int i;
337 337
338 if (__copy_from_user(buf, from, ELF_NFPREG * sizeof(double))) 338 if (__copy_from_user(buf, from, ELF_NFPREG * sizeof(double)))
339 return 1; 339 return 1;
340 for (i = 0; i < (ELF_NFPREG - 1) ; i++) 340 for (i = 0; i < (ELF_NFPREG - 1) ; i++)
341 task->thread.TS_TRANS_FPR(i) = buf[i]; 341 task->thread.TS_TRANS_FPR(i) = buf[i];
342 memcpy(&task->thread.transact_fpscr, &buf[i], sizeof(double)); 342 task->thread.transact_fp.fpscr = buf[i];
343 343
344 return 0; 344 return 0;
345} 345}
@@ -347,25 +347,25 @@ unsigned long copy_transact_fpr_from_user(struct task_struct *task,
347unsigned long copy_transact_vsx_to_user(void __user *to, 347unsigned long copy_transact_vsx_to_user(void __user *to,
348 struct task_struct *task) 348 struct task_struct *task)
349{ 349{
350 double buf[ELF_NVSRHALFREG]; 350 u64 buf[ELF_NVSRHALFREG];
351 int i; 351 int i;
352 352
353 /* save FPR copy to local buffer then write to the thread_struct */ 353 /* save FPR copy to local buffer then write to the thread_struct */
354 for (i = 0; i < ELF_NVSRHALFREG; i++) 354 for (i = 0; i < ELF_NVSRHALFREG; i++)
355 buf[i] = task->thread.transact_fpr[i][TS_VSRLOWOFFSET]; 355 buf[i] = task->thread.transact_fp.fpr[i][TS_VSRLOWOFFSET];
356 return __copy_to_user(to, buf, ELF_NVSRHALFREG * sizeof(double)); 356 return __copy_to_user(to, buf, ELF_NVSRHALFREG * sizeof(double));
357} 357}
358 358
359unsigned long copy_transact_vsx_from_user(struct task_struct *task, 359unsigned long copy_transact_vsx_from_user(struct task_struct *task,
360 void __user *from) 360 void __user *from)
361{ 361{
362 double buf[ELF_NVSRHALFREG]; 362 u64 buf[ELF_NVSRHALFREG];
363 int i; 363 int i;
364 364
365 if (__copy_from_user(buf, from, ELF_NVSRHALFREG * sizeof(double))) 365 if (__copy_from_user(buf, from, ELF_NVSRHALFREG * sizeof(double)))
366 return 1; 366 return 1;
367 for (i = 0; i < ELF_NVSRHALFREG ; i++) 367 for (i = 0; i < ELF_NVSRHALFREG ; i++)
368 task->thread.transact_fpr[i][TS_VSRLOWOFFSET] = buf[i]; 368 task->thread.transact_fp.fpr[i][TS_VSRLOWOFFSET] = buf[i];
369 return 0; 369 return 0;
370} 370}
371#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ 371#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
@@ -373,14 +373,14 @@ unsigned long copy_transact_vsx_from_user(struct task_struct *task,
373inline unsigned long copy_fpr_to_user(void __user *to, 373inline unsigned long copy_fpr_to_user(void __user *to,
374 struct task_struct *task) 374 struct task_struct *task)
375{ 375{
376 return __copy_to_user(to, task->thread.fpr, 376 return __copy_to_user(to, task->thread.fp_state.fpr,
377 ELF_NFPREG * sizeof(double)); 377 ELF_NFPREG * sizeof(double));
378} 378}
379 379
380inline unsigned long copy_fpr_from_user(struct task_struct *task, 380inline unsigned long copy_fpr_from_user(struct task_struct *task,
381 void __user *from) 381 void __user *from)
382{ 382{
383 return __copy_from_user(task->thread.fpr, from, 383 return __copy_from_user(task->thread.fp_state.fpr, from,
384 ELF_NFPREG * sizeof(double)); 384 ELF_NFPREG * sizeof(double));
385} 385}
386 386
@@ -388,14 +388,14 @@ inline unsigned long copy_fpr_from_user(struct task_struct *task,
388inline unsigned long copy_transact_fpr_to_user(void __user *to, 388inline unsigned long copy_transact_fpr_to_user(void __user *to,
389 struct task_struct *task) 389 struct task_struct *task)
390{ 390{
391 return __copy_to_user(to, task->thread.transact_fpr, 391 return __copy_to_user(to, task->thread.transact_fp.fpr,
392 ELF_NFPREG * sizeof(double)); 392 ELF_NFPREG * sizeof(double));
393} 393}
394 394
395inline unsigned long copy_transact_fpr_from_user(struct task_struct *task, 395inline unsigned long copy_transact_fpr_from_user(struct task_struct *task,
396 void __user *from) 396 void __user *from)
397{ 397{
398 return __copy_from_user(task->thread.transact_fpr, from, 398 return __copy_from_user(task->thread.transact_fp.fpr, from,
399 ELF_NFPREG * sizeof(double)); 399 ELF_NFPREG * sizeof(double));
400} 400}
401#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ 401#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
@@ -423,7 +423,7 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
423 /* save altivec registers */ 423 /* save altivec registers */
424 if (current->thread.used_vr) { 424 if (current->thread.used_vr) {
425 flush_altivec_to_thread(current); 425 flush_altivec_to_thread(current);
426 if (__copy_to_user(&frame->mc_vregs, current->thread.vr, 426 if (__copy_to_user(&frame->mc_vregs, &current->thread.vr_state,
427 ELF_NVRREG * sizeof(vector128))) 427 ELF_NVRREG * sizeof(vector128)))
428 return 1; 428 return 1;
429 /* set MSR_VEC in the saved MSR value to indicate that 429 /* set MSR_VEC in the saved MSR value to indicate that
@@ -534,17 +534,17 @@ static int save_tm_user_regs(struct pt_regs *regs,
534 /* save altivec registers */ 534 /* save altivec registers */
535 if (current->thread.used_vr) { 535 if (current->thread.used_vr) {
536 flush_altivec_to_thread(current); 536 flush_altivec_to_thread(current);
537 if (__copy_to_user(&frame->mc_vregs, current->thread.vr, 537 if (__copy_to_user(&frame->mc_vregs, &current->thread.vr_state,
538 ELF_NVRREG * sizeof(vector128))) 538 ELF_NVRREG * sizeof(vector128)))
539 return 1; 539 return 1;
540 if (msr & MSR_VEC) { 540 if (msr & MSR_VEC) {
541 if (__copy_to_user(&tm_frame->mc_vregs, 541 if (__copy_to_user(&tm_frame->mc_vregs,
542 current->thread.transact_vr, 542 &current->thread.transact_vr,
543 ELF_NVRREG * sizeof(vector128))) 543 ELF_NVRREG * sizeof(vector128)))
544 return 1; 544 return 1;
545 } else { 545 } else {
546 if (__copy_to_user(&tm_frame->mc_vregs, 546 if (__copy_to_user(&tm_frame->mc_vregs,
547 current->thread.vr, 547 &current->thread.vr_state,
548 ELF_NVRREG * sizeof(vector128))) 548 ELF_NVRREG * sizeof(vector128)))
549 return 1; 549 return 1;
550 } 550 }
@@ -692,11 +692,12 @@ static long restore_user_regs(struct pt_regs *regs,
692 regs->msr &= ~MSR_VEC; 692 regs->msr &= ~MSR_VEC;
693 if (msr & MSR_VEC) { 693 if (msr & MSR_VEC) {
694 /* restore altivec registers from the stack */ 694 /* restore altivec registers from the stack */
695 if (__copy_from_user(current->thread.vr, &sr->mc_vregs, 695 if (__copy_from_user(&current->thread.vr_state, &sr->mc_vregs,
696 sizeof(sr->mc_vregs))) 696 sizeof(sr->mc_vregs)))
697 return 1; 697 return 1;
698 } else if (current->thread.used_vr) 698 } else if (current->thread.used_vr)
699 memset(current->thread.vr, 0, ELF_NVRREG * sizeof(vector128)); 699 memset(&current->thread.vr_state, 0,
700 ELF_NVRREG * sizeof(vector128));
700 701
701 /* Always get VRSAVE back */ 702 /* Always get VRSAVE back */
702 if (__get_user(current->thread.vrsave, (u32 __user *)&sr->mc_vregs[32])) 703 if (__get_user(current->thread.vrsave, (u32 __user *)&sr->mc_vregs[32]))
@@ -722,7 +723,7 @@ static long restore_user_regs(struct pt_regs *regs,
722 return 1; 723 return 1;
723 } else if (current->thread.used_vsr) 724 } else if (current->thread.used_vsr)
724 for (i = 0; i < 32 ; i++) 725 for (i = 0; i < 32 ; i++)
725 current->thread.fpr[i][TS_VSRLOWOFFSET] = 0; 726 current->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = 0;
726#endif /* CONFIG_VSX */ 727#endif /* CONFIG_VSX */
727 /* 728 /*
728 * force the process to reload the FP registers from 729 * force the process to reload the FP registers from
@@ -798,15 +799,16 @@ static long restore_tm_user_regs(struct pt_regs *regs,
798 regs->msr &= ~MSR_VEC; 799 regs->msr &= ~MSR_VEC;
799 if (msr & MSR_VEC) { 800 if (msr & MSR_VEC) {
800 /* restore altivec registers from the stack */ 801 /* restore altivec registers from the stack */
801 if (__copy_from_user(current->thread.vr, &sr->mc_vregs, 802 if (__copy_from_user(&current->thread.vr_state, &sr->mc_vregs,
802 sizeof(sr->mc_vregs)) || 803 sizeof(sr->mc_vregs)) ||
803 __copy_from_user(current->thread.transact_vr, 804 __copy_from_user(&current->thread.transact_vr,
804 &tm_sr->mc_vregs, 805 &tm_sr->mc_vregs,
805 sizeof(sr->mc_vregs))) 806 sizeof(sr->mc_vregs)))
806 return 1; 807 return 1;
807 } else if (current->thread.used_vr) { 808 } else if (current->thread.used_vr) {
808 memset(current->thread.vr, 0, ELF_NVRREG * sizeof(vector128)); 809 memset(&current->thread.vr_state, 0,
809 memset(current->thread.transact_vr, 0, 810 ELF_NVRREG * sizeof(vector128));
811 memset(&current->thread.transact_vr, 0,
810 ELF_NVRREG * sizeof(vector128)); 812 ELF_NVRREG * sizeof(vector128));
811 } 813 }
812 814
@@ -838,8 +840,8 @@ static long restore_tm_user_regs(struct pt_regs *regs,
838 return 1; 840 return 1;
839 } else if (current->thread.used_vsr) 841 } else if (current->thread.used_vsr)
840 for (i = 0; i < 32 ; i++) { 842 for (i = 0; i < 32 ; i++) {
841 current->thread.fpr[i][TS_VSRLOWOFFSET] = 0; 843 current->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = 0;
842 current->thread.transact_fpr[i][TS_VSRLOWOFFSET] = 0; 844 current->thread.transact_fp.fpr[i][TS_VSRLOWOFFSET] = 0;
843 } 845 }
844#endif /* CONFIG_VSX */ 846#endif /* CONFIG_VSX */
845 847
@@ -1030,7 +1032,7 @@ int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka,
1030 if (__put_user(0, &rt_sf->uc.uc_link)) 1032 if (__put_user(0, &rt_sf->uc.uc_link))
1031 goto badframe; 1033 goto badframe;
1032 1034
1033 current->thread.fpscr.val = 0; /* turn off all fp exceptions */ 1035 current->thread.fp_state.fpscr = 0; /* turn off all fp exceptions */
1034 1036
1035 /* create a stack frame for the caller of the handler */ 1037 /* create a stack frame for the caller of the handler */
1036 newsp = ((unsigned long)rt_sf) - (__SIGNAL_FRAMESIZE + 16); 1038 newsp = ((unsigned long)rt_sf) - (__SIGNAL_FRAMESIZE + 16);
@@ -1463,7 +1465,7 @@ int handle_signal32(unsigned long sig, struct k_sigaction *ka,
1463 1465
1464 regs->link = tramp; 1466 regs->link = tramp;
1465 1467
1466 current->thread.fpscr.val = 0; /* turn off all fp exceptions */ 1468 current->thread.fp_state.fpscr = 0; /* turn off all fp exceptions */
1467 1469
1468 /* create a stack frame for the caller of the handler */ 1470 /* create a stack frame for the caller of the handler */
1469 newsp = ((unsigned long)frame) - __SIGNAL_FRAMESIZE; 1471 newsp = ((unsigned long)frame) - __SIGNAL_FRAMESIZE;
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
index 8b51b0278106..b3c615764c9b 100644
--- a/arch/powerpc/kernel/signal_64.c
+++ b/arch/powerpc/kernel/signal_64.c
@@ -103,7 +103,8 @@ static long setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
103 if (current->thread.used_vr) { 103 if (current->thread.used_vr) {
104 flush_altivec_to_thread(current); 104 flush_altivec_to_thread(current);
105 /* Copy 33 vec registers (vr0..31 and vscr) to the stack */ 105 /* Copy 33 vec registers (vr0..31 and vscr) to the stack */
106 err |= __copy_to_user(v_regs, current->thread.vr, 33 * sizeof(vector128)); 106 err |= __copy_to_user(v_regs, &current->thread.vr_state,
107 33 * sizeof(vector128));
107 /* set MSR_VEC in the MSR value in the frame to indicate that sc->v_reg) 108 /* set MSR_VEC in the MSR value in the frame to indicate that sc->v_reg)
108 * contains valid data. 109 * contains valid data.
109 */ 110 */
@@ -195,18 +196,18 @@ static long setup_tm_sigcontexts(struct sigcontext __user *sc,
195 if (current->thread.used_vr) { 196 if (current->thread.used_vr) {
196 flush_altivec_to_thread(current); 197 flush_altivec_to_thread(current);
197 /* Copy 33 vec registers (vr0..31 and vscr) to the stack */ 198 /* Copy 33 vec registers (vr0..31 and vscr) to the stack */
198 err |= __copy_to_user(v_regs, current->thread.vr, 199 err |= __copy_to_user(v_regs, &current->thread.vr_state,
199 33 * sizeof(vector128)); 200 33 * sizeof(vector128));
200 /* If VEC was enabled there are transactional VRs valid too, 201 /* If VEC was enabled there are transactional VRs valid too,
201 * else they're a copy of the checkpointed VRs. 202 * else they're a copy of the checkpointed VRs.
202 */ 203 */
203 if (msr & MSR_VEC) 204 if (msr & MSR_VEC)
204 err |= __copy_to_user(tm_v_regs, 205 err |= __copy_to_user(tm_v_regs,
205 current->thread.transact_vr, 206 &current->thread.transact_vr,
206 33 * sizeof(vector128)); 207 33 * sizeof(vector128));
207 else 208 else
208 err |= __copy_to_user(tm_v_regs, 209 err |= __copy_to_user(tm_v_regs,
209 current->thread.vr, 210 &current->thread.vr_state,
210 33 * sizeof(vector128)); 211 33 * sizeof(vector128));
211 212
212 /* set MSR_VEC in the MSR value in the frame to indicate 213 /* set MSR_VEC in the MSR value in the frame to indicate
@@ -349,10 +350,10 @@ static long restore_sigcontext(struct pt_regs *regs, sigset_t *set, int sig,
349 return -EFAULT; 350 return -EFAULT;
350 /* Copy 33 vec registers (vr0..31 and vscr) from the stack */ 351 /* Copy 33 vec registers (vr0..31 and vscr) from the stack */
351 if (v_regs != NULL && (msr & MSR_VEC) != 0) 352 if (v_regs != NULL && (msr & MSR_VEC) != 0)
352 err |= __copy_from_user(current->thread.vr, v_regs, 353 err |= __copy_from_user(&current->thread.vr_state, v_regs,
353 33 * sizeof(vector128)); 354 33 * sizeof(vector128));
354 else if (current->thread.used_vr) 355 else if (current->thread.used_vr)
355 memset(current->thread.vr, 0, 33 * sizeof(vector128)); 356 memset(&current->thread.vr_state, 0, 33 * sizeof(vector128));
356 /* Always get VRSAVE back */ 357 /* Always get VRSAVE back */
357 if (v_regs != NULL) 358 if (v_regs != NULL)
358 err |= __get_user(current->thread.vrsave, (u32 __user *)&v_regs[33]); 359 err |= __get_user(current->thread.vrsave, (u32 __user *)&v_regs[33]);
@@ -374,7 +375,7 @@ static long restore_sigcontext(struct pt_regs *regs, sigset_t *set, int sig,
374 err |= copy_vsx_from_user(current, v_regs); 375 err |= copy_vsx_from_user(current, v_regs);
375 else 376 else
376 for (i = 0; i < 32 ; i++) 377 for (i = 0; i < 32 ; i++)
377 current->thread.fpr[i][TS_VSRLOWOFFSET] = 0; 378 current->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = 0;
378#endif 379#endif
379 return err; 380 return err;
380} 381}
@@ -468,14 +469,14 @@ static long restore_tm_sigcontexts(struct pt_regs *regs,
468 return -EFAULT; 469 return -EFAULT;
469 /* Copy 33 vec registers (vr0..31 and vscr) from the stack */ 470 /* Copy 33 vec registers (vr0..31 and vscr) from the stack */
470 if (v_regs != NULL && tm_v_regs != NULL && (msr & MSR_VEC) != 0) { 471 if (v_regs != NULL && tm_v_regs != NULL && (msr & MSR_VEC) != 0) {
471 err |= __copy_from_user(current->thread.vr, v_regs, 472 err |= __copy_from_user(&current->thread.vr_state, v_regs,
472 33 * sizeof(vector128)); 473 33 * sizeof(vector128));
473 err |= __copy_from_user(current->thread.transact_vr, tm_v_regs, 474 err |= __copy_from_user(&current->thread.transact_vr, tm_v_regs,
474 33 * sizeof(vector128)); 475 33 * sizeof(vector128));
475 } 476 }
476 else if (current->thread.used_vr) { 477 else if (current->thread.used_vr) {
477 memset(current->thread.vr, 0, 33 * sizeof(vector128)); 478 memset(&current->thread.vr_state, 0, 33 * sizeof(vector128));
478 memset(current->thread.transact_vr, 0, 33 * sizeof(vector128)); 479 memset(&current->thread.transact_vr, 0, 33 * sizeof(vector128));
479 } 480 }
480 /* Always get VRSAVE back */ 481 /* Always get VRSAVE back */
481 if (v_regs != NULL && tm_v_regs != NULL) { 482 if (v_regs != NULL && tm_v_regs != NULL) {
@@ -507,8 +508,8 @@ static long restore_tm_sigcontexts(struct pt_regs *regs,
507 err |= copy_transact_vsx_from_user(current, tm_v_regs); 508 err |= copy_transact_vsx_from_user(current, tm_v_regs);
508 } else { 509 } else {
509 for (i = 0; i < 32 ; i++) { 510 for (i = 0; i < 32 ; i++) {
510 current->thread.fpr[i][TS_VSRLOWOFFSET] = 0; 511 current->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = 0;
511 current->thread.transact_fpr[i][TS_VSRLOWOFFSET] = 0; 512 current->thread.transact_fp.fpr[i][TS_VSRLOWOFFSET] = 0;
512 } 513 }
513 } 514 }
514#endif 515#endif
@@ -747,7 +748,7 @@ int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info,
747 goto badframe; 748 goto badframe;
748 749
749 /* Make sure signal handler doesn't get spurious FP exceptions */ 750 /* Make sure signal handler doesn't get spurious FP exceptions */
750 current->thread.fpscr.val = 0; 751 current->thread.fp_state.fpscr = 0;
751#ifdef CONFIG_PPC_TRANSACTIONAL_MEM 752#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
752 /* Remove TM bits from thread's MSR. The MSR in the sigcontext 753 /* Remove TM bits from thread's MSR. The MSR in the sigcontext
753 * just indicates to userland that we were doing a transaction, but we 754 * just indicates to userland that we were doing a transaction, but we
diff --git a/arch/powerpc/kernel/tm.S b/arch/powerpc/kernel/tm.S
index cd809eaa8b5c..761af4f0a632 100644
--- a/arch/powerpc/kernel/tm.S
+++ b/arch/powerpc/kernel/tm.S
@@ -12,16 +12,15 @@
12#include <asm/reg.h> 12#include <asm/reg.h>
13 13
14#ifdef CONFIG_VSX 14#ifdef CONFIG_VSX
15/* See fpu.S, this is very similar but to save/restore checkpointed FPRs/VSRs */ 15/* See fpu.S, this is borrowed from there */
16#define __SAVE_32FPRS_VSRS_TRANSACT(n,c,base) \ 16#define __SAVE_32FPRS_VSRS(n,c,base) \
17BEGIN_FTR_SECTION \ 17BEGIN_FTR_SECTION \
18 b 2f; \ 18 b 2f; \
19END_FTR_SECTION_IFSET(CPU_FTR_VSX); \ 19END_FTR_SECTION_IFSET(CPU_FTR_VSX); \
20 SAVE_32FPRS_TRANSACT(n,base); \ 20 SAVE_32FPRS(n,base); \
21 b 3f; \ 21 b 3f; \
222: SAVE_32VSRS_TRANSACT(n,c,base); \ 222: SAVE_32VSRS(n,c,base); \
233: 233:
24/* ...and this is just plain borrowed from there. */
25#define __REST_32FPRS_VSRS(n,c,base) \ 24#define __REST_32FPRS_VSRS(n,c,base) \
26BEGIN_FTR_SECTION \ 25BEGIN_FTR_SECTION \
27 b 2f; \ 26 b 2f; \
@@ -31,11 +30,11 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX); \
312: REST_32VSRS(n,c,base); \ 302: REST_32VSRS(n,c,base); \
323: 313:
33#else 32#else
34#define __SAVE_32FPRS_VSRS_TRANSACT(n,c,base) SAVE_32FPRS_TRANSACT(n, base) 33#define __SAVE_32FPRS_VSRS(n,c,base) SAVE_32FPRS(n, base)
35#define __REST_32FPRS_VSRS(n,c,base) REST_32FPRS(n, base) 34#define __REST_32FPRS_VSRS(n,c,base) REST_32FPRS(n, base)
36#endif 35#endif
37#define SAVE_32FPRS_VSRS_TRANSACT(n,c,base) \ 36#define SAVE_32FPRS_VSRS(n,c,base) \
38 __SAVE_32FPRS_VSRS_TRANSACT(n,__REG_##c,__REG_##base) 37 __SAVE_32FPRS_VSRS(n,__REG_##c,__REG_##base)
39#define REST_32FPRS_VSRS(n,c,base) \ 38#define REST_32FPRS_VSRS(n,c,base) \
40 __REST_32FPRS_VSRS(n,__REG_##c,__REG_##base) 39 __REST_32FPRS_VSRS(n,__REG_##c,__REG_##base)
41 40
@@ -157,10 +156,11 @@ _GLOBAL(tm_reclaim)
157 andis. r0, r4, MSR_VEC@h 156 andis. r0, r4, MSR_VEC@h
158 beq dont_backup_vec 157 beq dont_backup_vec
159 158
160 SAVE_32VRS_TRANSACT(0, r6, r3) /* r6 scratch, r3 thread */ 159 addi r7, r3, THREAD_TRANSACT_VRSTATE
160 SAVE_32VRS(0, r6, r7) /* r6 scratch, r7 transact vr state */
161 mfvscr vr0 161 mfvscr vr0
162 li r6, THREAD_TRANSACT_VSCR 162 li r6, VRSTATE_VSCR
163 stvx vr0, r3, r6 163 stvx vr0, r7, r6
164dont_backup_vec: 164dont_backup_vec:
165 mfspr r0, SPRN_VRSAVE 165 mfspr r0, SPRN_VRSAVE
166 std r0, THREAD_TRANSACT_VRSAVE(r3) 166 std r0, THREAD_TRANSACT_VRSAVE(r3)
@@ -168,10 +168,11 @@ dont_backup_vec:
168 andi. r0, r4, MSR_FP 168 andi. r0, r4, MSR_FP
169 beq dont_backup_fp 169 beq dont_backup_fp
170 170
171 SAVE_32FPRS_VSRS_TRANSACT(0, R6, R3) /* r6 scratch, r3 thread */ 171 addi r7, r3, THREAD_TRANSACT_FPSTATE
172 SAVE_32FPRS_VSRS(0, R6, R7) /* r6 scratch, r7 transact fp state */
172 173
173 mffs fr0 174 mffs fr0
174 stfd fr0,THREAD_TRANSACT_FPSCR(r3) 175 stfd fr0,FPSTATE_FPSCR(r7)
175 176
176dont_backup_fp: 177dont_backup_fp:
177 /* The moment we treclaim, ALL of our GPRs will switch 178 /* The moment we treclaim, ALL of our GPRs will switch
@@ -358,10 +359,11 @@ _GLOBAL(tm_recheckpoint)
358 andis. r0, r4, MSR_VEC@h 359 andis. r0, r4, MSR_VEC@h
359 beq dont_restore_vec 360 beq dont_restore_vec
360 361
361 li r5, THREAD_VSCR 362 addi r8, r3, THREAD_VRSTATE
362 lvx vr0, r3, r5 363 li r5, VRSTATE_VSCR
364 lvx vr0, r8, r5
363 mtvscr vr0 365 mtvscr vr0
364 REST_32VRS(0, r5, r3) /* r5 scratch, r3 THREAD ptr */ 366 REST_32VRS(0, r5, r8) /* r5 scratch, r8 ptr */
365dont_restore_vec: 367dont_restore_vec:
366 ld r5, THREAD_VRSAVE(r3) 368 ld r5, THREAD_VRSAVE(r3)
367 mtspr SPRN_VRSAVE, r5 369 mtspr SPRN_VRSAVE, r5
@@ -370,9 +372,10 @@ dont_restore_vec:
370 andi. r0, r4, MSR_FP 372 andi. r0, r4, MSR_FP
371 beq dont_restore_fp 373 beq dont_restore_fp
372 374
373 lfd fr0, THREAD_FPSCR(r3) 375 addi r8, r3, THREAD_FPSTATE
376 lfd fr0, FPSTATE_FPSCR(r8)
374 MTFSF_L(fr0) 377 MTFSF_L(fr0)
375 REST_32FPRS_VSRS(0, R4, R3) 378 REST_32FPRS_VSRS(0, R4, R8)
376 379
377dont_restore_fp: 380dont_restore_fp:
378 mtmsr r6 /* FP/Vec off again! */ 381 mtmsr r6 /* FP/Vec off again! */
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index f783c932faeb..f0a6814007a5 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -816,7 +816,7 @@ static void parse_fpe(struct pt_regs *regs)
816 816
817 flush_fp_to_thread(current); 817 flush_fp_to_thread(current);
818 818
819 code = __parse_fpscr(current->thread.fpscr.val); 819 code = __parse_fpscr(current->thread.fp_state.fpscr);
820 820
821 _exception(SIGFPE, regs, code, regs->nip); 821 _exception(SIGFPE, regs, code, regs->nip);
822} 822}
@@ -1069,7 +1069,7 @@ static int emulate_math(struct pt_regs *regs)
1069 return 0; 1069 return 0;
1070 case 1: { 1070 case 1: {
1071 int code = 0; 1071 int code = 0;
1072 code = __parse_fpscr(current->thread.fpscr.val); 1072 code = __parse_fpscr(current->thread.fp_state.fpscr);
1073 _exception(SIGFPE, regs, code, regs->nip); 1073 _exception(SIGFPE, regs, code, regs->nip);
1074 return 0; 1074 return 0;
1075 } 1075 }
@@ -1371,8 +1371,6 @@ void facility_unavailable_exception(struct pt_regs *regs)
1371 1371
1372#ifdef CONFIG_PPC_TRANSACTIONAL_MEM 1372#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
1373 1373
1374extern void do_load_up_fpu(struct pt_regs *regs);
1375
1376void fp_unavailable_tm(struct pt_regs *regs) 1374void fp_unavailable_tm(struct pt_regs *regs)
1377{ 1375{
1378 /* Note: This does not handle any kind of FP laziness. */ 1376 /* Note: This does not handle any kind of FP laziness. */
@@ -1403,8 +1401,6 @@ void fp_unavailable_tm(struct pt_regs *regs)
1403} 1401}
1404 1402
1405#ifdef CONFIG_ALTIVEC 1403#ifdef CONFIG_ALTIVEC
1406extern void do_load_up_altivec(struct pt_regs *regs);
1407
1408void altivec_unavailable_tm(struct pt_regs *regs) 1404void altivec_unavailable_tm(struct pt_regs *regs)
1409{ 1405{
1410 /* See the comments in fp_unavailable_tm(). This function operates 1406 /* See the comments in fp_unavailable_tm(). This function operates
@@ -1634,7 +1630,7 @@ void altivec_assist_exception(struct pt_regs *regs)
1634 /* XXX quick hack for now: set the non-Java bit in the VSCR */ 1630 /* XXX quick hack for now: set the non-Java bit in the VSCR */
1635 printk_ratelimited(KERN_ERR "Unrecognized altivec instruction " 1631 printk_ratelimited(KERN_ERR "Unrecognized altivec instruction "
1636 "in %s at %lx\n", current->comm, regs->nip); 1632 "in %s at %lx\n", current->comm, regs->nip);
1637 current->thread.vscr.u[3] |= 0x10000; 1633 current->thread.vr_state.vscr.u[3] |= 0x10000;
1638 } 1634 }
1639} 1635}
1640#endif /* CONFIG_ALTIVEC */ 1636#endif /* CONFIG_ALTIVEC */
diff --git a/arch/powerpc/kernel/vecemu.c b/arch/powerpc/kernel/vecemu.c
index 604d0947cb20..c4bfadb2606b 100644
--- a/arch/powerpc/kernel/vecemu.c
+++ b/arch/powerpc/kernel/vecemu.c
@@ -271,7 +271,7 @@ int emulate_altivec(struct pt_regs *regs)
271 vb = (instr >> 11) & 0x1f; 271 vb = (instr >> 11) & 0x1f;
272 vc = (instr >> 6) & 0x1f; 272 vc = (instr >> 6) & 0x1f;
273 273
274 vrs = current->thread.vr; 274 vrs = current->thread.vr_state.vr;
275 switch (instr & 0x3f) { 275 switch (instr & 0x3f) {
276 case 10: 276 case 10:
277 switch (vc) { 277 switch (vc) {
@@ -320,12 +320,12 @@ int emulate_altivec(struct pt_regs *regs)
320 case 14: /* vctuxs */ 320 case 14: /* vctuxs */
321 for (i = 0; i < 4; ++i) 321 for (i = 0; i < 4; ++i)
322 vrs[vd].u[i] = ctuxs(vrs[vb].u[i], va, 322 vrs[vd].u[i] = ctuxs(vrs[vb].u[i], va,
323 &current->thread.vscr.u[3]); 323 &current->thread.vr_state.vscr.u[3]);
324 break; 324 break;
325 case 15: /* vctsxs */ 325 case 15: /* vctsxs */
326 for (i = 0; i < 4; ++i) 326 for (i = 0; i < 4; ++i)
327 vrs[vd].u[i] = ctsxs(vrs[vb].u[i], va, 327 vrs[vd].u[i] = ctsxs(vrs[vb].u[i], va,
328 &current->thread.vscr.u[3]); 328 &current->thread.vr_state.vscr.u[3]);
329 break; 329 break;
330 default: 330 default:
331 return -EINVAL; 331 return -EINVAL;
diff --git a/arch/powerpc/kernel/vector.S b/arch/powerpc/kernel/vector.S
index 9e20999aaef2..eacda4eea2d7 100644
--- a/arch/powerpc/kernel/vector.S
+++ b/arch/powerpc/kernel/vector.S
@@ -8,29 +8,6 @@
8#include <asm/ptrace.h> 8#include <asm/ptrace.h>
9 9
10#ifdef CONFIG_PPC_TRANSACTIONAL_MEM 10#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
11/*
12 * Wrapper to call load_up_altivec from C.
13 * void do_load_up_altivec(struct pt_regs *regs);
14 */
15_GLOBAL(do_load_up_altivec)
16 mflr r0
17 std r0, 16(r1)
18 stdu r1, -112(r1)
19
20 subi r6, r3, STACK_FRAME_OVERHEAD
21 /* load_up_altivec expects r12=MSR, r13=PACA, and returns
22 * with r12 = new MSR.
23 */
24 ld r12,_MSR(r6)
25 GET_PACA(r13)
26 bl load_up_altivec
27 std r12,_MSR(r6)
28
29 ld r0, 112+16(r1)
30 addi r1, r1, 112
31 mtlr r0
32 blr
33
34/* void do_load_up_transact_altivec(struct thread_struct *thread) 11/* void do_load_up_transact_altivec(struct thread_struct *thread)
35 * 12 *
36 * This is similar to load_up_altivec but for the transactional version of the 13 * This is similar to load_up_altivec but for the transactional version of the
@@ -46,10 +23,11 @@ _GLOBAL(do_load_up_transact_altivec)
46 li r4,1 23 li r4,1
47 stw r4,THREAD_USED_VR(r3) 24 stw r4,THREAD_USED_VR(r3)
48 25
49 li r10,THREAD_TRANSACT_VSCR 26 li r10,THREAD_TRANSACT_VRSTATE+VRSTATE_VSCR
50 lvx vr0,r10,r3 27 lvx vr0,r10,r3
51 mtvscr vr0 28 mtvscr vr0
52 REST_32VRS_TRANSACT(0,r4,r3) 29 addi r10,r3,THREAD_TRANSACT_VRSTATE
30 REST_32VRS(0,r4,r10)
53 31
54 /* Disable VEC again. */ 32 /* Disable VEC again. */
55 MTMSRD(r6) 33 MTMSRD(r6)
@@ -59,7 +37,28 @@ _GLOBAL(do_load_up_transact_altivec)
59#endif 37#endif
60 38
61/* 39/*
62 * load_up_altivec(unused, unused, tsk) 40 * Load state from memory into VMX registers including VSCR.
41 * Assumes the caller has enabled VMX in the MSR.
42 */
43_GLOBAL(load_vr_state)
44 li r4,VRSTATE_VSCR
45 lvx vr0,r4,r3
46 mtvscr vr0
47 REST_32VRS(0,r4,r3)
48 blr
49
50/*
51 * Store VMX state into memory, including VSCR.
52 * Assumes the caller has enabled VMX in the MSR.
53 */
54_GLOBAL(store_vr_state)
55 SAVE_32VRS(0, r4, r3)
56 mfvscr vr0
57 li r4, VRSTATE_VSCR
58 stvx vr0, r4, r3
59 blr
60
61/*
63 * Disable VMX for the task which had it previously, 62 * Disable VMX for the task which had it previously,
64 * and save its vector registers in its thread_struct. 63 * and save its vector registers in its thread_struct.
65 * Enables the VMX for use in the kernel on return. 64 * Enables the VMX for use in the kernel on return.
@@ -90,10 +89,11 @@ _GLOBAL(load_up_altivec)
90 /* Save VMX state to last_task_used_altivec's THREAD struct */ 89 /* Save VMX state to last_task_used_altivec's THREAD struct */
91 toreal(r4) 90 toreal(r4)
92 addi r4,r4,THREAD 91 addi r4,r4,THREAD
93 SAVE_32VRS(0,r5,r4) 92 addi r7,r4,THREAD_VRSTATE
93 SAVE_32VRS(0,r5,r7)
94 mfvscr vr0 94 mfvscr vr0
95 li r10,THREAD_VSCR 95 li r10,VRSTATE_VSCR
96 stvx vr0,r10,r4 96 stvx vr0,r10,r7
97 /* Disable VMX for last_task_used_altivec */ 97 /* Disable VMX for last_task_used_altivec */
98 PPC_LL r5,PT_REGS(r4) 98 PPC_LL r5,PT_REGS(r4)
99 toreal(r5) 99 toreal(r5)
@@ -125,12 +125,13 @@ _GLOBAL(load_up_altivec)
125 oris r12,r12,MSR_VEC@h 125 oris r12,r12,MSR_VEC@h
126 std r12,_MSR(r1) 126 std r12,_MSR(r1)
127#endif 127#endif
128 addi r7,r5,THREAD_VRSTATE
128 li r4,1 129 li r4,1
129 li r10,THREAD_VSCR 130 li r10,VRSTATE_VSCR
130 stw r4,THREAD_USED_VR(r5) 131 stw r4,THREAD_USED_VR(r5)
131 lvx vr0,r10,r5 132 lvx vr0,r10,r7
132 mtvscr vr0 133 mtvscr vr0
133 REST_32VRS(0,r4,r5) 134 REST_32VRS(0,r4,r7)
134#ifndef CONFIG_SMP 135#ifndef CONFIG_SMP
135 /* Update last_task_used_altivec to 'current' */ 136 /* Update last_task_used_altivec to 'current' */
136 subi r4,r5,THREAD /* Back to 'current' */ 137 subi r4,r5,THREAD /* Back to 'current' */
@@ -165,12 +166,16 @@ _GLOBAL(giveup_altivec)
165 PPC_LCMPI 0,r3,0 166 PPC_LCMPI 0,r3,0
166 beqlr /* if no previous owner, done */ 167 beqlr /* if no previous owner, done */
167 addi r3,r3,THREAD /* want THREAD of task */ 168 addi r3,r3,THREAD /* want THREAD of task */
169 PPC_LL r7,THREAD_VRSAVEAREA(r3)
168 PPC_LL r5,PT_REGS(r3) 170 PPC_LL r5,PT_REGS(r3)
169 PPC_LCMPI 0,r5,0 171 PPC_LCMPI 0,r7,0
170 SAVE_32VRS(0,r4,r3) 172 bne 2f
173 addi r7,r3,THREAD_VRSTATE
1742: PPC_LCMPI 0,r5,0
175 SAVE_32VRS(0,r4,r7)
171 mfvscr vr0 176 mfvscr vr0
172 li r4,THREAD_VSCR 177 li r4,VRSTATE_VSCR
173 stvx vr0,r4,r3 178 stvx vr0,r4,r7
174 beq 1f 179 beq 1f
175 PPC_LL r4,_MSR-STACK_FRAME_OVERHEAD(r5) 180 PPC_LL r4,_MSR-STACK_FRAME_OVERHEAD(r5)
176#ifdef CONFIG_VSX 181#ifdef CONFIG_VSX