mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	m68k: split ret_from_fork(), simplify kernel_thread()
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
		
							parent
							
								
									0973c687e0
								
							
						
					
					
						commit
						533e6903be
					
				
					 4 changed files with 36 additions and 62 deletions
				
			
		| 
						 | 
				
			
			@ -13,6 +13,7 @@ config M68K
 | 
			
		|||
	select FPU if MMU
 | 
			
		||||
	select ARCH_WANT_IPC_PARSE_VERSION
 | 
			
		||||
	select ARCH_USES_GETTIMEOFFSET if MMU && !COLDFIRE
 | 
			
		||||
	select GENERIC_KERNEL_THREAD
 | 
			
		||||
 | 
			
		||||
config RWSEM_GENERIC_SPINLOCK
 | 
			
		||||
	bool
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -154,8 +154,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..
 | 
			
		||||
 */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -111,6 +111,17 @@ ENTRY(ret_from_fork)
 | 
			
		|||
	addql	#4,%sp
 | 
			
		||||
	jra	ret_from_exception
 | 
			
		||||
 | 
			
		||||
ENTRY(ret_from_kernel_thread)
 | 
			
		||||
	| a3 contains the kernel thread payload, d7 - its argument
 | 
			
		||||
	movel	%d1,%sp@-
 | 
			
		||||
	jsr	schedule_tail
 | 
			
		||||
	GET_CURRENT(%d0)
 | 
			
		||||
	movel	%d7,(%sp)
 | 
			
		||||
	jsr	%a3@
 | 
			
		||||
	addql	#4,%sp
 | 
			
		||||
	movel	%d0,(%sp)
 | 
			
		||||
	jra	sys_exit
 | 
			
		||||
 | 
			
		||||
#if defined(CONFIG_COLDFIRE) || !defined(CONFIG_MMU)
 | 
			
		||||
 | 
			
		||||
#ifdef TRAP_DBG_INTERRUPT
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -34,6 +34,7 @@
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
asmlinkage void ret_from_fork(void);
 | 
			
		||||
asmlinkage void ret_from_kernel_thread(void);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
| 
						 | 
				
			
			@ -120,51 +121,6 @@ void show_regs(struct pt_regs * regs)
 | 
			
		|||
		printk("USP: %08lx\n", rdusp());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Create a kernel thread
 | 
			
		||||
 */
 | 
			
		||||
int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
 | 
			
		||||
{
 | 
			
		||||
	int pid;
 | 
			
		||||
	mm_segment_t fs;
 | 
			
		||||
 | 
			
		||||
	fs = get_fs();
 | 
			
		||||
	set_fs (KERNEL_DS);
 | 
			
		||||
 | 
			
		||||
	{
 | 
			
		||||
	register long retval __asm__ ("d0");
 | 
			
		||||
	register long clone_arg __asm__ ("d1") = flags | CLONE_VM | CLONE_UNTRACED;
 | 
			
		||||
 | 
			
		||||
	retval = __NR_clone;
 | 
			
		||||
	__asm__ __volatile__
 | 
			
		||||
	  ("clrl %%d2\n\t"
 | 
			
		||||
	   "trap #0\n\t"		/* Linux/m68k system call */
 | 
			
		||||
	   "tstl %0\n\t"		/* child or parent */
 | 
			
		||||
	   "jne 1f\n\t"			/* parent - jump */
 | 
			
		||||
#ifdef CONFIG_MMU
 | 
			
		||||
	   "lea %%sp@(%c7),%6\n\t"	/* reload current */
 | 
			
		||||
	   "movel %6@,%6\n\t"
 | 
			
		||||
#endif
 | 
			
		||||
	   "movel %3,%%sp@-\n\t"	/* push argument */
 | 
			
		||||
	   "jsr %4@\n\t"		/* call fn */
 | 
			
		||||
	   "movel %0,%%d1\n\t"		/* pass exit value */
 | 
			
		||||
	   "movel %2,%%d0\n\t"		/* exit */
 | 
			
		||||
	   "trap #0\n"
 | 
			
		||||
	   "1:"
 | 
			
		||||
	   : "+d" (retval)
 | 
			
		||||
	   : "i" (__NR_clone), "i" (__NR_exit),
 | 
			
		||||
	     "r" (arg), "a" (fn), "d" (clone_arg), "r" (current),
 | 
			
		||||
	     "i" (-THREAD_SIZE)
 | 
			
		||||
	   : "d2");
 | 
			
		||||
 | 
			
		||||
	pid = retval;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	set_fs (fs);
 | 
			
		||||
	return pid;
 | 
			
		||||
}
 | 
			
		||||
EXPORT_SYMBOL(kernel_thread);
 | 
			
		||||
 | 
			
		||||
void flush_thread(void)
 | 
			
		||||
{
 | 
			
		||||
	current->thread.fs = __USER_DS;
 | 
			
		||||
| 
						 | 
				
			
			@ -216,30 +172,18 @@ asmlinkage int m68k_clone(struct pt_regs *regs)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
int copy_thread(unsigned long clone_flags, unsigned long usp,
 | 
			
		||||
		 unsigned long unused,
 | 
			
		||||
		 unsigned long arg,
 | 
			
		||||
		 struct task_struct * p, struct pt_regs * regs)
 | 
			
		||||
{
 | 
			
		||||
	struct pt_regs * childregs;
 | 
			
		||||
	struct switch_stack * childstack, *stack;
 | 
			
		||||
	unsigned long *retp;
 | 
			
		||||
	struct switch_stack *childstack;
 | 
			
		||||
 | 
			
		||||
	childregs = (struct pt_regs *) (task_stack_page(p) + THREAD_SIZE) - 1;
 | 
			
		||||
 | 
			
		||||
	*childregs = *regs;
 | 
			
		||||
	childregs->d0 = 0;
 | 
			
		||||
 | 
			
		||||
	retp = ((unsigned long *) regs);
 | 
			
		||||
	stack = ((struct switch_stack *) retp) - 1;
 | 
			
		||||
 | 
			
		||||
	childstack = ((struct switch_stack *) childregs) - 1;
 | 
			
		||||
	*childstack = *stack;
 | 
			
		||||
	childstack->retpc = (unsigned long)ret_from_fork;
 | 
			
		||||
 | 
			
		||||
	p->thread.usp = usp;
 | 
			
		||||
	p->thread.ksp = (unsigned long)childstack;
 | 
			
		||||
 | 
			
		||||
	if (clone_flags & CLONE_SETTLS)
 | 
			
		||||
		task_thread_info(p)->tp_value = regs->d5;
 | 
			
		||||
	p->thread.esp0 = (unsigned long)childregs;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Must save the current SFC/DFC value, NOT the value when
 | 
			
		||||
| 
						 | 
				
			
			@ -247,6 +191,26 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
 | 
			
		|||
	 */
 | 
			
		||||
	p->thread.fs = get_fs().seg;
 | 
			
		||||
 | 
			
		||||
	if (unlikely(!regs)) {
 | 
			
		||||
		/* kernel thread */
 | 
			
		||||
		memset(childstack, 0,
 | 
			
		||||
			sizeof(struct switch_stack) + sizeof(struct pt_regs));
 | 
			
		||||
		childregs->sr = PS_S;
 | 
			
		||||
		childstack->a3 = usp; /* function */
 | 
			
		||||
		childstack->d7 = arg;
 | 
			
		||||
		childstack->retpc = (unsigned long)ret_from_kernel_thread;
 | 
			
		||||
		p->thread.usp = 0;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
	*childregs = *regs;
 | 
			
		||||
	childregs->d0 = 0;
 | 
			
		||||
 | 
			
		||||
	*childstack = ((struct switch_stack *) regs)[-1];
 | 
			
		||||
	childstack->retpc = (unsigned long)ret_from_fork;
 | 
			
		||||
 | 
			
		||||
	if (clone_flags & CLONE_SETTLS)
 | 
			
		||||
		task_thread_info(p)->tp_value = regs->d5;
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_FPU
 | 
			
		||||
	if (!FPU_IS_EMU) {
 | 
			
		||||
		/* Copy the current fpu state */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue