patch-2.4.19 linux-2.4.19/arch/mips64/kernel/ptrace.c

Next file: linux-2.4.19/arch/mips64/kernel/r4k_genex.S
Previous file: linux-2.4.19/arch/mips64/kernel/process.c
Back to the patch index
Back to the overall index

diff -urN linux-2.4.18/arch/mips64/kernel/ptrace.c linux-2.4.19/arch/mips64/kernel/ptrace.c
@@ -22,11 +22,13 @@
 #include <linux/smp_lock.h>
 #include <linux/user.h>
 
+#include <asm/cpu.h>
 #include <asm/mipsregs.h>
 #include <asm/pgtable.h>
 #include <asm/page.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
+#include <asm/bootinfo.h>
 
 /*
  * Called by kernel/ptrace.c when detaching..
@@ -75,15 +77,11 @@
 		ret = ptrace_attach(child);
 		goto out_tsk;
 	}
-	ret = -ESRCH;
-	if (!(child->ptrace & PT_PTRACED))
-		goto out_tsk;
-	if (child->state != TASK_STOPPED) {
-		if (request != PTRACE_KILL)
-			goto out_tsk;
-	}
-	if (child->p_pptr != current)
+
+	ret = ptrace_check_attach(child, request == PTRACE_KILL);
+	if (ret < 0)
 		goto out_tsk;
+
 	switch (request) {
 	/* when I and D space are separate, these will need to be fixed. */
 	case PTRACE_PEEKTEXT: /* read word at location addr. */ 
@@ -114,17 +112,23 @@
 			break;
 		case FPR_BASE ... FPR_BASE + 31:
 			if (child->used_math) {
-				unsigned long *fregs =
-					(void *) child->thread.fpu.hard.fp_regs;
-
+				unsigned long long *fregs
+					= (unsigned long long *)
+					    &child->thread.fpu.hard.fp_regs[0];
+				if (mips_cpu.options & MIPS_CPU_FPU) {
 #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;
-				}
+					if (last_task_used_math == child) {
+						__enable_fpu();
+						save_fp(child);
+						__disable_fpu();
+						last_task_used_math = NULL;
+					}
 #endif
+				} else {
+					fregs = (unsigned long long *)
+						child->thread.fpu.soft.regs;
+				}
+
 				/*
 				 * The odd registers are actually the high
 				 * order bits of the values stored in the even
@@ -154,12 +158,15 @@
 			tmp = regs->lo;
 			break;
 		case FPC_CSR:
-			tmp = child->thread.fpu.hard.control;
+			if (mips_cpu.options & MIPS_CPU_FPU)
+				tmp = child->thread.fpu.hard.control;
+			else
+				tmp = child->thread.fpu.soft.sr;
 			break;
 		case FPC_EIR: { /* implementation / version register */
 			unsigned int flags;
 			__save_flags(flags);
-			set_cp0_status(ST0_CU1, ST0_CU1);
+			__enable_fpu();
 			__asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp));
 			__restore_flags(flags);
 			break;
@@ -192,17 +199,21 @@
 			regs->regs[addr] = data;
 			break;
 		case FPR_BASE ... FPR_BASE + 31: {
-			unsigned long *fregs =
-				(void *) child->thread.fpu.hard.fp_regs;
+			unsigned long long *fregs;
+			fregs = (unsigned long long *)&child->thread.fpu.hard.fp_regs[0];
 			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;
-					regs->cp0_status &= ~ST0_CU1;
-				}
+				if (last_task_used_math == child) 
+					if (mips_cpu.options & MIPS_CPU_FPU) {
+						__enable_fpu();
+						save_fp(child);
+						__disable_fpu();
+						last_task_used_math = NULL;
+						regs->cp0_status &= ~ST0_CU1;
+					} else {
+						fregs = (unsigned long long *)
+						child->thread.fpu.soft.regs;
+					}
 #endif
 			} else {
 				/* FP not yet used  */
@@ -234,7 +245,10 @@
 			regs->lo = data;
 			break;
 		case FPC_CSR:
-			child->thread.fpu.hard.control = data;
+			if (mips_cpu.options & MIPS_CPU_FPU) 
+				child->thread.fpu.hard.control = data;
+			else
+				child->thread.fpu.soft.sr = data;
 			break;
 		default:
 			/* The rest are not allowed. */
@@ -334,14 +348,9 @@
 		ret = ptrace_attach(child);
 		goto out_tsk;
 	}
-	ret = -ESRCH;
-	if (!(child->ptrace & PT_PTRACED))
-		goto out_tsk;
-	if (child->state != TASK_STOPPED) {
-		if (request != PTRACE_KILL)
-			goto out_tsk;
-	}
-	if (child->p_pptr != current)
+
+	ret = ptrace_check_attach(child, request == PTRACE_KILL);
+	if (ret < 0)
 		goto out_tsk;
 
 	switch (request) {
@@ -377,14 +386,20 @@
 				unsigned long long *fregs
 					= (unsigned long long *)
 					&child->thread.fpu.hard.fp_regs[0];
+				if (mips_cpu.options & MIPS_CPU_FPU) {
 #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;
-				}
+					if (last_task_used_math == child) {
+						__enable_fpu();
+						save_fp(child);
+						__disable_fpu();
+						last_task_used_math = NULL;
+					}
 #endif
+				} else {
+					fregs = (unsigned long long *)
+						child->thread.fpu.soft.regs;
+				}
+
 				/*
 				 * The odd registers are actually the high
 				 * order bits of the values stored in the even
@@ -414,12 +429,15 @@
 			tmp = regs->lo;
 			break;
 		case FPC_CSR:
-			tmp = child->thread.fpu.hard.control;
+			if (mips_cpu.options & MIPS_CPU_FPU)
+				tmp = child->thread.fpu.hard.control;
+			else
+				tmp = child->thread.fpu.soft.sr;
 			break;
 		case FPC_EIR: { /* implementation / version register */
 			unsigned int flags;
 			__save_flags(flags);
-			set_cp0_status(ST0_CU1, ST0_CU1);
+			__enable_fpu();
 			__asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp));
 			__restore_flags(flags);
 			break;
@@ -452,16 +470,22 @@
 			regs->regs[addr] = data;
 			break;
 		case FPR_BASE ... FPR_BASE + 31: {
-			unsigned long *fregs =
-				(void *) child->thread.fpu.hard.fp_regs;
+			unsigned long long *fregs = (unsigned long long *)
+				&child->thread.fpu.hard.fp_regs[0];
+
 			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;
-					regs->cp0_status &= ~ST0_CU1;
+				if (mips_cpu.options & MIPS_CPU_FPU) {
+					if (last_task_used_math == child) {
+						__enable_fpu();
+						save_fp(child);
+						__disable_fpu();
+						last_task_used_math = NULL;
+						regs->cp0_status &= ~ST0_CU1;
+					} else {
+						fregs = (unsigned long long *)
+						child->thread.fpu.soft.regs;
+					}
 				}
 #endif
 			} else {
@@ -494,7 +518,10 @@
 			regs->lo = data;
 			break;
 		case FPC_CSR:
-			child->thread.fpu.hard.control = data;
+			if (mips_cpu.options & MIPS_CPU_FPU)
+				child->thread.fpu.hard.control = data;
+			else
+				child->thread.fpu.soft.sr = data;
 			break;
 		default:
 			/* The rest are not allowed. */

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)