diff options
author | David Howells <dhowells@redhat.com> | 2010-10-27 17:29:01 +0100 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2010-10-27 17:29:01 +0100 |
commit | 7c7fcf762e405eb040ee10d22d656a791f616122 (patch) | |
tree | 2ec4f320fe2d348ffbdab6aebc9a36bcbf13da34 /arch/mn10300/kernel | |
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')
-rw-r--r-- | arch/mn10300/kernel/asm-offsets.c | 2 | ||||
-rw-r--r-- | arch/mn10300/kernel/mn10300-watchdog.c | 2 | ||||
-rw-r--r-- | arch/mn10300/kernel/process.c | 20 | ||||
-rw-r--r-- | arch/mn10300/kernel/signal.c | 20 | ||||
-rw-r--r-- | arch/mn10300/kernel/switch_to.S | 18 | ||||
-rw-r--r-- | arch/mn10300/kernel/traps.c | 8 |
6 files changed, 24 insertions, 46 deletions
diff --git a/arch/mn10300/kernel/asm-offsets.c b/arch/mn10300/kernel/asm-offsets.c index 54cc5b6b13f2..96f24fab7de6 100644 --- a/arch/mn10300/kernel/asm-offsets.c +++ b/arch/mn10300/kernel/asm-offsets.c @@ -23,6 +23,7 @@ void foo(void) OFFSET(TI_task, thread_info, task); OFFSET(TI_exec_domain, thread_info, exec_domain); + OFFSET(TI_frame, thread_info, frame); OFFSET(TI_flags, thread_info, flags); OFFSET(TI_cpu, thread_info, cpu); OFFSET(TI_preempt_count, thread_info, preempt_count); @@ -66,7 +67,6 @@ void foo(void) OFFSET(THREAD_SP, thread_struct, sp); OFFSET(THREAD_A3, thread_struct, a3); OFFSET(THREAD_USP, thread_struct, usp); - OFFSET(THREAD_FRAME, thread_struct, frame); #ifdef CONFIG_FPU OFFSET(THREAD_FPU_FLAGS, thread_struct, fpu_flags); OFFSET(THREAD_FPU_STATE, thread_struct, fpu_state); diff --git a/arch/mn10300/kernel/mn10300-watchdog.c b/arch/mn10300/kernel/mn10300-watchdog.c index 965dd61656c3..c5e12bfd9fcd 100644 --- a/arch/mn10300/kernel/mn10300-watchdog.c +++ b/arch/mn10300/kernel/mn10300-watchdog.c @@ -122,7 +122,7 @@ void __init watchdog_go(void) static void watchdog_dump_register(void *dummy) { printk(KERN_ERR "--- Register Dump (CPU%d) ---\n", CPUID); - show_registers(__frame); + show_registers(current_frame()); } #endif 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, unsigned long c_usp, unsigned long ustk_size, struct task_struct *p, struct pt_regs *kregs) { + struct thread_info *ti = task_thread_info(p); struct pt_regs *c_uregs, *c_kregs, *uregs; unsigned long c_ksp; @@ -248,7 +249,7 @@ int copy_thread(unsigned long clone_flags, /* the new TLS pointer is passed in as arg #5 to sys_clone() */ if (clone_flags & CLONE_SETTLS) - c_uregs->e2 = __frame->d3; + c_uregs->e2 = current_frame()->d3; /* set up the return kernel frame if called from kernel_thread() */ c_kregs = c_uregs; @@ -266,7 +267,7 @@ int copy_thread(unsigned long clone_flags, } /* set up things up so the scheduler can start the new task */ - p->thread.frame = c_kregs; + ti->frame = c_kregs; p->thread.a3 = (unsigned long) c_kregs; p->thread.sp = c_ksp; p->thread.pc = (unsigned long) ret_from_fork; @@ -278,25 +279,26 @@ int copy_thread(unsigned long clone_flags, /* * clone a process - * - tlsptr is retrieved by copy_thread() from __frame->d3 + * - tlsptr is retrieved by copy_thread() from current_frame()->d3 */ asmlinkage long sys_clone(unsigned long clone_flags, unsigned long newsp, int __user *parent_tidptr, int __user *child_tidptr, int __user *tlsptr) { - return do_fork(clone_flags, newsp ?: __frame->sp, __frame, 0, - parent_tidptr, child_tidptr); + return do_fork(clone_flags, newsp ?: current_frame()->sp, + current_frame(), 0, parent_tidptr, child_tidptr); } asmlinkage long sys_fork(void) { - return do_fork(SIGCHLD, __frame->sp, __frame, 0, NULL, NULL); + return do_fork(SIGCHLD, current_frame()->sp, + current_frame(), 0, NULL, NULL); } asmlinkage long sys_vfork(void) { - return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, __frame->sp, __frame, - 0, NULL, NULL); + return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, current_frame()->sp, + current_frame(), 0, NULL, NULL); } asmlinkage long sys_execve(const char __user *name, @@ -310,7 +312,7 @@ asmlinkage long sys_execve(const char __user *name, error = PTR_ERR(filename); if (IS_ERR(filename)) return error; - error = do_execve(filename, argv, envp, __frame); + error = do_execve(filename, argv, envp, current_frame()); putname(filename); return error; } diff --git a/arch/mn10300/kernel/signal.c b/arch/mn10300/kernel/signal.c index d4de05ab7864..690f4e9507d7 100644 --- a/arch/mn10300/kernel/signal.c +++ b/arch/mn10300/kernel/signal.c @@ -91,7 +91,7 @@ asmlinkage long sys_sigaction(int sig, */ asmlinkage long sys_sigaltstack(const stack_t __user *uss, stack_t *uoss) { - return do_sigaltstack(uss, uoss, __frame->sp); + return do_sigaltstack(uss, uoss, current_frame()->sp); } /* @@ -156,10 +156,11 @@ badframe: */ asmlinkage long sys_sigreturn(void) { - struct sigframe __user *frame = (struct sigframe __user *) __frame->sp; + struct sigframe __user *frame; sigset_t set; long d0; + frame = (struct sigframe __user *) current_frame()->sp; if (verify_area(VERIFY_READ, frame, sizeof(*frame))) goto badframe; if (__get_user(set.sig[0], &frame->sc.oldmask)) @@ -176,7 +177,7 @@ asmlinkage long sys_sigreturn(void) recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); - if (restore_sigcontext(__frame, &frame->sc, &d0)) + if (restore_sigcontext(current_frame(), &frame->sc, &d0)) goto badframe; return d0; @@ -191,11 +192,11 @@ badframe: */ asmlinkage long sys_rt_sigreturn(void) { - struct rt_sigframe __user *frame = - (struct rt_sigframe __user *) __frame->sp; + struct rt_sigframe __user *frame; sigset_t set; - unsigned long d0; + long d0; + frame = (struct rt_sigframe __user *) current_frame()->sp; if (verify_area(VERIFY_READ, frame, sizeof(*frame))) goto badframe; if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) @@ -207,10 +208,11 @@ asmlinkage long sys_rt_sigreturn(void) recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); - if (restore_sigcontext(__frame, &frame->uc.uc_mcontext, &d0)) + if (restore_sigcontext(current_frame(), &frame->uc.uc_mcontext, &d0)) goto badframe; - if (do_sigaltstack(&frame->uc.uc_stack, NULL, __frame->sp) == -EFAULT) + if (do_sigaltstack(&frame->uc.uc_stack, NULL, current_frame()->sp) == + -EFAULT) goto badframe; return d0; @@ -572,7 +574,7 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, u32 thread_info_flags) if (thread_info_flags & _TIF_NOTIFY_RESUME) { clear_thread_flag(TIF_NOTIFY_RESUME); - tracehook_notify_resume(__frame); + tracehook_notify_resume(current_frame()); if (current->replacement_session_keyring) key_replace_session_keyring(); } diff --git a/arch/mn10300/kernel/switch_to.S b/arch/mn10300/kernel/switch_to.S index b08cb2e3aebd..9074d0fb8788 100644 --- a/arch/mn10300/kernel/switch_to.S +++ b/arch/mn10300/kernel/switch_to.S @@ -38,15 +38,6 @@ ENTRY(__switch_to) mov d1,a1 # save prev context -#ifdef CONFIG_SMP - mov (CPUID),a2 - add a2,a2 - add a2,a2 - mov (___frame,a2),d0 -#else /* CONFIG_SMP */ - mov (__frame),d0 -#endif /* CONFIG_SMP */ - mov d0,(THREAD_FRAME,a0) mov __switch_back,d0 mov d0,(THREAD_PC,a0) mov sp,a2 @@ -68,15 +59,6 @@ ENTRY(__switch_to) mov a2,e2 #endif - mov (THREAD_FRAME,a1),a2 -#ifdef CONFIG_SMP - mov (CPUID),a0 - add a0,a0 - add a0,a0 - mov a2,(___frame,a0) -#else /* CONFIG_SMP */ - mov a2,(__frame) -#endif /* CONFIG_SMP */ mov (THREAD_PC,a1),a2 mov d2,d0 # for ret_from_fork mov d0,a0 # for __switch_to diff --git a/arch/mn10300/kernel/traps.c b/arch/mn10300/kernel/traps.c index c924a1dd3323..b90c3f160c77 100644 --- a/arch/mn10300/kernel/traps.c +++ b/arch/mn10300/kernel/traps.c @@ -45,14 +45,6 @@ #error "INTERRUPT_VECTOR_BASE not aligned to 16MiB boundary!" #endif -#ifdef CONFIG_SMP -struct pt_regs *___frame[NR_CPUS]; /* current frame pointer */ -EXPORT_SYMBOL(___frame); -#else /* CONFIG_SMP */ -struct pt_regs *__frame; /* current frame pointer */ -EXPORT_SYMBOL(__frame); -#endif /* CONFIG_SMP */ - int kstack_depth_to_print = 24; spinlock_t die_lock = __SPIN_LOCK_UNLOCKED(die_lock); |