Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

s390: switch to generic kernel_thread()

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Al Viro f9a7e025 37fe5d41

+34 -40
+1
arch/s390/Kconfig
··· 125 125 select GENERIC_CLOCKEVENTS 126 126 select KTIME_SCALAR if 32BIT 127 127 select HAVE_ARCH_SECCOMP_FILTER 128 + select GENERIC_KERNEL_THREAD 128 129 129 130 config SCHED_OMIT_FRAME_POINTER 130 131 def_bool y
-1
arch/s390/include/asm/processor.h
··· 135 135 136 136 /* Free all resources held by a thread. */ 137 137 extern void release_thread(struct task_struct *); 138 - extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); 139 138 140 139 /* 141 140 * Return saved PC of a blocked thread.
+33 -39
arch/s390/kernel/process.c
··· 98 98 99 99 extern void __kprobes kernel_thread_starter(void); 100 100 101 - int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) 102 - { 103 - struct pt_regs regs; 104 - 105 - memset(&regs, 0, sizeof(regs)); 106 - regs.psw.mask = psw_kernel_bits | 107 - PSW_MASK_DAT | PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK; 108 - regs.psw.addr = (unsigned long) kernel_thread_starter | PSW_ADDR_AMODE; 109 - regs.gprs[9] = (unsigned long) fn; 110 - regs.gprs[10] = (unsigned long) arg; 111 - regs.gprs[11] = (unsigned long) do_exit; 112 - regs.orig_gpr2 = -1; 113 - 114 - /* Ok, create the new process.. */ 115 - return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 116 - 0, &regs, 0, NULL, NULL); 117 - } 118 - EXPORT_SYMBOL(kernel_thread); 119 - 120 101 /* 121 102 * Free current thread data structures etc.. 122 103 */ ··· 114 133 } 115 134 116 135 int copy_thread(unsigned long clone_flags, unsigned long new_stackp, 117 - unsigned long unused, 136 + unsigned long arg, 118 137 struct task_struct *p, struct pt_regs *regs) 119 138 { 120 139 struct thread_info *ti; ··· 126 145 127 146 frame = container_of(task_pt_regs(p), struct fake_frame, childregs); 128 147 p->thread.ksp = (unsigned long) frame; 129 - /* Store access registers to kernel stack of new process. */ 130 - frame->childregs = *regs; 131 - frame->childregs.gprs[2] = 0; /* child returns 0 on fork. */ 132 - frame->childregs.gprs[15] = new_stackp; 133 - frame->sf.back_chain = 0; 148 + /* Save access registers to new thread structure. */ 149 + save_access_regs(&p->thread.acrs[0]); 150 + /* start new process with ar4 pointing to the correct address space */ 151 + p->thread.mm_segment = get_fs(); 152 + /* Don't copy debug registers */ 153 + memset(&p->thread.per_user, 0, sizeof(p->thread.per_user)); 154 + memset(&p->thread.per_event, 0, sizeof(p->thread.per_event)); 155 + clear_tsk_thread_flag(p, TIF_SINGLE_STEP); 156 + clear_tsk_thread_flag(p, TIF_PER_TRAP); 157 + /* Initialize per thread user and system timer values */ 158 + ti = task_thread_info(p); 159 + ti->user_timer = 0; 160 + ti->system_timer = 0; 134 161 162 + frame->sf.back_chain = 0; 135 163 /* new return point is ret_from_fork */ 136 164 frame->sf.gprs[8] = (unsigned long) ret_from_fork; 137 - 138 165 /* fake return stack for resume(), don't go back to schedule */ 139 166 frame->sf.gprs[9] = (unsigned long) frame; 140 167 141 - /* Save access registers to new thread structure. */ 142 - save_access_regs(&p->thread.acrs[0]); 168 + /* Store access registers to kernel stack of new process. */ 169 + if (unlikely(!regs)) { 170 + /* kernel thread */ 171 + memset(&frame->childregs, 0, sizeof(struct pt_regs)); 172 + frame->childregs.psw.mask = psw_kernel_bits | PSW_MASK_DAT | 173 + PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK; 174 + frame->childregs.psw.addr = PSW_ADDR_AMODE | 175 + (unsigned long) kernel_thread_starter; 176 + frame->childregs.gprs[9] = new_stackp; /* function */ 177 + frame->childregs.gprs[10] = arg; 178 + frame->childregs.gprs[11] = (unsigned long) do_exit; 179 + frame->childregs.orig_gpr2 = -1; 180 + 181 + return 0; 182 + } 183 + frame->childregs = *regs; 184 + frame->childregs.gprs[2] = 0; /* child returns 0 on fork. */ 185 + frame->childregs.gprs[15] = new_stackp; 143 186 144 187 #ifndef CONFIG_64BIT 145 188 /* ··· 189 184 } 190 185 } 191 186 #endif /* CONFIG_64BIT */ 192 - /* start new process with ar4 pointing to the correct address space */ 193 - p->thread.mm_segment = get_fs(); 194 - /* Don't copy debug registers */ 195 - memset(&p->thread.per_user, 0, sizeof(p->thread.per_user)); 196 - memset(&p->thread.per_event, 0, sizeof(p->thread.per_event)); 197 - clear_tsk_thread_flag(p, TIF_SINGLE_STEP); 198 - clear_tsk_thread_flag(p, TIF_PER_TRAP); 199 - /* Initialize per thread user and system timer values */ 200 - ti = task_thread_info(p); 201 - ti->user_timer = 0; 202 - ti->system_timer = 0; 203 187 return 0; 204 188 } 205 189