aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/kernel/Makefile5
-rw-r--r--arch/powerpc/kernel/fpu.S31
-rw-r--r--arch/powerpc/kernel/misc_32.S27
-rw-r--r--arch/powerpc/kernel/misc_64.S19
-rw-r--r--arch/powerpc/kernel/process.c2
-rw-r--r--arch/powerpc/kernel/signal_32.c2
-rw-r--r--arch/powerpc/kernel/traps.c2
-rw-r--r--arch/ppc/kernel/align.c4
-rw-r--r--arch/ppc/kernel/misc.S27
-rw-r--r--arch/ppc/kernel/process.c2
-rw-r--r--arch/ppc/kernel/traps.c2
-rw-r--r--arch/ppc/math-emu/sfp-machine.h2
-rw-r--r--arch/ppc64/Kconfig3
-rw-r--r--arch/ppc64/Makefile1
-rw-r--r--arch/ppc64/kernel/align.c4
-rw-r--r--arch/ppc64/kernel/head.S59
-rw-r--r--arch/ppc64/kernel/misc.S51
-rw-r--r--arch/ppc64/kernel/signal.c2
-rw-r--r--include/asm-powerpc/processor.h11
-rw-r--r--include/asm-powerpc/system.h4
-rw-r--r--include/asm-ppc/system.h4
-rw-r--r--include/asm-ppc64/system.h4
22 files changed, 59 insertions, 209 deletions
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index a733347964a0..94cf917b7854 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -29,7 +29,6 @@ extra-$(CONFIG_44x) := head_44x.o
29extra-$(CONFIG_FSL_BOOKE) := head_fsl_booke.o 29extra-$(CONFIG_FSL_BOOKE) := head_fsl_booke.o
30extra-$(CONFIG_8xx) := head_8xx.o 30extra-$(CONFIG_8xx) := head_8xx.o
31extra-$(CONFIG_PPC64) += entry_64.o 31extra-$(CONFIG_PPC64) += entry_64.o
32extra-$(CONFIG_PPC_FPU) += fpu.o
33extra-y += vmlinux.lds 32extra-y += vmlinux.lds
34 33
35obj-y += process.o init_task.o time.o \ 34obj-y += process.o init_task.o time.o \
@@ -49,7 +48,7 @@ else
49# stuff used from here for ARCH=ppc or ARCH=ppc64 48# stuff used from here for ARCH=ppc or ARCH=ppc64
50obj-$(CONFIG_PPC64) += traps.o process.o init_task.o time.o 49obj-$(CONFIG_PPC64) += traps.o process.o init_task.o time.o
51 50
52fpux-$(CONFIG_PPC32) += fpu.o
53extra-$(CONFIG_PPC_FPU) += $(fpux-y)
54 51
55endif 52endif
53
54extra-$(CONFIG_PPC_FPU) += fpu.o
diff --git a/arch/powerpc/kernel/fpu.S b/arch/powerpc/kernel/fpu.S
index 563d445ff584..51fd78da25b7 100644
--- a/arch/powerpc/kernel/fpu.S
+++ b/arch/powerpc/kernel/fpu.S
@@ -48,7 +48,7 @@ _GLOBAL(load_up_fpu)
48 addi r4,r4,THREAD /* want last_task_used_math->thread */ 48 addi r4,r4,THREAD /* want last_task_used_math->thread */
49 SAVE_32FPRS(0, r4) 49 SAVE_32FPRS(0, r4)
50 mffs fr0 50 mffs fr0
51 stfd fr0,THREAD_FPSCR-4(r4) 51 stfd fr0,THREAD_FPSCR(r4)
52 LDL r5,PT_REGS(r4) 52 LDL r5,PT_REGS(r4)
53 tophys(r5,r5) 53 tophys(r5,r5)
54 LDL r4,_MSR-STACK_FRAME_OVERHEAD(r5) 54 LDL r4,_MSR-STACK_FRAME_OVERHEAD(r5)
@@ -71,7 +71,7 @@ _GLOBAL(load_up_fpu)
71 or r12,r12,r4 71 or r12,r12,r4
72 std r12,_MSR(r1) 72 std r12,_MSR(r1)
73#endif 73#endif
74 lfd fr0,THREAD_FPSCR-4(r5) 74 lfd fr0,THREAD_FPSCR(r5)
75 mtfsf 0xff,fr0 75 mtfsf 0xff,fr0
76 REST_32FPRS(0, r5) 76 REST_32FPRS(0, r5)
77#ifndef CONFIG_SMP 77#ifndef CONFIG_SMP
@@ -104,7 +104,7 @@ _GLOBAL(giveup_fpu)
104 CMPI 0,r5,0 104 CMPI 0,r5,0
105 SAVE_32FPRS(0, r3) 105 SAVE_32FPRS(0, r3)
106 mffs fr0 106 mffs fr0
107 stfd fr0,THREAD_FPSCR-4(r3) 107 stfd fr0,THREAD_FPSCR(r3)
108 beq 1f 108 beq 1f
109 LDL r4,_MSR-STACK_FRAME_OVERHEAD(r5) 109 LDL r4,_MSR-STACK_FRAME_OVERHEAD(r5)
110 li r3,MSR_FP|MSR_FE0|MSR_FE1 110 li r3,MSR_FP|MSR_FE0|MSR_FE1
@@ -117,3 +117,28 @@ _GLOBAL(giveup_fpu)
117 STL r5,OFF(last_task_used_math)(r4) 117 STL r5,OFF(last_task_used_math)(r4)
118#endif /* CONFIG_SMP */ 118#endif /* CONFIG_SMP */
119 blr 119 blr
120
121/*
122 * These are used in the alignment trap handler when emulating
123 * single-precision loads and stores.
124 * We restore and save the fpscr so the task gets the same result
125 * and exceptions as if the cpu had performed the load or store.
126 */
127
128_GLOBAL(cvt_fd)
129 lfd 0,THREAD_FPSCR(r5) /* load up fpscr value */
130 mtfsf 0xff,0
131 lfs 0,0(r3)
132 stfd 0,0(r4)
133 mffs 0
134 stfd 0,THREAD_FPSCR(r5) /* save new fpscr value */
135 blr
136
137_GLOBAL(cvt_df)
138 lfd 0,THREAD_FPSCR(r5) /* load up fpscr value */
139 mtfsf 0xff,0
140 lfd 0,0(r3)
141 stfs 0,0(r4)
142 mffs 0
143 stfd 0,THREAD_FPSCR(r5) /* save new fpscr value */
144 blr
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S
index 303229b090b8..3bedb532aed9 100644
--- a/arch/powerpc/kernel/misc_32.S
+++ b/arch/powerpc/kernel/misc_32.S
@@ -993,33 +993,6 @@ _GLOBAL(_get_SP)
993 blr 993 blr
994 994
995/* 995/*
996 * These are used in the alignment trap handler when emulating
997 * single-precision loads and stores.
998 * We restore and save the fpscr so the task gets the same result
999 * and exceptions as if the cpu had performed the load or store.
1000 */
1001
1002#ifdef CONFIG_PPC_FPU
1003_GLOBAL(cvt_fd)
1004 lfd 0,-4(r5) /* load up fpscr value */
1005 mtfsf 0xff,0
1006 lfs 0,0(r3)
1007 stfd 0,0(r4)
1008 mffs 0 /* save new fpscr value */
1009 stfd 0,-4(r5)
1010 blr
1011
1012_GLOBAL(cvt_df)
1013 lfd 0,-4(r5) /* load up fpscr value */
1014 mtfsf 0xff,0
1015 lfd 0,0(r3)
1016 stfs 0,0(r4)
1017 mffs 0 /* save new fpscr value */
1018 stfd 0,-4(r5)
1019 blr
1020#endif
1021
1022/*
1023 * Create a kernel thread 996 * Create a kernel thread
1024 * kernel_thread(fn, arg, flags) 997 * kernel_thread(fn, arg, flags)
1025 */ 998 */
diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S
index 4775bed42cac..b3e95ff0dba0 100644
--- a/arch/powerpc/kernel/misc_64.S
+++ b/arch/powerpc/kernel/misc_64.S
@@ -462,25 +462,6 @@ _GLOBAL(_outsl_ns)
462 sync 462 sync
463 blr 463 blr
464 464
465
466_GLOBAL(cvt_fd)
467 lfd 0,0(r5) /* load up fpscr value */
468 mtfsf 0xff,0
469 lfs 0,0(r3)
470 stfd 0,0(r4)
471 mffs 0 /* save new fpscr value */
472 stfd 0,0(r5)
473 blr
474
475_GLOBAL(cvt_df)
476 lfd 0,0(r5) /* load up fpscr value */
477 mtfsf 0xff,0
478 lfd 0,0(r3)
479 stfs 0,0(r4)
480 mffs 0 /* save new fpscr value */
481 stfd 0,0(r5)
482 blr
483
484/* 465/*
485 * identify_cpu and calls setup_cpu 466 * identify_cpu and calls setup_cpu
486 * In: r3 = base of the cpu_specs array 467 * In: r3 = base of the cpu_specs array
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 047da1ae21fe..8f85dabe4df3 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -665,7 +665,7 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp)
665#endif 665#endif
666#endif /* CONFIG_SMP */ 666#endif /* CONFIG_SMP */
667 memset(current->thread.fpr, 0, sizeof(current->thread.fpr)); 667 memset(current->thread.fpr, 0, sizeof(current->thread.fpr));
668 current->thread.fpscr = 0; 668 current->thread.fpscr.val = 0;
669#ifdef CONFIG_ALTIVEC 669#ifdef CONFIG_ALTIVEC
670 memset(current->thread.vr, 0, sizeof(current->thread.vr)); 670 memset(current->thread.vr, 0, sizeof(current->thread.vr));
671 memset(&current->thread.vscr, 0, sizeof(current->thread.vscr)); 671 memset(&current->thread.vscr, 0, sizeof(current->thread.vscr));
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index 92452b2db26a..444c3e81884c 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -403,7 +403,7 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
403 ELF_NFPREG * sizeof(double))) 403 ELF_NFPREG * sizeof(double)))
404 return 1; 404 return 1;
405 405
406 current->thread.fpscr = 0; /* turn off all fp exceptions */ 406 current->thread.fpscr.val = 0; /* turn off all fp exceptions */
407 407
408#ifdef CONFIG_ALTIVEC 408#ifdef CONFIG_ALTIVEC
409 /* save altivec registers */ 409 /* save altivec registers */
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index f87580382da4..5d638ecddbd0 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -549,7 +549,7 @@ static void parse_fpe(struct pt_regs *regs)
549 549
550 flush_fp_to_thread(current); 550 flush_fp_to_thread(current);
551 551
552 fpscr = current->thread.fpscr; 552 fpscr = current->thread.fpscr.val;
553 553
554 /* Invalid operation */ 554 /* Invalid operation */
555 if ((fpscr & FPSCR_VE) && (fpscr & FPSCR_VX)) 555 if ((fpscr & FPSCR_VE) && (fpscr & FPSCR_VX))
diff --git a/arch/ppc/kernel/align.c b/arch/ppc/kernel/align.c
index ff81da9598d8..ab398c4b70b6 100644
--- a/arch/ppc/kernel/align.c
+++ b/arch/ppc/kernel/align.c
@@ -375,7 +375,7 @@ fix_alignment(struct pt_regs *regs)
375#ifdef CONFIG_PPC_FPU 375#ifdef CONFIG_PPC_FPU
376 preempt_disable(); 376 preempt_disable();
377 enable_kernel_fp(); 377 enable_kernel_fp();
378 cvt_fd(&data.f, &data.d, &current->thread.fpscr); 378 cvt_fd(&data.f, &data.d, &current->thread);
379 preempt_enable(); 379 preempt_enable();
380#else 380#else
381 return 0; 381 return 0;
@@ -385,7 +385,7 @@ fix_alignment(struct pt_regs *regs)
385#ifdef CONFIG_PPC_FPU 385#ifdef CONFIG_PPC_FPU
386 preempt_disable(); 386 preempt_disable();
387 enable_kernel_fp(); 387 enable_kernel_fp();
388 cvt_df(&data.d, &data.f, &current->thread.fpscr); 388 cvt_df(&data.d, &data.f, &current->thread);
389 preempt_enable(); 389 preempt_enable();
390#else 390#else
391 return 0; 391 return 0;
diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S
index 2350f3e09f95..3056ede2424d 100644
--- a/arch/ppc/kernel/misc.S
+++ b/arch/ppc/kernel/misc.S
@@ -968,33 +968,6 @@ _GLOBAL(_get_SP)
968 blr 968 blr
969 969
970/* 970/*
971 * These are used in the alignment trap handler when emulating
972 * single-precision loads and stores.
973 * We restore and save the fpscr so the task gets the same result
974 * and exceptions as if the cpu had performed the load or store.
975 */
976
977#ifdef CONFIG_PPC_FPU
978_GLOBAL(cvt_fd)
979 lfd 0,-4(r5) /* load up fpscr value */
980 mtfsf 0xff,0
981 lfs 0,0(r3)
982 stfd 0,0(r4)
983 mffs 0 /* save new fpscr value */
984 stfd 0,-4(r5)
985 blr
986
987_GLOBAL(cvt_df)
988 lfd 0,-4(r5) /* load up fpscr value */
989 mtfsf 0xff,0
990 lfd 0,0(r3)
991 stfs 0,0(r4)
992 mffs 0 /* save new fpscr value */
993 stfd 0,-4(r5)
994 blr
995#endif
996
997/*
998 * Create a kernel thread 971 * Create a kernel thread
999 * kernel_thread(fn, arg, flags) 972 * kernel_thread(fn, arg, flags)
1000 */ 973 */
diff --git a/arch/ppc/kernel/process.c b/arch/ppc/kernel/process.c
index 6d60c40598e7..78ea10197a0b 100644
--- a/arch/ppc/kernel/process.c
+++ b/arch/ppc/kernel/process.c
@@ -542,7 +542,7 @@ void start_thread(struct pt_regs *regs, unsigned long nip, unsigned long sp)
542 last_task_used_spe = NULL; 542 last_task_used_spe = NULL;
543#endif 543#endif
544 memset(current->thread.fpr, 0, sizeof(current->thread.fpr)); 544 memset(current->thread.fpr, 0, sizeof(current->thread.fpr));
545 current->thread.fpscr = 0; 545 current->thread.fpscr.val = 0;
546#ifdef CONFIG_ALTIVEC 546#ifdef CONFIG_ALTIVEC
547 memset(current->thread.vr, 0, sizeof(current->thread.vr)); 547 memset(current->thread.vr, 0, sizeof(current->thread.vr));
548 memset(&current->thread.vscr, 0, sizeof(current->thread.vscr)); 548 memset(&current->thread.vscr, 0, sizeof(current->thread.vscr));
diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c
index 5e4bf88a1ef5..f265b81e7008 100644
--- a/arch/ppc/kernel/traps.c
+++ b/arch/ppc/kernel/traps.c
@@ -659,7 +659,7 @@ void program_check_exception(struct pt_regs *regs)
659 giveup_fpu(current); 659 giveup_fpu(current);
660 preempt_enable(); 660 preempt_enable();
661 661
662 fpscr = current->thread.fpscr; 662 fpscr = current->thread.fpscr.val;
663 fpscr &= fpscr << 22; /* mask summary bits with enables */ 663 fpscr &= fpscr << 22; /* mask summary bits with enables */
664 if (fpscr & FPSCR_VX) 664 if (fpscr & FPSCR_VX)
665 code = FPE_FLTINV; 665 code = FPE_FLTINV;
diff --git a/arch/ppc/math-emu/sfp-machine.h b/arch/ppc/math-emu/sfp-machine.h
index 686e06d29186..4b17d83cfcdd 100644
--- a/arch/ppc/math-emu/sfp-machine.h
+++ b/arch/ppc/math-emu/sfp-machine.h
@@ -166,7 +166,7 @@ extern int fp_pack_ds(void *, long, unsigned long, unsigned long, long, long);
166#include <linux/kernel.h> 166#include <linux/kernel.h>
167#include <linux/sched.h> 167#include <linux/sched.h>
168 168
169#define __FPU_FPSCR (current->thread.fpscr) 169#define __FPU_FPSCR (current->thread.fpscr.val)
170 170
171/* We only actually write to the destination register 171/* We only actually write to the destination register
172 * if exceptions signalled (if any) will not trap. 172 * if exceptions signalled (if any) will not trap.
diff --git a/arch/ppc64/Kconfig b/arch/ppc64/Kconfig
index 8cc73cc1b4c4..b889277ab7de 100644
--- a/arch/ppc64/Kconfig
+++ b/arch/ppc64/Kconfig
@@ -197,6 +197,9 @@ config BOOTX_TEXT
197config POWER4 197config POWER4
198 def_bool y 198 def_bool y
199 199
200config PPC_FPU
201 def_bool y
202
200config POWER4_ONLY 203config POWER4_ONLY
201 bool "Optimize for POWER4" 204 bool "Optimize for POWER4"
202 default n 205 default n
diff --git a/arch/ppc64/Makefile b/arch/ppc64/Makefile
index 4d18bdb680f0..ba59225fd373 100644
--- a/arch/ppc64/Makefile
+++ b/arch/ppc64/Makefile
@@ -80,6 +80,7 @@ endif
80CFLAGS += $(call cc-option,-funit-at-a-time) 80CFLAGS += $(call cc-option,-funit-at-a-time)
81 81
82head-y := arch/ppc64/kernel/head.o 82head-y := arch/ppc64/kernel/head.o
83head-y += arch/powerpc/kernel/fpu.o
83 84
84libs-y += arch/ppc64/lib/ 85libs-y += arch/ppc64/lib/
85core-y += arch/ppc64/kernel/ arch/powerpc/kernel/ 86core-y += arch/ppc64/kernel/ arch/powerpc/kernel/
diff --git a/arch/ppc64/kernel/align.c b/arch/ppc64/kernel/align.c
index 330e7ef81427..256d5b592aa1 100644
--- a/arch/ppc64/kernel/align.c
+++ b/arch/ppc64/kernel/align.c
@@ -313,7 +313,7 @@ fix_alignment(struct pt_regs *regs)
313 /* Doing stfs, have to convert to single */ 313 /* Doing stfs, have to convert to single */
314 preempt_disable(); 314 preempt_disable();
315 enable_kernel_fp(); 315 enable_kernel_fp();
316 cvt_df(&current->thread.fpr[reg], (float *)&data.v[4], &current->thread.fpscr); 316 cvt_df(&current->thread.fpr[reg], (float *)&data.v[4], &current->thread);
317 disable_kernel_fp(); 317 disable_kernel_fp();
318 preempt_enable(); 318 preempt_enable();
319 } 319 }
@@ -349,7 +349,7 @@ fix_alignment(struct pt_regs *regs)
349 /* Doing lfs, have to convert to double */ 349 /* Doing lfs, have to convert to double */
350 preempt_disable(); 350 preempt_disable();
351 enable_kernel_fp(); 351 enable_kernel_fp();
352 cvt_fd((float *)&data.v[4], &current->thread.fpr[reg], &current->thread.fpscr); 352 cvt_fd((float *)&data.v[4], &current->thread.fpr[reg], &current->thread);
353 disable_kernel_fp(); 353 disable_kernel_fp();
354 preempt_enable(); 354 preempt_enable();
355 } 355 }
diff --git a/arch/ppc64/kernel/head.S b/arch/ppc64/kernel/head.S
index f58af9c246cb..929f9f42cf7a 100644
--- a/arch/ppc64/kernel/head.S
+++ b/arch/ppc64/kernel/head.S
@@ -81,7 +81,7 @@ _stext:
81_GLOBAL(__start) 81_GLOBAL(__start)
82 /* NOP this out unconditionally */ 82 /* NOP this out unconditionally */
83BEGIN_FTR_SECTION 83BEGIN_FTR_SECTION
84 b .__start_initialization_multiplatform 84 b .__start_initialization_multiplatform
85END_FTR_SECTION(0, 1) 85END_FTR_SECTION(0, 1)
86#endif /* CONFIG_PPC_MULTIPLATFORM */ 86#endif /* CONFIG_PPC_MULTIPLATFORM */
87 87
@@ -747,6 +747,7 @@ bad_stack:
747 * any task or sent any task a signal, you should use 747 * any task or sent any task a signal, you should use
748 * ret_from_except or ret_from_except_lite instead of this. 748 * ret_from_except or ret_from_except_lite instead of this.
749 */ 749 */
750 .globl fast_exception_return
750fast_exception_return: 751fast_exception_return:
751 ld r12,_MSR(r1) 752 ld r12,_MSR(r1)
752 ld r11,_NIP(r1) 753 ld r11,_NIP(r1)
@@ -858,62 +859,6 @@ fp_unavailable_common:
858 bl .kernel_fp_unavailable_exception 859 bl .kernel_fp_unavailable_exception
859 BUG_OPCODE 860 BUG_OPCODE
860 861
861/*
862 * load_up_fpu(unused, unused, tsk)
863 * Disable FP for the task which had the FPU previously,
864 * and save its floating-point registers in its thread_struct.
865 * Enables the FPU for use in the kernel on return.
866 * On SMP we know the fpu is free, since we give it up every
867 * switch (ie, no lazy save of the FP registers).
868 * On entry: r13 == 'current' && last_task_used_math != 'current'
869 */
870_STATIC(load_up_fpu)
871 mfmsr r5 /* grab the current MSR */
872 ori r5,r5,MSR_FP
873 mtmsrd r5 /* enable use of fpu now */
874 isync
875/*
876 * For SMP, we don't do lazy FPU switching because it just gets too
877 * horrendously complex, especially when a task switches from one CPU
878 * to another. Instead we call giveup_fpu in switch_to.
879 *
880 */
881#ifndef CONFIG_SMP
882 ld r3,last_task_used_math@got(r2)
883 ld r4,0(r3)
884 cmpdi 0,r4,0
885 beq 1f
886 /* Save FP state to last_task_used_math's THREAD struct */
887 addi r4,r4,THREAD
888 SAVE_32FPRS(0, r4)
889 mffs fr0
890 stfd fr0,THREAD_FPSCR(r4)
891 /* Disable FP for last_task_used_math */
892 ld r5,PT_REGS(r4)
893 ld r4,_MSR-STACK_FRAME_OVERHEAD(r5)
894 li r6,MSR_FP|MSR_FE0|MSR_FE1
895 andc r4,r4,r6
896 std r4,_MSR-STACK_FRAME_OVERHEAD(r5)
8971:
898#endif /* CONFIG_SMP */
899 /* enable use of FP after return */
900 ld r4,PACACURRENT(r13)
901 addi r5,r4,THREAD /* Get THREAD */
902 ld r4,THREAD_FPEXC_MODE(r5)
903 ori r12,r12,MSR_FP
904 or r12,r12,r4
905 std r12,_MSR(r1)
906 lfd fr0,THREAD_FPSCR(r5)
907 mtfsf 0xff,fr0
908 REST_32FPRS(0, r5)
909#ifndef CONFIG_SMP
910 /* Update last_task_used_math to 'current' */
911 subi r4,r5,THREAD /* Back to 'current' */
912 std r4,0(r3)
913#endif /* CONFIG_SMP */
914 /* restore registers and return */
915 b fast_exception_return
916
917 .align 7 862 .align 7
918 .globl altivec_unavailable_common 863 .globl altivec_unavailable_common
919altivec_unavailable_common: 864altivec_unavailable_common:
diff --git a/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S
index a33448c2bd91..9cae3d5c40e6 100644
--- a/arch/ppc64/kernel/misc.S
+++ b/arch/ppc64/kernel/misc.S
@@ -451,25 +451,6 @@ _GLOBAL(_outsl_ns)
451 sync 451 sync
452 blr 452 blr
453 453
454
455_GLOBAL(cvt_fd)
456 lfd 0,0(r5) /* load up fpscr value */
457 mtfsf 0xff,0
458 lfs 0,0(r3)
459 stfd 0,0(r4)
460 mffs 0 /* save new fpscr value */
461 stfd 0,0(r5)
462 blr
463
464_GLOBAL(cvt_df)
465 lfd 0,0(r5) /* load up fpscr value */
466 mtfsf 0xff,0
467 lfd 0,0(r3)
468 stfs 0,0(r4)
469 mffs 0 /* save new fpscr value */
470 stfd 0,0(r5)
471 blr
472
473/* 454/*
474 * identify_cpu and calls setup_cpu 455 * identify_cpu and calls setup_cpu
475 * In: r3 = base of the cpu_specs array 456 * In: r3 = base of the cpu_specs array
@@ -655,38 +636,6 @@ _GLOBAL(disable_kernel_fp)
655 isync 636 isync
656 blr 637 blr
657 638
658/*
659 * giveup_fpu(tsk)
660 * Disable FP for the task given as the argument,
661 * and save the floating-point registers in its thread_struct.
662 * Enables the FPU for use in the kernel on return.
663 */
664_GLOBAL(giveup_fpu)
665 mfmsr r5
666 ori r5,r5,MSR_FP
667 mtmsrd r5 /* enable use of fpu now */
668 isync
669 cmpdi 0,r3,0
670 beqlr- /* if no previous owner, done */
671 addi r3,r3,THREAD /* want THREAD of task */
672 ld r5,PT_REGS(r3)
673 cmpdi 0,r5,0
674 SAVE_32FPRS(0, r3)
675 mffs fr0
676 stfd fr0,THREAD_FPSCR(r3)
677 beq 1f
678 ld r4,_MSR-STACK_FRAME_OVERHEAD(r5)
679 li r3,MSR_FP|MSR_FE0|MSR_FE1
680 andc r4,r4,r3 /* disable FP for previous task */
681 std r4,_MSR-STACK_FRAME_OVERHEAD(r5)
6821:
683#ifndef CONFIG_SMP
684 li r5,0
685 ld r4,last_task_used_math@got(r2)
686 std r5,0(r4)
687#endif /* CONFIG_SMP */
688 blr
689
690#ifdef CONFIG_ALTIVEC 639#ifdef CONFIG_ALTIVEC
691 640
692#if 0 /* this has no callers for now */ 641#if 0 /* this has no callers for now */
diff --git a/arch/ppc64/kernel/signal.c b/arch/ppc64/kernel/signal.c
index 347112cca3c0..ec9d0984b6a0 100644
--- a/arch/ppc64/kernel/signal.c
+++ b/arch/ppc64/kernel/signal.c
@@ -133,7 +133,7 @@ static long setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
133 flush_fp_to_thread(current); 133 flush_fp_to_thread(current);
134 134
135 /* Make sure signal doesn't get spurrious FP exceptions */ 135 /* Make sure signal doesn't get spurrious FP exceptions */
136 current->thread.fpscr = 0; 136 current->thread.fpscr.val = 0;
137 137
138#ifdef CONFIG_ALTIVEC 138#ifdef CONFIG_ALTIVEC
139 err |= __put_user(v_regs, &sc->v_regs); 139 err |= __put_user(v_regs, &sc->v_regs);
diff --git a/include/asm-powerpc/processor.h b/include/asm-powerpc/processor.h
index 9592f533e058..eee954a001fd 100644
--- a/include/asm-powerpc/processor.h
+++ b/include/asm-powerpc/processor.h
@@ -162,10 +162,11 @@ struct thread_struct {
162 unsigned long dbcr1; 162 unsigned long dbcr1;
163#endif 163#endif
164 double fpr[32]; /* Complete floating point set */ 164 double fpr[32]; /* Complete floating point set */
165#ifdef CONFIG_PPC32 165 struct { /* fpr ... fpscr must be contiguous */
166 unsigned long fpscr_pad; /* fpr ... fpscr must be contiguous */ 166
167#endif 167 unsigned int pad;
168 unsigned long fpscr; /* Floating point status */ 168 unsigned int val; /* Floating point status */
169 } fpscr;
169 int fpexc_mode; /* floating-point exception mode */ 170 int fpexc_mode; /* floating-point exception mode */
170#ifdef CONFIG_PPC64 171#ifdef CONFIG_PPC64
171 unsigned long start_tb; /* Start purr when proc switched in */ 172 unsigned long start_tb; /* Start purr when proc switched in */
@@ -207,7 +208,7 @@ struct thread_struct {
207 .regs = (struct pt_regs *)INIT_SP - 1, /* XXX bogus, I think */ \ 208 .regs = (struct pt_regs *)INIT_SP - 1, /* XXX bogus, I think */ \
208 .fs = KERNEL_DS, \ 209 .fs = KERNEL_DS, \
209 .fpr = {0}, \ 210 .fpr = {0}, \
210 .fpscr = 0, \ 211 .fpscr = { .val = 0, }, \
211 .fpexc_mode = MSR_FE0|MSR_FE1, \ 212 .fpexc_mode = MSR_FE0|MSR_FE1, \
212} 213}
213#endif 214#endif
diff --git a/include/asm-powerpc/system.h b/include/asm-powerpc/system.h
index d60c8c928922..e926e43c4ae6 100644
--- a/include/asm-powerpc/system.h
+++ b/include/asm-powerpc/system.h
@@ -132,8 +132,8 @@ extern int emulate_altivec(struct pt_regs *);
132extern void giveup_spe(struct task_struct *); 132extern void giveup_spe(struct task_struct *);
133extern void load_up_spe(struct task_struct *); 133extern void load_up_spe(struct task_struct *);
134extern int fix_alignment(struct pt_regs *); 134extern int fix_alignment(struct pt_regs *);
135extern void cvt_fd(float *from, double *to, unsigned long *fpscr); 135extern void cvt_fd(float *from, double *to, struct thread_struct *thread);
136extern void cvt_df(double *from, float *to, unsigned long *fpscr); 136extern void cvt_df(double *from, float *to, struct thread_struct *thread);
137 137
138#ifdef CONFIG_ALTIVEC 138#ifdef CONFIG_ALTIVEC
139extern void flush_altivec_to_thread(struct task_struct *); 139extern void flush_altivec_to_thread(struct task_struct *);
diff --git a/include/asm-ppc/system.h b/include/asm-ppc/system.h
index 1f310783757e..eb30c09516ae 100644
--- a/include/asm-ppc/system.h
+++ b/include/asm-ppc/system.h
@@ -82,8 +82,8 @@ extern int emulate_altivec(struct pt_regs *);
82extern void giveup_spe(struct task_struct *); 82extern void giveup_spe(struct task_struct *);
83extern void load_up_spe(struct task_struct *); 83extern void load_up_spe(struct task_struct *);
84extern int fix_alignment(struct pt_regs *); 84extern int fix_alignment(struct pt_regs *);
85extern void cvt_fd(float *from, double *to, unsigned long *fpscr); 85extern void cvt_fd(float *from, double *to, struct thread_struct *thread);
86extern void cvt_df(double *from, float *to, unsigned long *fpscr); 86extern void cvt_df(double *from, float *to, struct thread_struct *thread);
87 87
88#ifdef CONFIG_ALTIVEC 88#ifdef CONFIG_ALTIVEC
89extern void flush_altivec_to_thread(struct task_struct *); 89extern void flush_altivec_to_thread(struct task_struct *);
diff --git a/include/asm-ppc64/system.h b/include/asm-ppc64/system.h
index 2e17ef7dbeb4..fd7c1f890c45 100644
--- a/include/asm-ppc64/system.h
+++ b/include/asm-ppc64/system.h
@@ -120,8 +120,8 @@ extern void giveup_altivec(struct task_struct *);
120extern void disable_kernel_altivec(void); 120extern void disable_kernel_altivec(void);
121extern void enable_kernel_altivec(void); 121extern void enable_kernel_altivec(void);
122extern int emulate_altivec(struct pt_regs *); 122extern int emulate_altivec(struct pt_regs *);
123extern void cvt_fd(float *from, double *to, unsigned long *fpscr); 123extern void cvt_fd(float *from, double *to, struct thread_struct *thread);
124extern void cvt_df(double *from, float *to, unsigned long *fpscr); 124extern void cvt_df(double *from, float *to, struct thread_struct *thread);
125 125
126#ifdef CONFIG_ALTIVEC 126#ifdef CONFIG_ALTIVEC
127extern void flush_altivec_to_thread(struct task_struct *); 127extern void flush_altivec_to_thread(struct task_struct *);