diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2012-10-10 13:17:31 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2012-10-14 19:37:40 -0400 |
commit | 557e1995a92d318206910d8b5c62075fe02b37e0 (patch) | |
tree | 8373bada8e8f5306eed59487827265305fa0f1be | |
parent | ddffeb8c4d0331609ef2581d84de4d763607bd37 (diff) | |
download | linux-stable-557e1995a92d318206910d8b5c62075fe02b37e0.tar.gz linux-stable-557e1995a92d318206910d8b5c62075fe02b37e0.tar.bz2 linux-stable-557e1995a92d318206910d8b5c62075fe02b37e0.zip |
h8300: generic kernel_thread()
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | arch/h8300/Kconfig | 1 | ||||
-rw-r--r-- | arch/h8300/include/asm/processor.h | 2 | ||||
-rw-r--r-- | arch/h8300/include/asm/ptrace.h | 2 | ||||
-rw-r--r-- | arch/h8300/kernel/entry.S | 10 | ||||
-rw-r--r-- | arch/h8300/kernel/h8300_ksyms.c | 1 | ||||
-rw-r--r-- | arch/h8300/kernel/process.c | 41 |
6 files changed, 21 insertions, 36 deletions
diff --git a/arch/h8300/Kconfig b/arch/h8300/Kconfig index 98fabd10e95f..4cef8a91c2a0 100644 --- a/arch/h8300/Kconfig +++ b/arch/h8300/Kconfig @@ -8,6 +8,7 @@ config H8300 select GENERIC_IRQ_SHOW select GENERIC_CPU_DEVICES select MODULES_USE_ELF_RELA + select GENERIC_KERNEL_THREAD config SYMBOL_PREFIX string diff --git a/arch/h8300/include/asm/processor.h b/arch/h8300/include/asm/processor.h index 4c9f6f87b617..4b0ca49bb463 100644 --- a/arch/h8300/include/asm/processor.h +++ b/arch/h8300/include/asm/processor.h @@ -107,8 +107,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.. */ diff --git a/arch/h8300/include/asm/ptrace.h b/arch/h8300/include/asm/ptrace.h index d09c440bdba7..00502a61bf0a 100644 --- a/arch/h8300/include/asm/ptrace.h +++ b/arch/h8300/include/asm/ptrace.h @@ -60,6 +60,8 @@ struct pt_regs { #define user_mode(regs) (!((regs)->ccr & PS_S)) #define instruction_pointer(regs) ((regs)->pc) #define profile_pc(regs) instruction_pointer(regs) +#define current_pt_regs() ((struct pt_regs *) \ + (THREAD_SIZE + (unsigned long)current_thread_info()) - 1) #endif /* __KERNEL__ */ #endif /* __ASSEMBLY__ */ #endif /* _H8300_PTRACE_H */ diff --git a/arch/h8300/kernel/entry.S b/arch/h8300/kernel/entry.S index ca7431690300..2cdb49a56099 100644 --- a/arch/h8300/kernel/entry.S +++ b/arch/h8300/kernel/entry.S @@ -158,6 +158,7 @@ INTERRUPTS = 128 .globl SYMBOL_NAME(system_call) .globl SYMBOL_NAME(ret_from_exception) .globl SYMBOL_NAME(ret_from_fork) +.globl SYMBOL_NAME(ret_from_kernel_thread) .globl SYMBOL_NAME(ret_from_interrupt) .globl SYMBOL_NAME(interrupt_redirect_table) .globl SYMBOL_NAME(sw_ksp),SYMBOL_NAME(sw_usp) @@ -330,6 +331,15 @@ SYMBOL_NAME_LABEL(ret_from_fork) jsr @SYMBOL_NAME(schedule_tail) jmp @SYMBOL_NAME(ret_from_exception) +SYMBOL_NAME_LABEL(ret_from_kernel_thread) + mov.l er2,er0 + jsr @SYMBOL_NAME(schedule_tail) + mov.l @(LER4:16,sp),er0 + mov.l @(LER5:16,sp),er1 + jsr @er1 + sub.l @er0,@er0 + jsr @SYMBOL_NAME(sys_exit) + SYMBOL_NAME_LABEL(resume) /* * Beware - when entering resume, offset of tss is in d1, diff --git a/arch/h8300/kernel/h8300_ksyms.c b/arch/h8300/kernel/h8300_ksyms.c index 6866bd9c7fb4..53d7c0e4bd83 100644 --- a/arch/h8300/kernel/h8300_ksyms.c +++ b/arch/h8300/kernel/h8300_ksyms.c @@ -33,7 +33,6 @@ EXPORT_SYMBOL(strncmp); EXPORT_SYMBOL(ip_fast_csum); -EXPORT_SYMBOL(kernel_thread); EXPORT_SYMBOL(enable_irq); EXPORT_SYMBOL(disable_irq); diff --git a/arch/h8300/kernel/process.c b/arch/h8300/kernel/process.c index e8dc1393a13a..e3dfea71c15f 100644 --- a/arch/h8300/kernel/process.c +++ b/arch/h8300/kernel/process.c @@ -47,6 +47,7 @@ void (*pm_power_off)(void) = NULL; EXPORT_SYMBOL(pm_power_off); asmlinkage void ret_from_fork(void); +asmlinkage void ret_from_kernel_thread(void); /* * The idle loop on an H8/300.. @@ -122,39 +123,6 @@ void show_regs(struct pt_regs * regs) printk("\n"); } -/* - * Create a kernel thread - */ -int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) -{ - long retval; - long clone_arg; - mm_segment_t fs; - - fs = get_fs(); - set_fs (KERNEL_DS); - clone_arg = flags | CLONE_VM; - __asm__("mov.l sp,er3\n\t" - "sub.l er2,er2\n\t" - "mov.l %2,er1\n\t" - "mov.l %1,er0\n\t" - "trapa #0\n\t" - "cmp.l sp,er3\n\t" - "beq 1f\n\t" - "mov.l %4,er0\n\t" - "mov.l %3,er1\n\t" - "jsr @er1\n\t" - "mov.l %5,er0\n\t" - "trapa #0\n" - "1:\n\t" - "mov.l er0,%0" - :"=r"(retval) - :"i"(__NR_clone),"g"(clone_arg),"g"(fn),"g"(arg),"i"(__NR_exit) - :"er0","er1","er2","er3"); - set_fs (fs); - return retval; -} - void flush_thread(void) { } @@ -198,6 +166,13 @@ int copy_thread(unsigned long clone_flags, childregs = (struct pt_regs *) (THREAD_SIZE + task_stack_page(p)) - 1; + if (unlikely(p->flags & PF_KTHREAD)) { + memset(childregs, 0, sizeof(struct pt_regs)); + childregs->retpc = (unsigned long) ret_from_kernel_thread; + childregs->er4 = topstk; /* arg */ + childregs->er5 = usp; /* fn */ + p->thread.ksp = (unsigned long)childregs; + } *childregs = *regs; childregs->retpc = (unsigned long) ret_from_fork; childregs->er0 = 0; |