s390: switch to generic kernel_thread()
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
37fe5d41f6
commit
f9a7e025df
|
@ -125,6 +125,7 @@ config S390
|
|||
select GENERIC_CLOCKEVENTS
|
||||
select KTIME_SCALAR if 32BIT
|
||||
select HAVE_ARCH_SECCOMP_FILTER
|
||||
select GENERIC_KERNEL_THREAD
|
||||
|
||||
config SCHED_OMIT_FRAME_POINTER
|
||||
def_bool y
|
||||
|
|
|
@ -135,7 +135,6 @@ struct seq_file;
|
|||
|
||||
/* Free all resources held by a thread. */
|
||||
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.
|
||||
|
|
|
@ -98,25 +98,6 @@ void cpu_idle(void)
|
|||
|
||||
extern void __kprobes kernel_thread_starter(void);
|
||||
|
||||
int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
|
||||
{
|
||||
struct pt_regs regs;
|
||||
|
||||
memset(®s, 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, ®s, 0, NULL, NULL);
|
||||
}
|
||||
EXPORT_SYMBOL(kernel_thread);
|
||||
|
||||
/*
|
||||
* 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,
|
||||
unsigned long unused,
|
||||
unsigned long arg,
|
||||
struct task_struct *p, struct pt_regs *regs)
|
||||
{
|
||||
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);
|
||||
p->thread.ksp = (unsigned long) frame;
|
||||
/* Store access registers to kernel stack of new process. */
|
||||
frame->childregs = *regs;
|
||||
frame->childregs.gprs[2] = 0; /* child returns 0 on fork. */
|
||||
frame->childregs.gprs[15] = new_stackp;
|
||||
frame->sf.back_chain = 0;
|
||||
/* Save access registers to new thread structure. */
|
||||
save_access_regs(&p->thread.acrs[0]);
|
||||
/* 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;
|
||||
|
||||
frame->sf.back_chain = 0;
|
||||
/* new return point is ret_from_fork */
|
||||
frame->sf.gprs[8] = (unsigned long) ret_from_fork;
|
||||
|
||||
/* fake return stack for resume(), don't go back to schedule */
|
||||
frame->sf.gprs[9] = (unsigned long) frame;
|
||||
|
||||
/* Save access registers to new thread structure. */
|
||||
save_access_regs(&p->thread.acrs[0]);
|
||||
/* Store access registers to kernel stack of new process. */
|
||||
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
|
||||
/*
|
||||
|
@ -184,17 +189,6 @@ int copy_thread(unsigned long clone_flags, unsigned long new_stackp,
|
|||
}
|
||||
}
|
||||
#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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue