From 46f15067c020a0ce712cb2d3ef38c0589a521c15 Mon Sep 17 00:00:00 2001 From: Mark Salter Date: Fri, 21 Sep 2012 12:26:37 -0400 Subject: c6x: add ret_from_kernel_thread(), simplify kernel_thread() Signed-off-by: Mark Salter Signed-off-by: Al Viro --- arch/c6x/kernel/entry.S | 20 ++++++++++++++++++++ arch/c6x/kernel/process.c | 38 ++++++++++++-------------------------- 2 files changed, 32 insertions(+), 26 deletions(-) (limited to 'arch/c6x') diff --git a/arch/c6x/kernel/entry.S b/arch/c6x/kernel/entry.S index 30b37e5..6e6bd9d 100644 --- a/arch/c6x/kernel/entry.S +++ b/arch/c6x/kernel/entry.S @@ -400,6 +400,26 @@ ret_from_fork_2: STW .D2T2 B0,*+SP(REGS_A4+8) ENDPROC(ret_from_fork) +ENTRY(ret_from_kernel_thread) +#ifdef CONFIG_C6X_BIG_KERNEL + MVKL .S1 schedule_tail,A0 + MVKH .S1 schedule_tail,A0 + B .S2X A0 +#else + B .S2 schedule_tail +#endif + LDW .D2T2 *+SP(REGS_A0+8),B10 /* get fn */ + ADDKPC .S2 0f,B3,3 +0: + B .S2 B10 /* call fn */ + LDW .D2T1 *+SP(REGS_A1+8),A4 /* get arg */ + MVKL .S2 sys_exit,B11 + MVKH .S2 sys_exit,B11 + ADDKPC .S2 0f,B3,1 +0: + BNOP .S2 B11,5 /* jump to sys_exit */ +ENDPROC(ret_from_kernel_thread) + ;; ;; These are the interrupt handlers, responsible for calling __do_IRQ() ;; int6 is used for syscalls (see _system_call entry) diff --git a/arch/c6x/kernel/process.c b/arch/c6x/kernel/process.c index 45e924a..d2ffc9b 100644 --- a/arch/c6x/kernel/process.c +++ b/arch/c6x/kernel/process.c @@ -25,6 +25,7 @@ void (*c6x_restart)(void); void (*c6x_halt)(void); extern asmlinkage void ret_from_fork(void); +extern asmlinkage void ret_from_kernel_thread(void); /* * power off function, if any @@ -103,36 +104,21 @@ void machine_power_off(void) halt_loop(); } -static void kernel_thread_helper(int dummy, void *arg, int (*fn)(void *)) -{ - do_exit(fn(arg)); -} - /* * Create a kernel thread */ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) { - struct pt_regs regs; - - /* - * copy_thread sets a4 to zero (child return from fork) - * so we can't just set things up to directly return to - * fn. - */ - memset(®s, 0, sizeof(regs)); - regs.b4 = (unsigned long) arg; - regs.a6 = (unsigned long) fn; - regs.pc = (unsigned long) kernel_thread_helper; - local_save_flags(regs.csr); - regs.csr |= 1; - regs.tsr = 5; /* Set GEE and GIE in TSR */ + struct pt_regs regs = { + .a0 = (unsigned long)fn, + .a1 = (unsigned long)arg, + .tsr = 0, /* kernel mode */ + }; /* Ok, create the new process.. */ return do_fork(flags | CLONE_VM | CLONE_UNTRACED, -1, ®s, 0, NULL, NULL); } -EXPORT_SYMBOL(kernel_thread); void flush_thread(void) { @@ -192,21 +178,21 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, childregs = task_pt_regs(p); *childregs = *regs; - childregs->a4 = 0; - if (usp == -1) + if (usp == -1) { /* case of __kernel_thread: we return to supervisor space */ childregs->sp = (unsigned long)(childregs + 1); - else + p->thread.pc = (unsigned long) ret_from_kernel_thread; + } else { /* Otherwise use the given stack */ childregs->sp = usp; + p->thread.pc = (unsigned long) ret_from_fork; + } /* Set usp/ksp */ p->thread.usp = childregs->sp; - /* switch_to uses stack to save/restore 14 callee-saved regs */ thread_saved_ksp(p) = (unsigned long)childregs - 8; - p->thread.pc = (unsigned int) ret_from_fork; - p->thread.wchan = (unsigned long) ret_from_fork; + p->thread.wchan = p->thread.pc; #ifdef __DSBT__ { unsigned long dp; -- cgit v1.1 From 39fcf44099dd64679c232c4a7bb81cf469e4e43c Mon Sep 17 00:00:00 2001 From: Mark Salter Date: Fri, 21 Sep 2012 12:26:38 -0400 Subject: c6x: switch to generic kernel_execve Signed-off-by: Mark Salter Signed-off-by: Al Viro --- arch/c6x/include/asm/unistd.h | 2 ++ arch/c6x/kernel/entry.S | 13 ++++++------- 2 files changed, 8 insertions(+), 7 deletions(-) (limited to 'arch/c6x') diff --git a/arch/c6x/include/asm/unistd.h b/arch/c6x/include/asm/unistd.h index 6d54ea4..1ce3a6f 100644 --- a/arch/c6x/include/asm/unistd.h +++ b/arch/c6x/include/asm/unistd.h @@ -16,6 +16,8 @@ #if !defined(_ASM_C6X_UNISTD_H) || defined(__SYSCALL) #define _ASM_C6X_UNISTD_H +#define __ARCH_WANT_KERNEL_EXECVE + /* Use the standard ABI for syscalls. */ #include diff --git a/arch/c6x/kernel/entry.S b/arch/c6x/kernel/entry.S index 6e6bd9d..32e3683 100644 --- a/arch/c6x/kernel/entry.S +++ b/arch/c6x/kernel/entry.S @@ -420,6 +420,12 @@ ENTRY(ret_from_kernel_thread) BNOP .S2 B11,5 /* jump to sys_exit */ ENDPROC(ret_from_kernel_thread) +ENTRY(ret_from_kernel_execve) + GET_THREAD_INFO A12 + BNOP .S2 syscall_exit,4 + ADD .D2X A4,-8,SP +ENDPROC(ret_from_kernel_execve) + ;; ;; These are the interrupt handlers, responsible for calling __do_IRQ() ;; int6 is used for syscalls (see _system_call entry) @@ -613,13 +619,6 @@ ENTRY(sys_sigaltstack) NOP 4 ENDPROC(sys_sigaltstack) - ;; kernel_execve -ENTRY(kernel_execve) - MVK .S2 __NR_execve,B0 - SWE - BNOP .S2 B3,5 -ENDPROC(kernel_execve) - ;; ;; Special system calls ;; return address is in B3 -- cgit v1.1 From 680a14535c330481517d3f95b2277353a14b8442 Mon Sep 17 00:00:00 2001 From: Mark Salter Date: Fri, 21 Sep 2012 12:26:39 -0400 Subject: c6x: switch to generic sys_execve Signed-off-by: Mark Salter Signed-off-by: Al Viro --- arch/c6x/include/asm/syscalls.h | 5 ----- arch/c6x/include/asm/unistd.h | 1 + arch/c6x/kernel/entry.S | 23 ----------------------- arch/c6x/kernel/process.c | 22 ---------------------- 4 files changed, 1 insertion(+), 50 deletions(-) (limited to 'arch/c6x') diff --git a/arch/c6x/include/asm/syscalls.h b/arch/c6x/include/asm/syscalls.h index aed53da..e7b8991 100644 --- a/arch/c6x/include/asm/syscalls.h +++ b/arch/c6x/include/asm/syscalls.h @@ -44,11 +44,6 @@ extern int sys_cache_sync(unsigned long s, unsigned long e); struct pt_regs; extern asmlinkage long sys_c6x_clone(struct pt_regs *regs); -extern asmlinkage long sys_c6x_execve(const char __user *name, - const char __user *const __user *argv, - const char __user *const __user *envp, - struct pt_regs *regs); - #include diff --git a/arch/c6x/include/asm/unistd.h b/arch/c6x/include/asm/unistd.h index 1ce3a6f..3c131d5 100644 --- a/arch/c6x/include/asm/unistd.h +++ b/arch/c6x/include/asm/unistd.h @@ -17,6 +17,7 @@ #define _ASM_C6X_UNISTD_H #define __ARCH_WANT_KERNEL_EXECVE +#define __ARCH_WANT_SYS_EXECVE /* Use the standard ABI for syscalls. */ #include diff --git a/arch/c6x/kernel/entry.S b/arch/c6x/kernel/entry.S index 32e3683..5449c36 100644 --- a/arch/c6x/kernel/entry.S +++ b/arch/c6x/kernel/entry.S @@ -647,29 +647,6 @@ ENTRY(sys_rt_sigreturn) #endif ENDPROC(sys_rt_sigreturn) -ENTRY(sys_execve) - ADDAW .D2 SP,2,B6 ; put regs addr in 4th parameter - ; & adjust regs stack addr - LDW .D2T2 *+SP(REGS_B4+8),B4 - - ;; c6x_execve(char *name, char **argv, - ;; char **envp, struct pt_regs *regs) -#ifdef CONFIG_C6X_BIG_KERNEL - || MVKL .S1 sys_c6x_execve,A0 - MVKH .S1 sys_c6x_execve,A0 - B .S2X A0 -#else - || B .S2 sys_c6x_execve -#endif - STW .D2T2 B3,*SP--[2] - ADDKPC .S2 ret_from_c6x_execve,B3,3 - -ret_from_c6x_execve: - LDW .D2T2 *++SP[2],B3 - NOP 4 - BNOP .S2 B3,5 -ENDPROC(sys_execve) - ENTRY(sys_pread_c6x) MV .D2X A8,B7 #ifdef CONFIG_C6X_BIG_KERNEL diff --git a/arch/c6x/kernel/process.c b/arch/c6x/kernel/process.c index d2ffc9b..f98616d 100644 --- a/arch/c6x/kernel/process.c +++ b/arch/c6x/kernel/process.c @@ -207,28 +207,6 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, return 0; } -/* - * c6x_execve() executes a new program. - */ -SYSCALL_DEFINE4(c6x_execve, const char __user *, name, - const char __user *const __user *, argv, - const char __user *const __user *, envp, - struct pt_regs *, regs) -{ - int error; - char *filename; - - filename = getname(name); - error = PTR_ERR(filename); - if (IS_ERR(filename)) - goto out; - - error = do_execve(filename, argv, envp, regs); - putname(filename); -out: - return error; -} - unsigned long get_wchan(struct task_struct *p) { return p->thread.wchan; -- cgit v1.1 From 5687580bcb758ddc95be9894f592a65034e77401 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 22 Sep 2012 18:23:49 -0400 Subject: c6x: switch to generic kernel_thread() Signed-off-by: Al Viro --- arch/c6x/Kconfig | 1 + arch/c6x/include/asm/processor.h | 2 -- arch/c6x/kernel/process.c | 24 +++++------------------- 3 files changed, 6 insertions(+), 21 deletions(-) (limited to 'arch/c6x') diff --git a/arch/c6x/Kconfig b/arch/c6x/Kconfig index 983c859..45268b5 100644 --- a/arch/c6x/Kconfig +++ b/arch/c6x/Kconfig @@ -17,6 +17,7 @@ config C6X select OF select OF_EARLY_FLATTREE select GENERIC_CLOCKEVENTS + select GENERIC_KERNEL_THREAD config MMU def_bool n diff --git a/arch/c6x/include/asm/processor.h b/arch/c6x/include/asm/processor.h index c50af7e..b9eb3da 100644 --- a/arch/c6x/include/asm/processor.h +++ b/arch/c6x/include/asm/processor.h @@ -92,8 +92,6 @@ static inline void release_thread(struct task_struct *dead_task) { } -extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); - #define copy_segments(tsk, mm) do { } while (0) #define release_segments(mm) do { } while (0) diff --git a/arch/c6x/kernel/process.c b/arch/c6x/kernel/process.c index f98616d..2770d9a 100644 --- a/arch/c6x/kernel/process.c +++ b/arch/c6x/kernel/process.c @@ -104,22 +104,6 @@ void machine_power_off(void) halt_loop(); } -/* - * Create a kernel thread - */ -int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) -{ - struct pt_regs regs = { - .a0 = (unsigned long)fn, - .a1 = (unsigned long)arg, - .tsr = 0, /* kernel mode */ - }; - - /* Ok, create the new process.. */ - return do_fork(flags | CLONE_VM | CLONE_UNTRACED, -1, ®s, - 0, NULL, NULL); -} - void flush_thread(void) { } @@ -177,14 +161,16 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, childregs = task_pt_regs(p); - *childregs = *regs; - - if (usp == -1) { + if (!regs) { /* case of __kernel_thread: we return to supervisor space */ + memset(childregs, 0, sizeof(struct pt_regs)); childregs->sp = (unsigned long)(childregs + 1); p->thread.pc = (unsigned long) ret_from_kernel_thread; + childregs->a0 = usp; /* function */ + childregs->a1 = ustk_size; /* argument */ } else { /* Otherwise use the given stack */ + *childregs = *regs; childregs->sp = usp; p->thread.pc = (unsigned long) ret_from_fork; } -- cgit v1.1 From 16a8016372c42c7628eb4a39d75386a461e8c5d0 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 1 Jun 2012 14:22:01 -0400 Subject: sanitize tsk_is_polling() Make default just return 0. The current default (checking TIF_POLLING_NRFLAG) is taken to architectures that need it; ones that don't do polling in their idle threads don't need to defined TIF_POLLING_NRFLAG at all. ia64 defined both TS_POLLING (used by its tsk_is_polling()) and TIF_POLLING_NRFLAG (not used at all). Killed the latter... Signed-off-by: Al Viro --- arch/c6x/include/asm/thread_info.h | 1 - arch/c6x/kernel/asm-offsets.c | 1 - 2 files changed, 2 deletions(-) (limited to 'arch/c6x') diff --git a/arch/c6x/include/asm/thread_info.h b/arch/c6x/include/asm/thread_info.h index 1710bcb..4c8dc56 100644 --- a/arch/c6x/include/asm/thread_info.h +++ b/arch/c6x/include/asm/thread_info.h @@ -97,7 +97,6 @@ struct thread_info *current_thread_info(void) #define TIF_NEED_RESCHED 3 /* rescheduling necessary */ #define TIF_RESTORE_SIGMASK 4 /* restore signal mask in do_signal() */ -#define TIF_POLLING_NRFLAG 16 /* true if polling TIF_NEED_RESCHED */ #define TIF_MEMDIE 17 /* OOM killer killed process */ #define TIF_WORK_MASK 0x00007FFE /* work on irq/exception return */ diff --git a/arch/c6x/kernel/asm-offsets.c b/arch/c6x/kernel/asm-offsets.c index 759ad6d..60f1e43 100644 --- a/arch/c6x/kernel/asm-offsets.c +++ b/arch/c6x/kernel/asm-offsets.c @@ -116,7 +116,6 @@ void foo(void) DEFINE(_TIF_NOTIFY_RESUME, (1<