Re: 2.6.26-rc: SPARC: Sun Ultra 10 can not boot

!MAILaRCHIVE_VOTE_RePLACE
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
To: <a.beregalov@...>
Cc: <kernel-testers@...>, <sparclinux@...>, <linux-kernel@...>
Date: Friday, June 20, 2008 - 6:51 pm

From: "Alexander Beregalov" <a.beregalov@gmail.com>
Date: Sat, 21 Jun 2008 02:42:36 +0400


Something is screwey here... Hmmm...

When I added the changeset in question, it fixed a problem in that
any backtrace of a kernel thread would loop forever at the end.
Any stack backtrace would hang or reach a safety limit (such as
the one imposed by lockdep).

Please double check that you are precisely reverting this patch
below _before_ doing these tests:

commit a051bc5bb1ac6dc138d529077fa20cbbc6622d95
Author: David S. Miller <davem@davemloft.net>
Date:   Wed May 21 18:14:28 2008 -0700

    sparc64: Fix kernel thread stack termination.
    
    Because of the silly way I set up the initial stack for
    new kernel threads, there is a loop at the top of the
    stack.
    
    To fix this, properly add another stack frame that is copied
    from the parent and terminate it in the child by setting
    the frame pointer in that frame to zero.
    
    Signed-off-by: David S. Miller <davem@davemloft.net>

diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c
index 0a0c05f..2084f81 100644
--- a/arch/sparc64/kernel/process.c
+++ b/arch/sparc64/kernel/process.c
@@ -657,20 +657,39 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
 		struct task_struct *p, struct pt_regs *regs)
 {
 	struct thread_info *t = task_thread_info(p);
+	struct sparc_stackf *parent_sf;
+	unsigned long child_stack_sz;
 	char *child_trap_frame;
+	int kernel_thread;
 
-	/* Calculate offset to stack_frame & pt_regs */
-	child_trap_frame = task_stack_page(p) + (THREAD_SIZE - (TRACEREG_SZ+STACKFRAME_SZ));
-	memcpy(child_trap_frame, (((struct sparc_stackf *)regs)-1), (TRACEREG_SZ+STACKFRAME_SZ));
+	kernel_thread = (regs->tstate & TSTATE_PRIV) ? 1 : 0;
+	parent_sf = ((struct sparc_stackf *) regs) - 1;
 
-	t->flags = (t->flags & ~((0xffUL << TI_FLAG_CWP_SHIFT) | (0xffUL << TI_FLAG_CURRENT_DS_SHIFT))) |
+	/* Calculate offset to stack_frame & pt_regs */
+	child_stack_sz = ((STACKFRAME_SZ + TRACEREG_SZ) +
+			  (kernel_thread ? STACKFRAME_SZ : 0));
+	child_trap_frame = (task_stack_page(p) +
+			    (THREAD_SIZE - child_stack_sz));
+	memcpy(child_trap_frame, parent_sf, child_stack_sz);
+
+	t->flags = (t->flags & ~((0xffUL << TI_FLAG_CWP_SHIFT) |
+				 (0xffUL << TI_FLAG_CURRENT_DS_SHIFT))) |
 		(((regs->tstate + 1) & TSTATE_CWP) << TI_FLAG_CWP_SHIFT);
 	t->new_child = 1;
 	t->ksp = ((unsigned long) child_trap_frame) - STACK_BIAS;
-	t->kregs = (struct pt_regs *)(child_trap_frame+sizeof(struct sparc_stackf));
+	t->kregs = (struct pt_regs *) (child_trap_frame +
+				       sizeof(struct sparc_stackf));
 	t->fpsaved[0] = 0;
 
-	if (regs->tstate & TSTATE_PRIV) {
+	if (kernel_thread) {
+		struct sparc_stackf *child_sf = (struct sparc_stackf *)
+			(child_trap_frame + (STACKFRAME_SZ + TRACEREG_SZ));
+
+		/* Zero terminate the stack backtrace.  */
+		child_sf->fp = NULL;
+		t->kregs->u_regs[UREG_FP] =
+		  ((unsigned long) child_sf) - STACK_BIAS;
+
 		/* Special case, if we are spawning a kernel thread from
 		 * a userspace task (via KMOD, NFS, or similar) we must
 		 * disable performance counters in the child because the
@@ -681,12 +700,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
 			t->pcr_reg = 0;
 			t->flags &= ~_TIF_PERFCTR;
 		}
-		t->kregs->u_regs[UREG_FP] = t->ksp;
 		t->flags |= ((long)ASI_P << TI_FLAG_CURRENT_DS_SHIFT);
-		flush_register_windows();
-		memcpy((void *)(t->ksp + STACK_BIAS),
-		       (void *)(regs->u_regs[UREG_FP] + STACK_BIAS),
-		       sizeof(struct sparc_stackf));
 		t->kregs->u_regs[UREG_G6] = (unsigned long) t;
 		t->kregs->u_regs[UREG_G4] = (unsigned long) t->task;
 	} else {
--
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
Re: 2.6.26-rc: SPARC: Sun Ultra 10 can not boot, David Miller, (Fri Jun 20, 6:51 pm)
Re: 2.6.26-rc: SPARC: Sun Ultra 10 can not boot, Alexander Beregalov, (Fri Jun 20, 7:12 pm)
Re: 2.6.26-rc: SPARC: Sun Ultra 10 can not boot, David Miller, (Fri Jun 20, 7:21 pm)
Re: 2.6.26-rc: SPARC: Sun Ultra 10 can not boot, Alexander Beregalov, (Fri Jun 20, 7:36 pm)
Re: 2.6.26-rc: SPARC: Sun Ultra 10 can not boot, Alexander Beregalov, (Mon Jul 7, 5:19 am)
Re: 2.6.26-rc: SPARC: Sun Ultra 10 can not boot, David Miller, (Mon Jul 7, 7:01 am)
Re: 2.6.26-rc: SPARC: Sun Ultra 10 can not boot, Mikael Pettersson, (Mon Jul 7, 9:05 am)
Re: 2.6.26-rc: SPARC: Sun Ultra 10 can not boot, Alexander Beregalov, (Mon Jul 7, 11:59 am)
Re: 2.6.26-rc: SPARC: Sun Ultra 10 can not boot, David Miller, (Fri Aug 8, 2:01 am)
Re: 2.6.26-rc: SPARC: Sun Ultra 10 can not boot, Alexander Beregalov, (Fri Aug 8, 5:31 am)
Re: 2.6.26-rc: SPARC: Sun Ultra 10 can not boot, David Miller, (Fri Aug 8, 5:40 am)
Re: 2.6.26-rc: SPARC: Sun Ultra 10 can not boot, Alexander Beregalov, (Fri Aug 8, 6:14 am)
Re: 2.6.26-rc: SPARC: Sun Ultra 10 can not boot, David Miller, (Fri Aug 8, 6:38 am)
Re: 2.6.26-rc: SPARC: Sun Ultra 10 can not boot, Alexander Beregalov, (Fri Aug 8, 6:56 am)
Re: 2.6.26-rc: SPARC: Sun Ultra 10 can not boot, David Miller, (Fri Aug 8, 7:18 am)
Re: 2.6.26-rc: SPARC: Sun Ultra 10 can not boot, Alexander Beregalov, (Fri Aug 8, 10:28 am)
Re: 2.6.26-rc: SPARC: Sun Ultra 10 can not boot, Alexander Beregalov, (Fri Aug 8, 7:52 am)
Re: 2.6.26-rc: SPARC: Sun Ultra 10 can not boot, David Miller, (Wed Aug 13, 11:53 pm)
Re: 2.6.26-rc: SPARC: Sun Ultra 10 can not boot, Alexander Beregalov, (Thu Aug 14, 6:19 am)
Re: 2.6.26-rc: SPARC: Sun Ultra 10 can not boot, David Miller, (Fri Aug 8, 7:17 pm)