diff options
Diffstat (limited to 'arch/unicore32/kernel')
| -rw-r--r-- | arch/unicore32/kernel/entry.S | 20 | ||||
| -rw-r--r-- | arch/unicore32/kernel/process.c | 58 | ||||
| -rw-r--r-- | arch/unicore32/kernel/setup.h | 6 | ||||
| -rw-r--r-- | arch/unicore32/kernel/sys.c | 63 | 
4 files changed, 27 insertions, 120 deletions
diff --git a/arch/unicore32/kernel/entry.S b/arch/unicore32/kernel/entry.S index dcb87ab19dd..7049350c790 100644 --- a/arch/unicore32/kernel/entry.S +++ b/arch/unicore32/kernel/entry.S @@ -573,17 +573,16 @@ ENDPROC(ret_to_user)   */  ENTRY(ret_from_fork)  	b.l	schedule_tail -	get_thread_info tsk -	ldw	r1, [tsk+], #TI_FLAGS		@ check for syscall tracing -	mov	why, #1 -	cand.a	r1, #_TIF_SYSCALL_TRACE		@ are we tracing syscalls? -	beq	ret_slow_syscall -	mov	r1, sp -	mov	r0, #1				@ trace exit [IP = 1] -	b.l	syscall_trace  	b	ret_slow_syscall  ENDPROC(ret_from_fork) +ENTRY(ret_from_kernel_thread) +	b.l	schedule_tail +	mov	r0, r5 +	adr	lr, ret_slow_syscall +	mov	pc, r4 +ENDPROC(ret_from_kernel_thread) +  /*=============================================================================   * SWI handler   *----------------------------------------------------------------------------- @@ -669,11 +668,6 @@ __cr_alignment:  #endif  	.ltorg -ENTRY(sys_execve) -		add	r3, sp, #S_OFF -		b	__sys_execve -ENDPROC(sys_execve) -  ENTRY(sys_clone)  		add	ip, sp, #S_OFF  		stw	ip, [sp+], #4 diff --git a/arch/unicore32/kernel/process.c b/arch/unicore32/kernel/process.c index b008586dad7..a8fe265ce2c 100644 --- a/arch/unicore32/kernel/process.c +++ b/arch/unicore32/kernel/process.c @@ -258,6 +258,7 @@ void release_thread(struct task_struct *dead_task)  }  asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); +asmlinkage void ret_from_kernel_thread(void) __asm__("ret_from_kernel_thread");  int  copy_thread(unsigned long clone_flags, unsigned long stack_start, @@ -266,17 +267,22 @@ copy_thread(unsigned long clone_flags, unsigned long stack_start,  	struct thread_info *thread = task_thread_info(p);  	struct pt_regs *childregs = task_pt_regs(p); -	*childregs = *regs; -	childregs->UCreg_00 = 0; -	childregs->UCreg_sp = stack_start; -  	memset(&thread->cpu_context, 0, sizeof(struct cpu_context_save));  	thread->cpu_context.sp = (unsigned long)childregs; -	thread->cpu_context.pc = (unsigned long)ret_from_fork; - -	if (clone_flags & CLONE_SETTLS) -		childregs->UCreg_16 = regs->UCreg_03; +	if (unlikely(!regs)) { +		thread->cpu_context.pc = (unsigned long)ret_from_kernel_thread; +		thread->cpu_context.r4 = stack_start; +		thread->cpu_context.r5 = stk_sz; +		memset(childregs, 0, sizeof(struct pt_regs)); +	} else { +		thread->cpu_context.pc = (unsigned long)ret_from_fork; +		*childregs = *regs; +		childregs->UCreg_00 = 0; +		childregs->UCreg_sp = stack_start; +		if (clone_flags & CLONE_SETTLS) +			childregs->UCreg_16 = regs->UCreg_03; +	}  	return 0;  } @@ -305,42 +311,6 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fp)  }  EXPORT_SYMBOL(dump_fpu); -/* - * Shuffle the argument into the correct register before calling the - * thread function.  r1 is the thread argument, r2 is the pointer to - * the thread function, and r3 points to the exit function. - */ -asm(".pushsection .text\n" -"	.align\n" -"	.type	kernel_thread_helper, #function\n" -"kernel_thread_helper:\n" -"	mov.a	asr, r7\n" -"	mov	r0, r4\n" -"	mov	lr, r6\n" -"	mov	pc, r5\n" -"	.size	kernel_thread_helper, . - kernel_thread_helper\n" -"	.popsection"); - -/* - * Create a kernel thread. - */ -pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) -{ -	struct pt_regs regs; - -	memset(®s, 0, sizeof(regs)); - -	regs.UCreg_04 = (unsigned long)arg; -	regs.UCreg_05 = (unsigned long)fn; -	regs.UCreg_06 = (unsigned long)do_exit; -	regs.UCreg_07 = PRIV_MODE; -	regs.UCreg_pc = (unsigned long)kernel_thread_helper; -	regs.UCreg_asr = regs.UCreg_07 | PSR_I_BIT; - -	return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); -} -EXPORT_SYMBOL(kernel_thread); -  unsigned long get_wchan(struct task_struct *p)  {  	struct stackframe frame; diff --git a/arch/unicore32/kernel/setup.h b/arch/unicore32/kernel/setup.h index f23955028a1..30f749da8f7 100644 --- a/arch/unicore32/kernel/setup.h +++ b/arch/unicore32/kernel/setup.h @@ -30,4 +30,10 @@ extern char __vectors_start[], __vectors_end[];  extern void kernel_thread_helper(void);  extern void __init early_signal_init(void); + +extern asmlinkage void __backtrace(void); +extern asmlinkage void c_backtrace(unsigned long fp, int pmode); + +extern void __show_regs(struct pt_regs *); +  #endif diff --git a/arch/unicore32/kernel/sys.c b/arch/unicore32/kernel/sys.c index fabdee96110..9680134b31f 100644 --- a/arch/unicore32/kernel/sys.c +++ b/arch/unicore32/kernel/sys.c @@ -42,69 +42,6 @@ asmlinkage long __sys_clone(unsigned long clone_flags, unsigned long newsp,  			parent_tid, child_tid);  } -/* sys_execve() executes a new program. - * This is called indirectly via a small wrapper - */ -asmlinkage long __sys_execve(const char __user *filename, -			  const char __user *const __user *argv, -			  const char __user *const __user *envp, -			  struct pt_regs *regs) -{ -	int error; -	struct filename *fn; - -	fn = getname(filename); -	error = PTR_ERR(fn); -	if (IS_ERR(fn)) -		goto out; -	error = do_execve(fn->name, argv, envp, regs); -	putname(fn); -out: -	return error; -} - -int kernel_execve(const char *filename, -		  const char *const argv[], -		  const char *const envp[]) -{ -	struct pt_regs regs; -	int ret; - -	memset(®s, 0, sizeof(struct pt_regs)); -	ret = do_execve(filename, -			(const char __user *const __user *)argv, -			(const char __user *const __user *)envp, ®s); -	if (ret < 0) -		goto out; - -	/* -	 * Save argc to the register structure for userspace. -	 */ -	regs.UCreg_00 = ret; - -	/* -	 * We were successful.  We won't be returning to our caller, but -	 * instead to user space by manipulating the kernel stack. -	 */ -	asm("add	r0, %0, %1\n\t" -		"mov	r1, %2\n\t" -		"mov	r2, %3\n\t" -		"mov	r22, #0\n\t"	/* not a syscall */ -		"mov	r23, %0\n\t"	/* thread structure */ -		"b.l	memmove\n\t"	/* copy regs to top of stack */ -		"mov	sp, r0\n\t"	/* reposition stack pointer */ -		"b	ret_to_user" -		: -		: "r" (current_thread_info()), -		  "Ir" (THREAD_START_SP - sizeof(regs)), -		  "r" (®s), -		  "Ir" (sizeof(regs)) -		: "r0", "r1", "r2", "r3", "ip", "lr", "memory"); - - out: -	return ret; -} -  /* Note: used by the compat code even in 64-bit Linux. */  SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len,  		unsigned long, prot, unsigned long, flags,  |