aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mn10300/kernel
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2010-10-27 12:29:01 -0400
committerDavid Howells <dhowells@redhat.com>2010-10-27 12:29:01 -0400
commit7c7fcf762e405eb040ee10d22d656a791f616122 (patch)
tree2ec4f320fe2d348ffbdab6aebc9a36bcbf13da34 /arch/mn10300/kernel
parenta5e03ca2fd57a5823b759981bff8d19b46ddad4d (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.c2
-rw-r--r--arch/mn10300/kernel/mn10300-watchdog.c2
-rw-r--r--arch/mn10300/kernel/process.c20
-rw-r--r--arch/mn10300/kernel/signal.c20
-rw-r--r--arch/mn10300/kernel/switch_to.S18
-rw-r--r--arch/mn10300/kernel/traps.c8
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)
23 23
24 OFFSET(TI_task, thread_info, task); 24 OFFSET(TI_task, thread_info, task);
25 OFFSET(TI_exec_domain, thread_info, exec_domain); 25 OFFSET(TI_exec_domain, thread_info, exec_domain);
26 OFFSET(TI_frame, thread_info, frame);
26 OFFSET(TI_flags, thread_info, flags); 27 OFFSET(TI_flags, thread_info, flags);
27 OFFSET(TI_cpu, thread_info, cpu); 28 OFFSET(TI_cpu, thread_info, cpu);
28 OFFSET(TI_preempt_count, thread_info, preempt_count); 29 OFFSET(TI_preempt_count, thread_info, preempt_count);
@@ -66,7 +67,6 @@ void foo(void)
66 OFFSET(THREAD_SP, thread_struct, sp); 67 OFFSET(THREAD_SP, thread_struct, sp);
67 OFFSET(THREAD_A3, thread_struct, a3); 68 OFFSET(THREAD_A3, thread_struct, a3);
68 OFFSET(THREAD_USP, thread_struct, usp); 69 OFFSET(THREAD_USP, thread_struct, usp);
69 OFFSET(THREAD_FRAME, thread_struct, frame);
70#ifdef CONFIG_FPU 70#ifdef CONFIG_FPU
71 OFFSET(THREAD_FPU_FLAGS, thread_struct, fpu_flags); 71 OFFSET(THREAD_FPU_FLAGS, thread_struct, fpu_flags);
72 OFFSET(THREAD_FPU_STATE, thread_struct, fpu_state); 72 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)
122static void watchdog_dump_register(void *dummy) 122static void watchdog_dump_register(void *dummy)
123{ 123{
124 printk(KERN_ERR "--- Register Dump (CPU%d) ---\n", CPUID); 124 printk(KERN_ERR "--- Register Dump (CPU%d) ---\n", CPUID);
125 show_registers(__frame); 125 show_registers(current_frame());
126} 126}
127#endif 127#endif
128 128
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 */
283asmlinkage long sys_clone(unsigned long clone_flags, unsigned long newsp, 284asmlinkage 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
291asmlinkage long sys_fork(void) 292asmlinkage 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
296asmlinkage long sys_vfork(void) 298asmlinkage 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
302asmlinkage long sys_execve(const char __user *name, 304asmlinkage 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}
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,
91 */ 91 */
92asmlinkage long sys_sigaltstack(const stack_t __user *uss, stack_t *uoss) 92asmlinkage long sys_sigaltstack(const stack_t __user *uss, stack_t *uoss)
93{ 93{
94 return do_sigaltstack(uss, uoss, __frame->sp); 94 return do_sigaltstack(uss, uoss, current_frame()->sp);
95} 95}
96 96
97/* 97/*
@@ -156,10 +156,11 @@ badframe:
156 */ 156 */
157asmlinkage long sys_sigreturn(void) 157asmlinkage long sys_sigreturn(void)
158{ 158{
159 struct sigframe __user *frame = (struct sigframe __user *) __frame->sp; 159 struct sigframe __user *frame;
160 sigset_t set; 160 sigset_t set;
161 long d0; 161 long d0;
162 162
163 frame = (struct sigframe __user *) current_frame()->sp;
163 if (verify_area(VERIFY_READ, frame, sizeof(*frame))) 164 if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
164 goto badframe; 165 goto badframe;
165 if (__get_user(set.sig[0], &frame->sc.oldmask)) 166 if (__get_user(set.sig[0], &frame->sc.oldmask))
@@ -176,7 +177,7 @@ asmlinkage long sys_sigreturn(void)
176 recalc_sigpending(); 177 recalc_sigpending();
177 spin_unlock_irq(&current->sighand->siglock); 178 spin_unlock_irq(&current->sighand->siglock);
178 179
179 if (restore_sigcontext(__frame, &frame->sc, &d0)) 180 if (restore_sigcontext(current_frame(), &frame->sc, &d0))
180 goto badframe; 181 goto badframe;
181 182
182 return d0; 183 return d0;
@@ -191,11 +192,11 @@ badframe:
191 */ 192 */
192asmlinkage long sys_rt_sigreturn(void) 193asmlinkage long sys_rt_sigreturn(void)
193{ 194{
194 struct rt_sigframe __user *frame = 195 struct rt_sigframe __user *frame;
195 (struct rt_sigframe __user *) __frame->sp;
196 sigset_t set; 196 sigset_t set;
197 unsigned long d0; 197 long d0;
198 198
199 frame = (struct rt_sigframe __user *) current_frame()->sp;
199 if (verify_area(VERIFY_READ, frame, sizeof(*frame))) 200 if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
200 goto badframe; 201 goto badframe;
201 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) 202 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
@@ -207,10 +208,11 @@ asmlinkage long sys_rt_sigreturn(void)
207 recalc_sigpending(); 208 recalc_sigpending();
208 spin_unlock_irq(&current->sighand->siglock); 209 spin_unlock_irq(&current->sighand->siglock);
209 210
210 if (restore_sigcontext(__frame, &frame->uc.uc_mcontext, &d0)) 211 if (restore_sigcontext(current_frame(), &frame->uc.uc_mcontext, &d0))
211 goto badframe; 212 goto badframe;
212 213
213 if (do_sigaltstack(&frame->uc.uc_stack, NULL, __frame->sp) == -EFAULT) 214 if (do_sigaltstack(&frame->uc.uc_stack, NULL, current_frame()->sp) ==
215 -EFAULT)
214 goto badframe; 216 goto badframe;
215 217
216 return d0; 218 return d0;
@@ -572,7 +574,7 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, u32 thread_info_flags)
572 574
573 if (thread_info_flags & _TIF_NOTIFY_RESUME) { 575 if (thread_info_flags & _TIF_NOTIFY_RESUME) {
574 clear_thread_flag(TIF_NOTIFY_RESUME); 576 clear_thread_flag(TIF_NOTIFY_RESUME);
575 tracehook_notify_resume(__frame); 577 tracehook_notify_resume(current_frame());
576 if (current->replacement_session_keyring) 578 if (current->replacement_session_keyring)
577 key_replace_session_keyring(); 579 key_replace_session_keyring();
578 } 580 }
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)
38 mov d1,a1 38 mov d1,a1
39 39
40 # save prev context 40 # save prev context
41#ifdef CONFIG_SMP
42 mov (CPUID),a2
43 add a2,a2
44 add a2,a2
45 mov (___frame,a2),d0
46#else /* CONFIG_SMP */
47 mov (__frame),d0
48#endif /* CONFIG_SMP */
49 mov d0,(THREAD_FRAME,a0)
50 mov __switch_back,d0 41 mov __switch_back,d0
51 mov d0,(THREAD_PC,a0) 42 mov d0,(THREAD_PC,a0)
52 mov sp,a2 43 mov sp,a2
@@ -68,15 +59,6 @@ ENTRY(__switch_to)
68 mov a2,e2 59 mov a2,e2
69#endif 60#endif
70 61
71 mov (THREAD_FRAME,a1),a2
72#ifdef CONFIG_SMP
73 mov (CPUID),a0
74 add a0,a0
75 add a0,a0
76 mov a2,(___frame,a0)
77#else /* CONFIG_SMP */
78 mov a2,(__frame)
79#endif /* CONFIG_SMP */
80 mov (THREAD_PC,a1),a2 62 mov (THREAD_PC,a1),a2
81 mov d2,d0 # for ret_from_fork 63 mov d2,d0 # for ret_from_fork
82 mov d0,a0 # for __switch_to 64 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 @@
45#error "INTERRUPT_VECTOR_BASE not aligned to 16MiB boundary!" 45#error "INTERRUPT_VECTOR_BASE not aligned to 16MiB boundary!"
46#endif 46#endif
47 47
48#ifdef CONFIG_SMP
49struct pt_regs *___frame[NR_CPUS]; /* current frame pointer */
50EXPORT_SYMBOL(___frame);
51#else /* CONFIG_SMP */
52struct pt_regs *__frame; /* current frame pointer */
53EXPORT_SYMBOL(__frame);
54#endif /* CONFIG_SMP */
55
56int kstack_depth_to_print = 24; 48int kstack_depth_to_print = 24;
57 49
58spinlock_t die_lock = __SPIN_LOCK_UNLOCKED(die_lock); 50spinlock_t die_lock = __SPIN_LOCK_UNLOCKED(die_lock);