diff options
author | David Howells <dhowells@redhat.com> | 2010-10-27 12:29:01 -0400 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2010-10-27 12:29:01 -0400 |
commit | 7c7fcf762e405eb040ee10d22d656a791f616122 (patch) | |
tree | 2ec4f320fe2d348ffbdab6aebc9a36bcbf13da34 /arch/mn10300/kernel/process.c | |
parent | a5e03ca2fd57a5823b759981bff8d19b46ddad4d (diff) |
MN10300: Save frame pointer in thread_info struct rather than global var
Save the current exception frame pointer in the thread_info struct rather than
in a global variable as the latter makes SMP tricky, especially when preemption
is also enabled.
This also replaces __frame with current_frame() and rearranges header file
inclusions to make it all compile.
Signed-off-by: David Howells <dhowells@redhat.com>
Acked-by: Akira Takeuchi <takeuchi.akr@jp.panasonic.com>
Diffstat (limited to 'arch/mn10300/kernel/process.c')
-rw-r--r-- | arch/mn10300/kernel/process.c | 20 |
1 files changed, 11 insertions, 9 deletions
diff --git a/arch/mn10300/kernel/process.c b/arch/mn10300/kernel/process.c index b2e85ed73a54..0d0f8049a17b 100644 --- a/arch/mn10300/kernel/process.c +++ b/arch/mn10300/kernel/process.c | |||
@@ -228,6 +228,7 @@ int copy_thread(unsigned long clone_flags, | |||
228 | unsigned long c_usp, unsigned long ustk_size, | 228 | unsigned long c_usp, unsigned long ustk_size, |
229 | struct task_struct *p, struct pt_regs *kregs) | 229 | struct task_struct *p, struct pt_regs *kregs) |
230 | { | 230 | { |
231 | struct thread_info *ti = task_thread_info(p); | ||
231 | struct pt_regs *c_uregs, *c_kregs, *uregs; | 232 | struct pt_regs *c_uregs, *c_kregs, *uregs; |
232 | unsigned long c_ksp; | 233 | unsigned long c_ksp; |
233 | 234 | ||
@@ -248,7 +249,7 @@ int copy_thread(unsigned long clone_flags, | |||
248 | 249 | ||
249 | /* the new TLS pointer is passed in as arg #5 to sys_clone() */ | 250 | /* the new TLS pointer is passed in as arg #5 to sys_clone() */ |
250 | if (clone_flags & CLONE_SETTLS) | 251 | if (clone_flags & CLONE_SETTLS) |
251 | c_uregs->e2 = __frame->d3; | 252 | c_uregs->e2 = current_frame()->d3; |
252 | 253 | ||
253 | /* set up the return kernel frame if called from kernel_thread() */ | 254 | /* set up the return kernel frame if called from kernel_thread() */ |
254 | c_kregs = c_uregs; | 255 | c_kregs = c_uregs; |
@@ -266,7 +267,7 @@ int copy_thread(unsigned long clone_flags, | |||
266 | } | 267 | } |
267 | 268 | ||
268 | /* set up things up so the scheduler can start the new task */ | 269 | /* set up things up so the scheduler can start the new task */ |
269 | p->thread.frame = c_kregs; | 270 | ti->frame = c_kregs; |
270 | p->thread.a3 = (unsigned long) c_kregs; | 271 | p->thread.a3 = (unsigned long) c_kregs; |
271 | p->thread.sp = c_ksp; | 272 | p->thread.sp = c_ksp; |
272 | p->thread.pc = (unsigned long) ret_from_fork; | 273 | p->thread.pc = (unsigned long) ret_from_fork; |
@@ -278,25 +279,26 @@ int copy_thread(unsigned long clone_flags, | |||
278 | 279 | ||
279 | /* | 280 | /* |
280 | * clone a process | 281 | * clone a process |
281 | * - tlsptr is retrieved by copy_thread() from __frame->d3 | 282 | * - tlsptr is retrieved by copy_thread() from current_frame()->d3 |
282 | */ | 283 | */ |
283 | asmlinkage long sys_clone(unsigned long clone_flags, unsigned long newsp, | 284 | asmlinkage long sys_clone(unsigned long clone_flags, unsigned long newsp, |
284 | int __user *parent_tidptr, int __user *child_tidptr, | 285 | int __user *parent_tidptr, int __user *child_tidptr, |
285 | int __user *tlsptr) | 286 | int __user *tlsptr) |
286 | { | 287 | { |
287 | return do_fork(clone_flags, newsp ?: __frame->sp, __frame, 0, | 288 | return do_fork(clone_flags, newsp ?: current_frame()->sp, |
288 | parent_tidptr, child_tidptr); | 289 | current_frame(), 0, parent_tidptr, child_tidptr); |
289 | } | 290 | } |
290 | 291 | ||
291 | asmlinkage long sys_fork(void) | 292 | asmlinkage long sys_fork(void) |
292 | { | 293 | { |
293 | return do_fork(SIGCHLD, __frame->sp, __frame, 0, NULL, NULL); | 294 | return do_fork(SIGCHLD, current_frame()->sp, |
295 | current_frame(), 0, NULL, NULL); | ||
294 | } | 296 | } |
295 | 297 | ||
296 | asmlinkage long sys_vfork(void) | 298 | asmlinkage long sys_vfork(void) |
297 | { | 299 | { |
298 | return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, __frame->sp, __frame, | 300 | return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, current_frame()->sp, |
299 | 0, NULL, NULL); | 301 | current_frame(), 0, NULL, NULL); |
300 | } | 302 | } |
301 | 303 | ||
302 | asmlinkage long sys_execve(const char __user *name, | 304 | asmlinkage long sys_execve(const char __user *name, |
@@ -310,7 +312,7 @@ asmlinkage long sys_execve(const char __user *name, | |||
310 | error = PTR_ERR(filename); | 312 | error = PTR_ERR(filename); |
311 | if (IS_ERR(filename)) | 313 | if (IS_ERR(filename)) |
312 | return error; | 314 | return error; |
313 | error = do_execve(filename, argv, envp, __frame); | 315 | error = do_execve(filename, argv, envp, current_frame()); |
314 | putname(filename); | 316 | putname(filename); |
315 | return error; | 317 | return error; |
316 | } | 318 | } |