diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2012-09-21 20:48:32 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2012-09-30 23:03:03 -0400 |
commit | f9a7e025dfc28783fd2b05812e663251acf4bf21 (patch) | |
tree | b48ea29a01293afa82be905797268b7997852def /arch/s390 | |
parent | 37fe5d41f6403b0ea84c1586548bf1b03f834af0 (diff) |
s390: switch to generic kernel_thread()
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'arch/s390')
-rw-r--r-- | arch/s390/Kconfig | 1 | ||||
-rw-r--r-- | arch/s390/include/asm/processor.h | 1 | ||||
-rw-r--r-- | arch/s390/kernel/process.c | 72 |
3 files changed, 34 insertions, 40 deletions
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 107610e01a29..57442393bac7 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig | |||
@@ -125,6 +125,7 @@ config S390 | |||
125 | select GENERIC_CLOCKEVENTS | 125 | select GENERIC_CLOCKEVENTS |
126 | select KTIME_SCALAR if 32BIT | 126 | select KTIME_SCALAR if 32BIT |
127 | select HAVE_ARCH_SECCOMP_FILTER | 127 | select HAVE_ARCH_SECCOMP_FILTER |
128 | select GENERIC_KERNEL_THREAD | ||
128 | 129 | ||
129 | config SCHED_OMIT_FRAME_POINTER | 130 | config SCHED_OMIT_FRAME_POINTER |
130 | def_bool y | 131 | def_bool y |
diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h index 0bc77619c3a3..da6f5baeee5c 100644 --- a/arch/s390/include/asm/processor.h +++ b/arch/s390/include/asm/processor.h | |||
@@ -135,7 +135,6 @@ struct seq_file; | |||
135 | 135 | ||
136 | /* Free all resources held by a thread. */ | 136 | /* Free all resources held by a thread. */ |
137 | extern void release_thread(struct task_struct *); | 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 | * Return saved PC of a blocked thread. | 140 | * Return saved PC of a blocked thread. |
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index 2868a364ff94..bab088de4569 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c | |||
@@ -98,25 +98,6 @@ void cpu_idle(void) | |||
98 | 98 | ||
99 | extern void __kprobes kernel_thread_starter(void); | 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(®s, 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, ®s, 0, NULL, NULL); | ||
117 | } | ||
118 | EXPORT_SYMBOL(kernel_thread); | ||
119 | |||
120 | /* | 101 | /* |
121 | * Free current thread data structures etc.. | 102 | * Free current thread data structures etc.. |
122 | */ | 103 | */ |
@@ -133,7 +114,7 @@ void release_thread(struct task_struct *dead_task) | |||
133 | } | 114 | } |
134 | 115 | ||
135 | int copy_thread(unsigned long clone_flags, unsigned long new_stackp, | 116 | int copy_thread(unsigned long clone_flags, unsigned long new_stackp, |
136 | unsigned long unused, | 117 | unsigned long arg, |
137 | struct task_struct *p, struct pt_regs *regs) | 118 | struct task_struct *p, struct pt_regs *regs) |
138 | { | 119 | { |
139 | struct thread_info *ti; | 120 | struct thread_info *ti; |
@@ -145,20 +126,44 @@ int copy_thread(unsigned long clone_flags, unsigned long new_stackp, | |||
145 | 126 | ||
146 | frame = container_of(task_pt_regs(p), struct fake_frame, childregs); | 127 | frame = container_of(task_pt_regs(p), struct fake_frame, childregs); |
147 | p->thread.ksp = (unsigned long) frame; | 128 | p->thread.ksp = (unsigned long) frame; |
148 | /* Store access registers to kernel stack of new process. */ | 129 | /* Save access registers to new thread structure. */ |
149 | frame->childregs = *regs; | 130 | save_access_regs(&p->thread.acrs[0]); |
150 | frame->childregs.gprs[2] = 0; /* child returns 0 on fork. */ | 131 | /* start new process with ar4 pointing to the correct address space */ |
151 | frame->childregs.gprs[15] = new_stackp; | 132 | p->thread.mm_segment = get_fs(); |
152 | frame->sf.back_chain = 0; | 133 | /* Don't copy debug registers */ |
134 | memset(&p->thread.per_user, 0, sizeof(p->thread.per_user)); | ||
135 | memset(&p->thread.per_event, 0, sizeof(p->thread.per_event)); | ||
136 | clear_tsk_thread_flag(p, TIF_SINGLE_STEP); | ||
137 | clear_tsk_thread_flag(p, TIF_PER_TRAP); | ||
138 | /* Initialize per thread user and system timer values */ | ||
139 | ti = task_thread_info(p); | ||
140 | ti->user_timer = 0; | ||
141 | ti->system_timer = 0; | ||
153 | 142 | ||
143 | frame->sf.back_chain = 0; | ||
154 | /* new return point is ret_from_fork */ | 144 | /* new return point is ret_from_fork */ |
155 | frame->sf.gprs[8] = (unsigned long) ret_from_fork; | 145 | frame->sf.gprs[8] = (unsigned long) ret_from_fork; |
156 | |||
157 | /* fake return stack for resume(), don't go back to schedule */ | 146 | /* fake return stack for resume(), don't go back to schedule */ |
158 | frame->sf.gprs[9] = (unsigned long) frame; | 147 | frame->sf.gprs[9] = (unsigned long) frame; |
159 | 148 | ||
160 | /* Save access registers to new thread structure. */ | 149 | /* Store access registers to kernel stack of new process. */ |
161 | save_access_regs(&p->thread.acrs[0]); | 150 | if (unlikely(!regs)) { |
151 | /* kernel thread */ | ||
152 | memset(&frame->childregs, 0, sizeof(struct pt_regs)); | ||
153 | frame->childregs.psw.mask = psw_kernel_bits | PSW_MASK_DAT | | ||
154 | PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK; | ||
155 | frame->childregs.psw.addr = PSW_ADDR_AMODE | | ||
156 | (unsigned long) kernel_thread_starter; | ||
157 | frame->childregs.gprs[9] = new_stackp; /* function */ | ||
158 | frame->childregs.gprs[10] = arg; | ||
159 | frame->childregs.gprs[11] = (unsigned long) do_exit; | ||
160 | frame->childregs.orig_gpr2 = -1; | ||
161 | |||
162 | return 0; | ||
163 | } | ||
164 | frame->childregs = *regs; | ||
165 | frame->childregs.gprs[2] = 0; /* child returns 0 on fork. */ | ||
166 | frame->childregs.gprs[15] = new_stackp; | ||
162 | 167 | ||
163 | #ifndef CONFIG_64BIT | 168 | #ifndef CONFIG_64BIT |
164 | /* | 169 | /* |
@@ -184,17 +189,6 @@ int copy_thread(unsigned long clone_flags, unsigned long new_stackp, | |||
184 | } | 189 | } |
185 | } | 190 | } |
186 | #endif /* CONFIG_64BIT */ | 191 | #endif /* CONFIG_64BIT */ |
187 | /* start new process with ar4 pointing to the correct address space */ | ||
188 | p->thread.mm_segment = get_fs(); | ||
189 | /* Don't copy debug registers */ | ||
190 | memset(&p->thread.per_user, 0, sizeof(p->thread.per_user)); | ||
191 | memset(&p->thread.per_event, 0, sizeof(p->thread.per_event)); | ||
192 | clear_tsk_thread_flag(p, TIF_SINGLE_STEP); | ||
193 | clear_tsk_thread_flag(p, TIF_PER_TRAP); | ||
194 | /* Initialize per thread user and system timer values */ | ||
195 | ti = task_thread_info(p); | ||
196 | ti->user_timer = 0; | ||
197 | ti->system_timer = 0; | ||
198 | return 0; | 192 | return 0; |
199 | } | 193 | } |
200 | 194 | ||