Loading arch/s390/Kconfig +1 −0 Original line number Original line Diff line number Diff line Loading @@ -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 Loading arch/s390/include/asm/processor.h +0 −1 Original line number Original line Diff line number Diff line Loading @@ -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. Loading arch/s390/kernel/process.c +33 −39 Original line number Original line Diff line number Diff line Loading @@ -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(®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.. * Free current thread data structures etc.. */ */ Loading @@ -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; Loading @@ -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 /* /* Loading @@ -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; } } Loading Loading
arch/s390/Kconfig +1 −0 Original line number Original line Diff line number Diff line Loading @@ -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 Loading
arch/s390/include/asm/processor.h +0 −1 Original line number Original line Diff line number Diff line Loading @@ -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. Loading
arch/s390/kernel/process.c +33 −39 Original line number Original line Diff line number Diff line Loading @@ -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(®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.. * Free current thread data structures etc.. */ */ Loading @@ -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; Loading @@ -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 /* /* Loading @@ -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; } } Loading