patch-2.1.124 linux/arch/i386/kernel/traps.c

Next file: linux/arch/ppc/8xx_io/Makefile
Previous file: linux/arch/i386/kernel/smp.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.123/linux/arch/i386/kernel/traps.c linux/arch/i386/kernel/traps.c
@@ -191,7 +191,7 @@
 	do_exit(SIGSEGV);
 }
 
-static void die_if_kernel(const char * str, struct pt_regs * regs, long err)
+static inline void die_if_kernel(const char * str, struct pt_regs * regs, long err)
 {
 	if (!(regs->eflags & VM_MASK) && !(3 & regs->xcs))
 		die(str, regs, err);
@@ -339,7 +339,16 @@
 
 	/* Mask out spurious TF errors due to lazy TF clearing */
 	if (condition & DR_STEP) {
-		if ((tsk->flags & PF_PTRACED) == 0)
+		/*
+		 * The TF error should be masked out only if the current
+		 * process is not traced and if the TRAP flag has been set
+		 * previously by a tracing process (condition detected by
+		 * the PF_DTRACE flag); remember that the i386 TRAP flag
+		 * can be modified by the process itself in user mode,
+		 * allowing programs to debug themselves without the ptrace()
+		 * interface.
+		 */
+		if ((tsk->flags & (PF_DTRACE|PF_PTRACED)) == PF_DTRACE)
 			goto clear_TF;
 	}
 
@@ -385,20 +394,15 @@
 {
 	struct task_struct * task;
 
-	lock_kernel();
-	clts();
-	task = current;
 	/*
-	 *	Save the info for the exception handler
+	 * Save the info for the exception handler
+	 * (this will also clear the error)
 	 */
-	__asm__ __volatile__("fnsave %0":"=m" (task->tss.i387.hard));
-	task->flags&=~PF_USEDFPU;
-	stts();
-
+	task = current;
+	save_fpu(task);
 	task->tss.trap_no = 16;
 	task->tss.error_code = 0;
 	force_sig(SIGFPE, task);
-	unlock_kernel();
 }
 
 asmlinkage void do_coprocessor_error(struct pt_regs * regs, long error_code)
@@ -423,19 +427,9 @@
  * Careful.. There are problems with IBM-designed IRQ13 behaviour.
  * Don't touch unless you *really* know how it works.
  */
-asmlinkage void math_state_restore(void)
+asmlinkage void math_state_restore(struct pt_regs regs)
 {
 	__asm__ __volatile__("clts");		/* Allow maths ops (or we recurse) */
-
-/*
- *	SMP is actually simpler than uniprocessor for once. Because
- *	we can't pull the delayed FPU switching trick Linus does
- *	we simply have to do the restore each context switch and
- *	set the flag. switch_to() will always save the state in
- *	case we swap processors. We also don't use the coprocessor
- *	timer - IRQ 13 mode isn't used with SMP machines (thank god).
- */
-
 	if(current->used_math)
 		__asm__("frstor %0": :"m" (current->tss.i387));
 	else

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov