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 | |
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) | |||
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) | |||
122 | static void watchdog_dump_register(void *dummy) | 122 | static 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 | */ |
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 | } |
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 | */ |
92 | asmlinkage long sys_sigaltstack(const stack_t __user *uss, stack_t *uoss) | 92 | asmlinkage 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 | */ |
157 | asmlinkage long sys_sigreturn(void) | 157 | asmlinkage 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(¤t->sighand->siglock); | 178 | spin_unlock_irq(¤t->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 | */ |
192 | asmlinkage long sys_rt_sigreturn(void) | 193 | asmlinkage 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(¤t->sighand->siglock); | 209 | spin_unlock_irq(¤t->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 | ||
49 | struct pt_regs *___frame[NR_CPUS]; /* current frame pointer */ | ||
50 | EXPORT_SYMBOL(___frame); | ||
51 | #else /* CONFIG_SMP */ | ||
52 | struct pt_regs *__frame; /* current frame pointer */ | ||
53 | EXPORT_SYMBOL(__frame); | ||
54 | #endif /* CONFIG_SMP */ | ||
55 | |||
56 | int kstack_depth_to_print = 24; | 48 | int kstack_depth_to_print = 24; |
57 | 49 | ||
58 | spinlock_t die_lock = __SPIN_LOCK_UNLOCKED(die_lock); | 50 | spinlock_t die_lock = __SPIN_LOCK_UNLOCKED(die_lock); |