aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel/process_32.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/kernel/process_32.c')
-rw-r--r--arch/sh/kernel/process_32.c87
1 files changed, 19 insertions, 68 deletions
diff --git a/arch/sh/kernel/process_32.c b/arch/sh/kernel/process_32.c
index ba7345f37bc9..fce8029de922 100644
--- a/arch/sh/kernel/process_32.c
+++ b/arch/sh/kernel/process_32.c
@@ -68,38 +68,6 @@ void show_regs(struct pt_regs * regs)
68 show_code(regs); 68 show_code(regs);
69} 69}
70 70
71/*
72 * Create a kernel thread
73 */
74__noreturn void kernel_thread_helper(void *arg, int (*fn)(void *))
75{
76 do_exit(fn(arg));
77}
78
79/* Don't use this in BL=1(cli). Or else, CPU resets! */
80int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
81{
82 struct pt_regs regs;
83 int pid;
84
85 memset(&regs, 0, sizeof(regs));
86 regs.regs[4] = (unsigned long)arg;
87 regs.regs[5] = (unsigned long)fn;
88
89 regs.pc = (unsigned long)kernel_thread_helper;
90 regs.sr = SR_MD;
91#if defined(CONFIG_SH_FPU)
92 regs.sr |= SR_FD;
93#endif
94
95 /* Ok, create the new process.. */
96 pid = do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0,
97 &regs, 0, NULL, NULL);
98
99 return pid;
100}
101EXPORT_SYMBOL(kernel_thread);
102
103void start_thread(struct pt_regs *regs, unsigned long new_pc, 71void start_thread(struct pt_regs *regs, unsigned long new_pc,
104 unsigned long new_sp) 72 unsigned long new_sp)
105{ 73{
@@ -157,9 +125,10 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu)
157EXPORT_SYMBOL(dump_fpu); 125EXPORT_SYMBOL(dump_fpu);
158 126
159asmlinkage void ret_from_fork(void); 127asmlinkage void ret_from_fork(void);
128asmlinkage void ret_from_kernel_thread(void);
160 129
161int copy_thread(unsigned long clone_flags, unsigned long usp, 130int copy_thread(unsigned long clone_flags, unsigned long usp,
162 unsigned long unused, 131 unsigned long arg,
163 struct task_struct *p, struct pt_regs *regs) 132 struct task_struct *p, struct pt_regs *regs)
164{ 133{
165 struct thread_info *ti = task_thread_info(p); 134 struct thread_info *ti = task_thread_info(p);
@@ -177,29 +146,34 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
177 } 146 }
178#endif 147#endif
179 148
180 childregs = task_pt_regs(p); 149 memset(p->thread.ptrace_bps, 0, sizeof(p->thread.ptrace_bps));
181 *childregs = *regs;
182 150
183 if (user_mode(regs)) { 151 childregs = task_pt_regs(p);
184 childregs->regs[15] = usp; 152 p->thread.sp = (unsigned long) childregs;
185 ti->addr_limit = USER_DS; 153 if (unlikely(p->flags & PF_KTHREAD)) {
186 } else { 154 memset(childregs, 0, sizeof(struct pt_regs));
187 childregs->regs[15] = (unsigned long)childregs; 155 p->thread.pc = (unsigned long) ret_from_kernel_thread;
156 childregs->regs[4] = arg;
157 childregs->regs[5] = usp;
158 childregs->sr = SR_MD;
159#if defined(CONFIG_SH_FPU)
160 childregs->sr |= SR_FD;
161#endif
188 ti->addr_limit = KERNEL_DS; 162 ti->addr_limit = KERNEL_DS;
189 ti->status &= ~TS_USEDFPU; 163 ti->status &= ~TS_USEDFPU;
190 p->fpu_counter = 0; 164 p->fpu_counter = 0;
165 return 0;
191 } 166 }
167 *childregs = *regs;
168
169 childregs->regs[15] = usp;
170 ti->addr_limit = USER_DS;
192 171
193 if (clone_flags & CLONE_SETTLS) 172 if (clone_flags & CLONE_SETTLS)
194 childregs->gbr = childregs->regs[0]; 173 childregs->gbr = childregs->regs[0];
195 174
196 childregs->regs[0] = 0; /* Set return value for child */ 175 childregs->regs[0] = 0; /* Set return value for child */
197
198 p->thread.sp = (unsigned long) childregs;
199 p->thread.pc = (unsigned long) ret_from_fork; 176 p->thread.pc = (unsigned long) ret_from_fork;
200
201 memset(p->thread.ptrace_bps, 0, sizeof(p->thread.ptrace_bps));
202
203 return 0; 177 return 0;
204} 178}
205 179
@@ -288,29 +262,6 @@ asmlinkage int sys_vfork(unsigned long r4, unsigned long r5,
288 0, NULL, NULL); 262 0, NULL, NULL);
289} 263}
290 264
291/*
292 * sys_execve() executes a new program.
293 */
294asmlinkage int sys_execve(const char __user *ufilename,
295 const char __user *const __user *uargv,
296 const char __user *const __user *uenvp,
297 unsigned long r7, struct pt_regs __regs)
298{
299 struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
300 int error;
301 struct filename *filename;
302
303 filename = getname(ufilename);
304 error = PTR_ERR(filename);
305 if (IS_ERR(filename))
306 goto out;
307
308 error = do_execve(filename->name, uargv, uenvp, regs);
309 putname(filename);
310out:
311 return error;
312}
313
314unsigned long get_wchan(struct task_struct *p) 265unsigned long get_wchan(struct task_struct *p)
315{ 266{
316 unsigned long pc; 267 unsigned long pc;