···125125 select GENERIC_CLOCKEVENTS126126 select KTIME_SCALAR if 32BIT127127 select HAVE_ARCH_SECCOMP_FILTER128128+ select GENERIC_KERNEL_THREAD128129129130config SCHED_OMIT_FRAME_POINTER130131 def_bool y
-1
arch/s390/include/asm/processor.h
···135135136136/* Free all resources held by a thread. */137137extern void release_thread(struct task_struct *);138138-extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);139138140139/*141140 * Return saved PC of a blocked thread.
+33-39
arch/s390/kernel/process.c
···98989999extern void __kprobes kernel_thread_starter(void);100100101101-int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)102102-{103103- struct pt_regs regs;104104-105105- memset(®s, 0, sizeof(regs));106106- regs.psw.mask = psw_kernel_bits |107107- PSW_MASK_DAT | PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK;108108- regs.psw.addr = (unsigned long) kernel_thread_starter | PSW_ADDR_AMODE;109109- regs.gprs[9] = (unsigned long) fn;110110- regs.gprs[10] = (unsigned long) arg;111111- regs.gprs[11] = (unsigned long) do_exit;112112- regs.orig_gpr2 = -1;113113-114114- /* Ok, create the new process.. */115115- return do_fork(flags | CLONE_VM | CLONE_UNTRACED,116116- 0, ®s, 0, NULL, NULL);117117-}118118-EXPORT_SYMBOL(kernel_thread);119119-120101/*121102 * Free current thread data structures etc..122103 */···114133}115134116135int copy_thread(unsigned long clone_flags, unsigned long new_stackp,117117- unsigned long unused,136136+ unsigned long arg,118137 struct task_struct *p, struct pt_regs *regs)119138{120139 struct thread_info *ti;···126145127146 frame = container_of(task_pt_regs(p), struct fake_frame, childregs);128147 p->thread.ksp = (unsigned long) frame;129129- /* Store access registers to kernel stack of new process. */130130- frame->childregs = *regs;131131- frame->childregs.gprs[2] = 0; /* child returns 0 on fork. */132132- frame->childregs.gprs[15] = new_stackp;133133- frame->sf.back_chain = 0;148148+ /* Save access registers to new thread structure. */149149+ save_access_regs(&p->thread.acrs[0]);150150+ /* start new process with ar4 pointing to the correct address space */151151+ p->thread.mm_segment = get_fs();152152+ /* Don't copy debug registers */153153+ memset(&p->thread.per_user, 0, sizeof(p->thread.per_user));154154+ memset(&p->thread.per_event, 0, sizeof(p->thread.per_event));155155+ clear_tsk_thread_flag(p, TIF_SINGLE_STEP);156156+ clear_tsk_thread_flag(p, TIF_PER_TRAP);157157+ /* Initialize per thread user and system timer values */158158+ ti = task_thread_info(p);159159+ ti->user_timer = 0;160160+ ti->system_timer = 0;134161162162+ frame->sf.back_chain = 0;135163 /* new return point is ret_from_fork */136164 frame->sf.gprs[8] = (unsigned long) ret_from_fork;137137-138165 /* fake return stack for resume(), don't go back to schedule */139166 frame->sf.gprs[9] = (unsigned long) frame;140167141141- /* Save access registers to new thread structure. */142142- save_access_regs(&p->thread.acrs[0]);168168+ /* Store access registers to kernel stack of new process. */169169+ if (unlikely(!regs)) {170170+ /* kernel thread */171171+ memset(&frame->childregs, 0, sizeof(struct pt_regs));172172+ frame->childregs.psw.mask = psw_kernel_bits | PSW_MASK_DAT |173173+ PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK;174174+ frame->childregs.psw.addr = PSW_ADDR_AMODE |175175+ (unsigned long) kernel_thread_starter;176176+ frame->childregs.gprs[9] = new_stackp; /* function */177177+ frame->childregs.gprs[10] = arg;178178+ frame->childregs.gprs[11] = (unsigned long) do_exit;179179+ frame->childregs.orig_gpr2 = -1;180180+181181+ return 0;182182+ }183183+ frame->childregs = *regs;184184+ frame->childregs.gprs[2] = 0; /* child returns 0 on fork. */185185+ frame->childregs.gprs[15] = new_stackp;143186144187#ifndef CONFIG_64BIT145188 /*···189184 }190185 }191186#endif /* CONFIG_64BIT */192192- /* start new process with ar4 pointing to the correct address space */193193- p->thread.mm_segment = get_fs();194194- /* Don't copy debug registers */195195- memset(&p->thread.per_user, 0, sizeof(p->thread.per_user));196196- memset(&p->thread.per_event, 0, sizeof(p->thread.per_event));197197- clear_tsk_thread_flag(p, TIF_SINGLE_STEP);198198- clear_tsk_thread_flag(p, TIF_PER_TRAP);199199- /* Initialize per thread user and system timer values */200200- ti = task_thread_info(p);201201- ti->user_timer = 0;202202- ti->system_timer = 0;203187 return 0;204188}205189