m68k: always set stack frame format for ColdFire on thread start
Greg Ungerer [Wed, 12 Sep 2012 09:13:19 +0000 (05:13 -0400)]
The stack frame "format" field needs to be explicitly set on thread creation
on ColdFire. For a normal long word aligned user stack pointer the frame
format is 0x4.

We were doing this for non-MMU ColdFire, but not for the case with MMU enabled.
So fix it so we always do it if targeting ColdFire.

The old code happend to rely on the stack frame format being inhereted from
the process calling exec. Furture changes means that may not always work,
so we really do want to set it explicitly.

Signed-off-by: Greg Ungerer <gerg@uclinux.org>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

arch/m68k/include/asm/processor.h

index f17c42a..9b4c82c 100644 (file)
@@ -100,6 +100,16 @@ struct thread_struct {
        .fs     = __KERNEL_DS,                                          \
 }
 
+/*
+ * ColdFire stack format sbould be 0x4 for an aligned usp (will always be
+ * true on thread creation). We need to set this explicitly.
+ */
+#ifdef CONFIG_COLDFIRE
+#define setframeformat(_regs)  do { (_regs)->format = 0x4; } while(0)
+#else
+#define setframeformat(_regs)  do { } while (0)
+#endif
+
 #ifdef CONFIG_MMU
 /*
  * Do necessary setup to start up a newly executed thread.
@@ -109,6 +119,7 @@ static inline void start_thread(struct pt_regs * regs, unsigned long pc,
 {
        regs->pc = pc;
        regs->sr &= ~0x2000;
+       setframeformat(regs);
        wrusp(usp);
 }
 
@@ -116,21 +127,11 @@ extern int handle_kernel_fault(struct pt_regs *regs);
 
 #else
 
-/*
- * Coldfire stacks need to be re-aligned on trap exit, conventional
- * 68k can handle this case cleanly.
- */
-#ifdef CONFIG_COLDFIRE
-#define reformat(_regs)                do { (_regs)->format = 0x4; } while(0)
-#else
-#define reformat(_regs)                do { } while (0)
-#endif
-
 #define start_thread(_regs, _pc, _usp)                  \
 do {                                                    \
        (_regs)->pc = (_pc);                            \
        ((struct switch_stack *)(_regs))[-1].a6 = 0;    \
-       reformat(_regs);                                \
+       setframeformat(_regs);                          \
        if (current->mm)                                \
                (_regs)->d5 = current->mm->start_data;  \
        (_regs)->sr &= ~0x2000;                         \