Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f9a7e025 authored by Al Viro's avatar Al Viro
Browse files

s390: switch to generic kernel_thread()



Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 37fe5d41
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -125,6 +125,7 @@ config S390
	select GENERIC_CLOCKEVENTS
	select GENERIC_CLOCKEVENTS
	select KTIME_SCALAR if 32BIT
	select KTIME_SCALAR if 32BIT
	select HAVE_ARCH_SECCOMP_FILTER
	select HAVE_ARCH_SECCOMP_FILTER
	select GENERIC_KERNEL_THREAD


config SCHED_OMIT_FRAME_POINTER
config SCHED_OMIT_FRAME_POINTER
	def_bool y
	def_bool y
+0 −1
Original line number Original line Diff line number Diff line
@@ -135,7 +135,6 @@ struct seq_file;


/* Free all resources held by a thread. */
/* Free all resources held by a thread. */
extern void release_thread(struct task_struct *);
extern void release_thread(struct task_struct *);
extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);


/*
/*
 * Return saved PC of a blocked thread.
 * Return saved PC of a blocked thread.
+33 −39
Original line number Original line Diff line number Diff line
@@ -98,25 +98,6 @@ void cpu_idle(void)


extern void __kprobes kernel_thread_starter(void);
extern void __kprobes kernel_thread_starter(void);


int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
{
	struct pt_regs regs;

	memset(&regs, 0, sizeof(regs));
	regs.psw.mask = psw_kernel_bits |
		PSW_MASK_DAT | PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK;
	regs.psw.addr = (unsigned long) kernel_thread_starter | PSW_ADDR_AMODE;
	regs.gprs[9] = (unsigned long) fn;
	regs.gprs[10] = (unsigned long) arg;
	regs.gprs[11] = (unsigned long) do_exit;
	regs.orig_gpr2 = -1;

	/* Ok, create the new process.. */
	return do_fork(flags | CLONE_VM | CLONE_UNTRACED,
		       0, &regs, 0, NULL, NULL);
}
EXPORT_SYMBOL(kernel_thread);

/*
/*
 * Free current thread data structures etc..
 * Free current thread data structures etc..
 */
 */
@@ -133,7 +114,7 @@ void release_thread(struct task_struct *dead_task)
}
}


int copy_thread(unsigned long clone_flags, unsigned long new_stackp,
int copy_thread(unsigned long clone_flags, unsigned long new_stackp,
		unsigned long unused,
		unsigned long arg,
		struct task_struct *p, struct pt_regs *regs)
		struct task_struct *p, struct pt_regs *regs)
{
{
	struct thread_info *ti;
	struct thread_info *ti;
@@ -145,20 +126,44 @@ int copy_thread(unsigned long clone_flags, unsigned long new_stackp,


	frame = container_of(task_pt_regs(p), struct fake_frame, childregs);
	frame = container_of(task_pt_regs(p), struct fake_frame, childregs);
	p->thread.ksp = (unsigned long) frame;
	p->thread.ksp = (unsigned long) frame;
	/* Store access registers to kernel stack of new process. */
	/* Save access registers to new thread structure. */
	frame->childregs = *regs;
	save_access_regs(&p->thread.acrs[0]);
	frame->childregs.gprs[2] = 0;	/* child returns 0 on fork. */
	/* start new process with ar4 pointing to the correct address space */
	frame->childregs.gprs[15] = new_stackp;
	p->thread.mm_segment = get_fs();
	frame->sf.back_chain = 0;
	/* Don't copy debug registers */
	memset(&p->thread.per_user, 0, sizeof(p->thread.per_user));
	memset(&p->thread.per_event, 0, sizeof(p->thread.per_event));
	clear_tsk_thread_flag(p, TIF_SINGLE_STEP);
	clear_tsk_thread_flag(p, TIF_PER_TRAP);
	/* Initialize per thread user and system timer values */
	ti = task_thread_info(p);
	ti->user_timer = 0;
	ti->system_timer = 0;


	frame->sf.back_chain = 0;
	/* new return point is ret_from_fork */
	/* new return point is ret_from_fork */
	frame->sf.gprs[8] = (unsigned long) ret_from_fork;
	frame->sf.gprs[8] = (unsigned long) ret_from_fork;

	/* fake return stack for resume(), don't go back to schedule */
	/* fake return stack for resume(), don't go back to schedule */
	frame->sf.gprs[9] = (unsigned long) frame;
	frame->sf.gprs[9] = (unsigned long) frame;


	/* Save access registers to new thread structure. */
	/* Store access registers to kernel stack of new process. */
	save_access_regs(&p->thread.acrs[0]);
	if (unlikely(!regs)) {
		/* kernel thread */
		memset(&frame->childregs, 0, sizeof(struct pt_regs));
		frame->childregs.psw.mask = psw_kernel_bits | PSW_MASK_DAT |
				PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK;
		frame->childregs.psw.addr = PSW_ADDR_AMODE |
				(unsigned long) kernel_thread_starter;
		frame->childregs.gprs[9] = new_stackp; /* function */
		frame->childregs.gprs[10] = arg;
		frame->childregs.gprs[11] = (unsigned long) do_exit;
		frame->childregs.orig_gpr2 = -1;

		return 0;
	}
	frame->childregs = *regs;
	frame->childregs.gprs[2] = 0;	/* child returns 0 on fork. */
	frame->childregs.gprs[15] = new_stackp;


#ifndef CONFIG_64BIT
#ifndef CONFIG_64BIT
	/*
	/*
@@ -184,17 +189,6 @@ int copy_thread(unsigned long clone_flags, unsigned long new_stackp,
		}
		}
	}
	}
#endif /* CONFIG_64BIT */
#endif /* CONFIG_64BIT */
	/* start new process with ar4 pointing to the correct address space */
	p->thread.mm_segment = get_fs();
	/* Don't copy debug registers */
	memset(&p->thread.per_user, 0, sizeof(p->thread.per_user));
	memset(&p->thread.per_event, 0, sizeof(p->thread.per_event));
	clear_tsk_thread_flag(p, TIF_SINGLE_STEP);
	clear_tsk_thread_flag(p, TIF_PER_TRAP);
	/* Initialize per thread user and system timer values */
	ti = task_thread_info(p);
	ti->user_timer = 0;
	ti->system_timer = 0;
	return 0;
	return 0;
}
}