diff options
Diffstat (limited to 'arch/m68k/kernel/process.c')
-rw-r--r-- | arch/m68k/kernel/process.c | 104 |
1 files changed, 24 insertions, 80 deletions
diff --git a/arch/m68k/kernel/process.c b/arch/m68k/kernel/process.c index ac2892e49c7c..c51bb172e14d 100644 --- a/arch/m68k/kernel/process.c +++ b/arch/m68k/kernel/process.c | |||
@@ -35,6 +35,7 @@ | |||
35 | 35 | ||
36 | 36 | ||
37 | asmlinkage void ret_from_fork(void); | 37 | asmlinkage void ret_from_fork(void); |
38 | asmlinkage void ret_from_kernel_thread(void); | ||
38 | 39 | ||
39 | 40 | ||
40 | /* | 41 | /* |
@@ -123,51 +124,6 @@ void show_regs(struct pt_regs * regs) | |||
123 | printk("USP: %08lx\n", rdusp()); | 124 | printk("USP: %08lx\n", rdusp()); |
124 | } | 125 | } |
125 | 126 | ||
126 | /* | ||
127 | * Create a kernel thread | ||
128 | */ | ||
129 | int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) | ||
130 | { | ||
131 | int pid; | ||
132 | mm_segment_t fs; | ||
133 | |||
134 | fs = get_fs(); | ||
135 | set_fs (KERNEL_DS); | ||
136 | |||
137 | { | ||
138 | register long retval __asm__ ("d0"); | ||
139 | register long clone_arg __asm__ ("d1") = flags | CLONE_VM | CLONE_UNTRACED; | ||
140 | |||
141 | retval = __NR_clone; | ||
142 | __asm__ __volatile__ | ||
143 | ("clrl %%d2\n\t" | ||
144 | "trap #0\n\t" /* Linux/m68k system call */ | ||
145 | "tstl %0\n\t" /* child or parent */ | ||
146 | "jne 1f\n\t" /* parent - jump */ | ||
147 | #ifdef CONFIG_MMU | ||
148 | "lea %%sp@(%c7),%6\n\t" /* reload current */ | ||
149 | "movel %6@,%6\n\t" | ||
150 | #endif | ||
151 | "movel %3,%%sp@-\n\t" /* push argument */ | ||
152 | "jsr %4@\n\t" /* call fn */ | ||
153 | "movel %0,%%d1\n\t" /* pass exit value */ | ||
154 | "movel %2,%%d0\n\t" /* exit */ | ||
155 | "trap #0\n" | ||
156 | "1:" | ||
157 | : "+d" (retval) | ||
158 | : "i" (__NR_clone), "i" (__NR_exit), | ||
159 | "r" (arg), "a" (fn), "d" (clone_arg), "r" (current), | ||
160 | "i" (-THREAD_SIZE) | ||
161 | : "d2"); | ||
162 | |||
163 | pid = retval; | ||
164 | } | ||
165 | |||
166 | set_fs (fs); | ||
167 | return pid; | ||
168 | } | ||
169 | EXPORT_SYMBOL(kernel_thread); | ||
170 | |||
171 | void flush_thread(void) | 127 | void flush_thread(void) |
172 | { | 128 | { |
173 | current->thread.fs = __USER_DS; | 129 | current->thread.fs = __USER_DS; |
@@ -219,30 +175,18 @@ asmlinkage int m68k_clone(struct pt_regs *regs) | |||
219 | } | 175 | } |
220 | 176 | ||
221 | int copy_thread(unsigned long clone_flags, unsigned long usp, | 177 | int copy_thread(unsigned long clone_flags, unsigned long usp, |
222 | unsigned long unused, | 178 | unsigned long arg, |
223 | struct task_struct * p, struct pt_regs * regs) | 179 | struct task_struct * p, struct pt_regs * regs) |
224 | { | 180 | { |
225 | struct pt_regs * childregs; | 181 | struct pt_regs * childregs; |
226 | struct switch_stack * childstack, *stack; | 182 | struct switch_stack *childstack; |
227 | unsigned long *retp; | ||
228 | 183 | ||
229 | childregs = (struct pt_regs *) (task_stack_page(p) + THREAD_SIZE) - 1; | 184 | childregs = (struct pt_regs *) (task_stack_page(p) + THREAD_SIZE) - 1; |
230 | |||
231 | *childregs = *regs; | ||
232 | childregs->d0 = 0; | ||
233 | |||
234 | retp = ((unsigned long *) regs); | ||
235 | stack = ((struct switch_stack *) retp) - 1; | ||
236 | |||
237 | childstack = ((struct switch_stack *) childregs) - 1; | 185 | childstack = ((struct switch_stack *) childregs) - 1; |
238 | *childstack = *stack; | ||
239 | childstack->retpc = (unsigned long)ret_from_fork; | ||
240 | 186 | ||
241 | p->thread.usp = usp; | 187 | p->thread.usp = usp; |
242 | p->thread.ksp = (unsigned long)childstack; | 188 | p->thread.ksp = (unsigned long)childstack; |
243 | 189 | p->thread.esp0 = (unsigned long)childregs; | |
244 | if (clone_flags & CLONE_SETTLS) | ||
245 | task_thread_info(p)->tp_value = regs->d5; | ||
246 | 190 | ||
247 | /* | 191 | /* |
248 | * Must save the current SFC/DFC value, NOT the value when | 192 | * Must save the current SFC/DFC value, NOT the value when |
@@ -250,6 +194,26 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, | |||
250 | */ | 194 | */ |
251 | p->thread.fs = get_fs().seg; | 195 | p->thread.fs = get_fs().seg; |
252 | 196 | ||
197 | if (unlikely(!regs)) { | ||
198 | /* kernel thread */ | ||
199 | memset(childstack, 0, | ||
200 | sizeof(struct switch_stack) + sizeof(struct pt_regs)); | ||
201 | childregs->sr = PS_S; | ||
202 | childstack->a3 = usp; /* function */ | ||
203 | childstack->d7 = arg; | ||
204 | childstack->retpc = (unsigned long)ret_from_kernel_thread; | ||
205 | p->thread.usp = 0; | ||
206 | return 0; | ||
207 | } | ||
208 | *childregs = *regs; | ||
209 | childregs->d0 = 0; | ||
210 | |||
211 | *childstack = ((struct switch_stack *) regs)[-1]; | ||
212 | childstack->retpc = (unsigned long)ret_from_fork; | ||
213 | |||
214 | if (clone_flags & CLONE_SETTLS) | ||
215 | task_thread_info(p)->tp_value = regs->d5; | ||
216 | |||
253 | #ifdef CONFIG_FPU | 217 | #ifdef CONFIG_FPU |
254 | if (!FPU_IS_EMU) { | 218 | if (!FPU_IS_EMU) { |
255 | /* Copy the current fpu state */ | 219 | /* Copy the current fpu state */ |
@@ -337,26 +301,6 @@ int dump_fpu (struct pt_regs *regs, struct user_m68kfp_struct *fpu) | |||
337 | EXPORT_SYMBOL(dump_fpu); | 301 | EXPORT_SYMBOL(dump_fpu); |
338 | #endif /* CONFIG_FPU */ | 302 | #endif /* CONFIG_FPU */ |
339 | 303 | ||
340 | /* | ||
341 | * sys_execve() executes a new program. | ||
342 | */ | ||
343 | asmlinkage int sys_execve(const char __user *name, | ||
344 | const char __user *const __user *argv, | ||
345 | const char __user *const __user *envp) | ||
346 | { | ||
347 | int error; | ||
348 | char * filename; | ||
349 | struct pt_regs *regs = (struct pt_regs *) &name; | ||
350 | |||
351 | filename = getname(name); | ||
352 | error = PTR_ERR(filename); | ||
353 | if (IS_ERR(filename)) | ||
354 | return error; | ||
355 | error = do_execve(filename, argv, envp, regs); | ||
356 | putname(filename); | ||
357 | return error; | ||
358 | } | ||
359 | |||
360 | unsigned long get_wchan(struct task_struct *p) | 304 | unsigned long get_wchan(struct task_struct *p) |
361 | { | 305 | { |
362 | unsigned long fp, pc; | 306 | unsigned long fp, pc; |