--david
--- lia64/kernel/ptrace.c	Mon Jul 23 13:51:13 2001
+++ lia64-kdb/kernel/ptrace.c	Tue Sep  4 18:22:49 2001
@@ -60,6 +60,40 @@
 	return -EPERM;
 }
 
+long ptrace_freeze_child(struct task_struct *child, long request, unsigned long *freeze_info)
+{
+	unsigned long old_cpus_allowed;
+
+	if (request == PTRACE_KILL)
+		return 0;
+
+	if (child->state != TASK_STOPPED)
+		return -ESRCH;
+
+#ifdef CONFIG_SMP
+	while (child->has_cpu) {
+		if (child->state != TASK_STOPPED)
+			return -ESRCH;
+		barrier();
+	}
+#endif
+
+	old_cpus_allowed = xchg(&child->cpus_allowed, 0);
+
+	if (child->state != TASK_STOPPED) {
+		xchg(&child->cpus_allowed, old_cpus_allowed);
+		return -ESRCH;
+	}
+
+	*freeze_info = old_cpus_allowed;
+	return 0;
+}
+
+void ptrace_thaw_child(struct task_struct *child, long request, unsigned long freeze_info)
+{
+	if (request != PTRACE_KILL)
+		xchg(&child->cpus_allowed, freeze_info);
+}
 
 /*
  * Access another process' address space, one page at a time.
--- lia64/arch/ia64/kernel/ptrace.c	Mon Jul 23 13:50:57 2001
+++ lia64-kdb/arch/ia64/kernel/ptrace.c	Tue Sep  4 16:45:03 2001
@@ -794,7 +794,7 @@
 	    long arg4, long arg5, long arg6, long arg7, long stack)
 {
 	struct pt_regs *pt, *regs = (struct pt_regs *) &stack;
-	unsigned long flags, urbs_end;
+	unsigned long flags, urbs_end, freeze_info;
 	struct task_struct *child;
 	struct switch_stack *sw;
 	long ret;
@@ -840,6 +840,10 @@
 	if (child->p_pptr != current)
 		goto out_tsk;
 
+	ret = ptrace_freeze_child(child, request, &freeze_info);
+	if (ret < 0)
+		goto out_tsk;
+
 	pt = ia64_task_regs(child);
 	sw = (struct switch_stack *) (child->thread.ksp + 16);
 
@@ -856,7 +860,7 @@
 			ret = data;
 			regs->r8 = 0;	/* ensure "ret" is not mistaken as an error code */
 		}
-		goto out_tsk;
+		goto out_thaw;
 
 	      case PTRACE_POKETEXT:
 	      case PTRACE_POKEDATA:		/* write the word at location addr */
@@ -865,45 +869,45 @@
 			threads_sync_user_rbs(child, urbs_end, 1);
 
 		ret = ia64_poke(child, sw, urbs_end, addr, data);
-		goto out_tsk;
+		goto out_thaw;
 
 	      case PTRACE_PEEKUSR:		/* read the word at addr in the USER area */
 		if (access_uarea(child, addr, &data, 0) < 0) {
 			ret = -EIO;
-			goto out_tsk;
+			goto out_thaw;
 		}
 		ret = data;
 		regs->r8 = 0;	/* ensure "ret" is not mistaken as an error code */
-		goto out_tsk;
+		goto out_thaw;
 
 	      case PTRACE_POKEUSR:	      /* write the word at addr in the USER area */
 		if (access_uarea(child, addr, &data, 1) < 0) {
 			ret = -EIO;
-			goto out_tsk;
+			goto out_thaw;
 		}
 		ret = 0;
-		goto out_tsk;
+		goto out_thaw;
 
 	      case PTRACE_GETSIGINFO:
 		ret = -EIO;
 		if (!access_ok(VERIFY_WRITE, data, sizeof (siginfo_t)) || !child->thread.siginfo)
-			goto out_tsk;
+			goto out_thaw;
 		ret = copy_siginfo_to_user((siginfo_t *) data, child->thread.siginfo);
-		goto out_tsk;
+		goto out_thaw;
 
 	      case PTRACE_SETSIGINFO:
 		ret = -EIO;
 		if (!access_ok(VERIFY_READ, data, sizeof (siginfo_t))
 		    || child->thread.siginfo == 0)
-			goto out_tsk;
+			goto out_thaw;
 		ret = copy_siginfo_from_user(child->thread.siginfo, (siginfo_t *) data);
-		goto out_tsk;
+		goto out_thaw;
 
 	      case PTRACE_SYSCALL:	/* continue and stop at next (return from) syscall */
 	      case PTRACE_CONT:		/* restart after signal. */
 		ret = -EIO;
 		if (data > _NSIG)
-			goto out_tsk;
+			goto out_thaw;
 		if (request == PTRACE_SYSCALL)
 			child->ptrace |= PT_TRACESYS;
 		else
@@ -919,7 +923,7 @@
 
 		wake_up_process(child);
 		ret = 0;
-		goto out_tsk;
+		goto out_thaw;
 
 	      case PTRACE_KILL:
 		/*
@@ -928,7 +932,7 @@
 		 * that it wants to exit.
 		 */
 		if (child->state == TASK_ZOMBIE)		/* already dead */
-			goto out_tsk;
+			goto out_thaw;
 		child->exit_code = SIGKILL;
 
 		/* make sure the single step/take-branch tra bits are not set: */
@@ -940,13 +944,13 @@
 
 		wake_up_process(child);
 		ret = 0;
-		goto out_tsk;
+		goto out_thaw;
 
 	      case PTRACE_SINGLESTEP:		/* let child execute for one instruction */
 	      case PTRACE_SINGLEBLOCK:
 		ret = -EIO;
 		if (data > _NSIG)
-			goto out_tsk;
+			goto out_thaw;
 
 		child->ptrace &= ~PT_TRACESYS;
 		if (request == PTRACE_SINGLESTEP) {
@@ -962,12 +966,12 @@
 		/* give it a chance to run. */
 		wake_up_process(child);
 		ret = 0;
-		goto out_tsk;
+		goto out_thaw;
 
 	      case PTRACE_DETACH:		/* detach a process that was attached. */
 		ret = -EIO;
 		if (data > _NSIG)
-			goto out_tsk;
+			goto out_thaw;
 
 		child->ptrace &= ~(PT_PTRACED|PT_TRACESYS);
 		child->exit_code = data;
@@ -986,12 +990,14 @@
 
 		wake_up_process(child);
 		ret = 0;
-		goto out_tsk;
+		goto out_thaw;
 
 	      default:
 		ret = -EIO;
-		goto out_tsk;
+		goto out_thaw;
 	}
+  out_thaw:
+	ptrace_thaw_child(child, request, freeze_info);
   out_tsk:
 	free_task_struct(child);
   out:
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/