blackfin: convert kernel_thread() and kernel_execve() to generic ones
authorAl Viro <viro@zeniv.linux.org.uk>
Sat, 13 Oct 2012 07:22:53 +0000 (03:22 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Mon, 15 Oct 2012 03:06:52 +0000 (23:06 -0400)
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
arch/blackfin/Kconfig
arch/blackfin/include/asm/processor.h
arch/blackfin/kernel/entry.S
arch/blackfin/kernel/process.c
arch/blackfin/mach-common/entry.S

index b6f3ad5..ab9ff40 100644 (file)
@@ -45,6 +45,8 @@ config BLACKFIN
        select ARCH_USES_GETTIMEOFFSET if !GENERIC_CLOCKEVENTS
        select HAVE_MOD_ARCH_SPECIFIC
        select MODULES_USE_ELF_RELA
+       select GENERIC_KERNEL_THREAD
+       select GENERIC_KERNEL_EXECVE
 
 config GENERIC_CSUM
        def_bool y
index 4ef7cfe..d0e72e9 100644 (file)
@@ -75,8 +75,6 @@ static inline void release_thread(struct task_struct *dead_task)
 {
 }
 
-extern int kernel_thread(int (*fn) (void *), void *arg, unsigned long flags);
-
 /*
  * Free current thread data structures etc..
  */
index f33792c..78f4f63 100644 (file)
@@ -46,22 +46,16 @@ ENTRY(_ret_from_fork)
        SP += -12;
        pseudo_long_call _schedule_tail, p5;
        SP += 12;
-       r0 = [sp + PT_IPEND];
-       cc = bittst(r0,1);
-       if cc jump .Lin_kernel;
+       p1 = [sp++];
+       r0 = [sp++];
+       cc = p1 == 0;
+       if cc jump .Lfork;
+       sp += -12;
+       call (p1);
+       sp += 12;
+.Lfork:
        RESTORE_CONTEXT
        rti;
-.Lin_kernel:
-       bitclr(r0,1);
-       [sp + PT_IPEND] = r0;
-       /* do a 'fake' RTI by jumping to [RETI]
-        * to avoid clearing supervisor mode in child
-        */
-       r0 = [sp + PT_PC];
-       [sp + PT_P0] = r0;
-
-       RESTORE_ALL_SYS
-       jump (p0);
 ENDPROC(_ret_from_fork)
 
 ENTRY(_sys_vfork)
index bb1cc72..9945b94 100644 (file)
@@ -102,40 +102,6 @@ void cpu_idle(void)
 }
 
 /*
- * This gets run with P1 containing the
- * function to call, and R1 containing
- * the "args".  Note P0 is clobbered on the way here.
- */
-void kernel_thread_helper(void);
-__asm__(".section .text\n"
-       ".align 4\n"
-       "_kernel_thread_helper:\n\t"
-       "\tsp += -12;\n\t"
-       "\tr0 = r1;\n\t" "\tcall (p1);\n\t" "\tcall _do_exit;\n" ".previous");
-
-/*
- * Create a kernel thread.
- */
-pid_t kernel_thread(int (*fn) (void *), void *arg, unsigned long flags)
-{
-       struct pt_regs regs;
-
-       memset(&regs, 0, sizeof(regs));
-
-       regs.r1 = (unsigned long)arg;
-       regs.p1 = (unsigned long)fn;
-       regs.pc = (unsigned long)kernel_thread_helper;
-       regs.orig_p0 = -1;
-       /* Set bit 2 to tell ret_from_fork we should be returning to kernel
-          mode.  */
-       regs.ipend = 0x8002;
-       __asm__ __volatile__("%0 = syscfg;":"=da"(regs.syscfg):);
-       return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL,
-                      NULL);
-}
-EXPORT_SYMBOL(kernel_thread);
-
-/*
  * Do necessary setup to start up a newly executed thread.
  *
  * pass the data segment into user programs if it exists,
@@ -193,13 +159,26 @@ copy_thread(unsigned long clone_flags,
            struct task_struct *p, struct pt_regs *regs)
 {
        struct pt_regs *childregs;
+       unsigned long *v;
 
        childregs = (struct pt_regs *) (task_stack_page(p) + THREAD_SIZE) - 1;
-       *childregs = *regs;
-       childregs->r0 = 0;
+       v = ((unsigned long *)childregs) - 2;
+       if (unlikely(!regs)) {
+               memset(childregs, 0, sizeof(struct pt_regs));
+               v[0] = usp;
+               v[1] = topstk;
+               childregs->orig_p0 = -1;
+               childregs->ipend = 0x8000;
+               __asm__ __volatile__("%0 = syscfg;":"=da"(childregs->syscfg):);
+               p->thread.usp = 0;
+       } else {
+               *childregs = *regs;
+               childregs->r0 = 0;
+               p->thread.usp = usp;
+               v[0] = v[1] = 0;
+       }
 
-       p->thread.usp = usp;
-       p->thread.ksp = (unsigned long)childregs;
+       p->thread.ksp = (unsigned long)v;
        p->thread.pc = (unsigned long)ret_from_fork;
 
        return 0;
index 1c3d2c5..4a38c68 100644 (file)
@@ -530,61 +530,6 @@ ENTRY(_trap) /* Exception: 4th entry into system event table(supervisor mode)*/
        jump .Lsyscall_really_exit;
 ENDPROC(_trap)
 
-ENTRY(_kernel_execve)
-       link SIZEOF_PTREGS;
-       p0 = sp;
-       r3 = SIZEOF_PTREGS / 4;
-       r4 = 0(x);
-.Lclear_regs:
-       [p0++] = r4;
-       r3 += -1;
-       cc = r3 == 0;
-       if !cc jump .Lclear_regs (bp);
-
-       p0 = sp;
-       sp += -16;
-       [sp + 12] = p0;
-       pseudo_long_call _do_execve, p5;
-       SP += 16;
-       cc = r0 == 0;
-       if ! cc jump .Lexecve_failed;
-       /* Success.  Copy our temporary pt_regs to the top of the kernel
-        * stack and do a normal exception return.
-        */
-       r1 = sp;
-       r0 = (-KERNEL_STACK_SIZE) (x);
-       r1 = r1 & r0;
-       p2 = r1;
-       p3 = [p2];
-       r0 = KERNEL_STACK_SIZE - 4 (z);
-       p1 = r0;
-       p1 = p1 + p2;
-
-       p0 = fp;
-       r4 = [p0--];
-       r3 = SIZEOF_PTREGS / 4;
-.Lcopy_regs:
-       r4 = [p0--];
-       [p1--] = r4;
-       r3 += -1;
-       cc = r3 == 0;
-       if ! cc jump .Lcopy_regs (bp);
-
-       r0 = (KERNEL_STACK_SIZE - SIZEOF_PTREGS) (z);
-       p1 = r0;
-       p1 = p1 + p2;
-       sp = p1;
-       r0 = syscfg;
-       [SP + PT_SYSCFG] = r0;
-       [p3 + (TASK_THREAD + THREAD_KSP)] = sp;
-
-       RESTORE_CONTEXT;
-       rti;
-.Lexecve_failed:
-       unlink;
-       rts;
-ENDPROC(_kernel_execve)
-
 ENTRY(_system_call)
        /* Store IPEND */
        p2.l = lo(IPEND);