summaryrefslogtreecommitdiffstats
path: root/arch/mips64
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips64')
-rw-r--r--arch/mips64/kernel/process.c11
-rw-r--r--arch/mips64/kernel/ptrace.c11
-rw-r--r--arch/mips64/kernel/signal.c9
-rw-r--r--arch/mips64/kernel/signal32.c10
-rw-r--r--arch/mips64/kernel/traps.c10
5 files changed, 36 insertions, 15 deletions
diff --git a/arch/mips64/kernel/process.c b/arch/mips64/kernel/process.c
index d6d8b7435..22ce0ed6d 100644
--- a/arch/mips64/kernel/process.c
+++ b/arch/mips64/kernel/process.c
@@ -7,6 +7,7 @@
* Copyright (C) 1994 - 1999 by Ralf Baechle and others.
* Copyright (C) 1999 Silicon Graphics, Inc.
*/
+#include <linux/config.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/kernel.h>
@@ -52,20 +53,20 @@ asmlinkage void ret_from_fork(void);
void exit_thread(void)
{
/* Forget lazy fpu state */
- if (last_task_used_math == current) {
+ if (IS_FPU_OWNER()) {
set_cp0_status(ST0_CU1, ST0_CU1);
__asm__ __volatile__("cfc1\t$0,$31");
- last_task_used_math = NULL;
+ CLEAR_FPU_OWNER();
}
}
void flush_thread(void)
{
/* Forget lazy fpu state */
- if (last_task_used_math == current) {
+ if (IS_FPU_OWNER()) {
set_cp0_status(ST0_CU1, ST0_CU1);
__asm__ __volatile__("cfc1\t$0,$31");
- last_task_used_math = NULL;
+ CLEAR_FPU_OWNER();
}
}
@@ -77,7 +78,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
childksp = (unsigned long)p + KERNEL_STACK_SIZE - 32;
- if (last_task_used_math == current) {
+ if (IS_FPU_OWNER()) {
save_fp(p);
}
/* set up new TSS. */
diff --git a/arch/mips64/kernel/ptrace.c b/arch/mips64/kernel/ptrace.c
index 0301a66a3..b79a61f0e 100644
--- a/arch/mips64/kernel/ptrace.c
+++ b/arch/mips64/kernel/ptrace.c
@@ -13,6 +13,7 @@
* At this time Linux/MIPS64 only supports syscall tracing, even for 32-bit
* binaries.
*/
+#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/mm.h>
@@ -36,7 +37,6 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
struct task_struct *child;
unsigned long flags;
int ret;
- extern void save_fp(void*);
lock_kernel();
#if 0
@@ -132,12 +132,14 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
break;
case FPR_BASE ... FPR_BASE + 31:
if (child->used_math) {
+#ifndef CONFIG_SMP
if (last_task_used_math == child) {
set_cp0_status(ST0_CU1, ST0_CU1);
save_fp(child);
set_cp0_status(ST0_CU1, 0);
last_task_used_math = NULL;
}
+#endif
tmp = child->thread.fpu.hard.fp_regs[addr - 32];
} else {
tmp = -EIO;
@@ -199,6 +201,7 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
case FPR_BASE ... FPR_BASE + 31: {
unsigned long *fregs;
if (child->used_math) {
+#ifndef CONFIG_SMP
if (last_task_used_math == child) {
set_cp0_status(ST0_CU1, ST0_CU1);
save_fp(child);
@@ -206,6 +209,7 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
last_task_used_math = NULL;
regs->cp0_status &= ~ST0_CU1;
}
+#endif
} else {
/* FP not yet used */
memset(&child->thread.fpu.hard, ~0,
@@ -293,7 +297,6 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
struct task_struct *child;
unsigned long flags;
int ret;
- extern void save_fp(void*);
lock_kernel();
#if 0
@@ -389,12 +392,14 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
break;
case FPR_BASE ... FPR_BASE + 31:
if (child->used_math) {
+#ifndef CONFIG_SMP
if (last_task_used_math == child) {
set_cp0_status(ST0_CU1, ST0_CU1);
save_fp(child);
set_cp0_status(ST0_CU1, 0);
last_task_used_math = NULL;
}
+#endif
tmp = child->thread.fpu.hard.fp_regs[addr - 32];
} else {
tmp = -EIO;
@@ -456,6 +461,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
case FPR_BASE ... FPR_BASE + 31: {
unsigned long *fregs;
if (child->used_math) {
+#ifndef CONFIG_SMP
if (last_task_used_math == child) {
set_cp0_status(ST0_CU1, ST0_CU1);
save_fp(child);
@@ -463,6 +469,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
last_task_used_math = NULL;
regs->cp0_status &= ~ST0_CU1;
}
+#endif
} else {
/* FP not yet used */
memset(&child->thread.fpu.hard, ~0,
diff --git a/arch/mips64/kernel/signal.c b/arch/mips64/kernel/signal.c
index 40a727831..7f644a437 100644
--- a/arch/mips64/kernel/signal.c
+++ b/arch/mips64/kernel/signal.c
@@ -26,6 +26,7 @@
#include <asm/stackframe.h>
#include <asm/uaccess.h>
#include <asm/ucontext.h>
+#include <asm/system.h>
#define DEBUG_SIG 0
@@ -209,8 +210,8 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
err |= __get_user(owned_fp, &sc->sc_ownedfp);
if (owned_fp) {
- if (current == last_task_used_math) {
- last_task_used_math = 0;
+ if (IS_FPU_OWNER()) {
+ CLEAR_FPU_OWNER();
regs->cp0_status &= ~ST0_CU1;
}
current->used_math = 1;
@@ -338,9 +339,9 @@ setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
err |= __put_user(regs->cp0_badvaddr, &sc->sc_badvaddr);
if (current->used_math) { /* fp is active. */
- if (current == last_task_used_math) {
+ if (IS_FPU_OWNER()) {
lazy_fpu_switch(current, 0);
- last_task_used_math = NULL;
+ CLEAR_FPU_OWNER();
regs->cp0_status &= ~ST0_CU1;
}
err |= __put_user(1, &sc->sc_ownedfp);
diff --git a/arch/mips64/kernel/signal32.c b/arch/mips64/kernel/signal32.c
index 4addc707c..e33a69d5e 100644
--- a/arch/mips64/kernel/signal32.c
+++ b/arch/mips64/kernel/signal32.c
@@ -8,6 +8,7 @@
* Copyright (C) 1994 - 1999 Ralf Baechle
* Copyright (C) 1999 Silicon Graphics, Inc.
*/
+#include <linux/config.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
@@ -25,6 +26,7 @@
#include <asm/stackframe.h>
#include <asm/uaccess.h>
#include <asm/ucontext.h>
+#include <asm/system.h>
#define DEBUG_SIG 0
@@ -239,8 +241,8 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
err |= __get_user(owned_fp, &sc->sc_ownedfp);
if (owned_fp) {
- if (current == last_task_used_math) {
- last_task_used_math = 0;
+ if (IS_FPU_OWNER()) {
+ CLEAR_FPU_OWNER();
regs->cp0_status &= ~ST0_CU1;
}
current->used_math = 1;
@@ -373,9 +375,9 @@ setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
err |= __put_user(regs->cp0_badvaddr, &sc->sc_badvaddr);
if (current->used_math) { /* fp is active. */
- if (current == last_task_used_math) {
+ if (IS_FPU_OWNER()) {
lazy_fpu_switch(current, 0);
- last_task_used_math = NULL;
+ CLEAR_FPU_OWNER();
regs->cp0_status &= ~ST0_CU1;
}
err |= __put_user(1, &sc->sc_ownedfp);
diff --git a/arch/mips64/kernel/traps.c b/arch/mips64/kernel/traps.c
index 9f97fb0d8..fa58017cf 100644
--- a/arch/mips64/kernel/traps.c
+++ b/arch/mips64/kernel/traps.c
@@ -346,6 +346,7 @@ void do_cpu(struct pt_regs *regs)
goto bad_cid;
regs->cp0_status |= ST0_CU1;
+#ifndef CONFIG_SMP
if (last_task_used_math == current)
return;
@@ -357,6 +358,15 @@ void do_cpu(struct pt_regs *regs)
current->used_math = 1;
}
last_task_used_math = current;
+#else
+ if (current->used_math) {
+ lazy_fpu_switch(0, current);
+ } else {
+ init_fpu();
+ current->used_math = 1;
+ }
+ current->flags |= PF_USEDFPU;
+#endif
return;
bad_cid: