History

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.

David Howells committed 16 years ago

Commit 7c7fcf71 parent a5e03ca15 files · +76 −146Browse files

Unified · Split

15 files
  1. arch/mn10300/include/asm/frame.inc +13 −43
  2. arch/mn10300/include/asm/irq_regs.h +5 −1
  3. arch/mn10300/include/asm/pgalloc.h +0 −1
  4. arch/mn10300/include/asm/processor.h +18 −28
  5. arch/mn10300/include/asm/ptrace.h +0 −6
  6. arch/mn10300/include/asm/smp.h +0 −13
  7. arch/mn10300/include/asm/thread_info.h +14 −4
  8. arch/mn10300/include/asm/uaccess.h +1 −3
  9. arch/mn10300/kernel/asm-offsets.c +1 −1
  10. arch/mn10300/kernel/mn10300-watchdog.c +1 −1
  11. arch/mn10300/kernel/process.c +11 −9
  12. arch/mn10300/kernel/signal.c +11 −9
  13. arch/mn10300/kernel/switch_to.S +0 −18
  14. arch/mn10300/kernel/traps.c +0 −8
  15. mm/maccess.c +1 −1
arch/mn10300/include/asm/frame.inc+13−43
@@ -18,9 +18,7 @@ · 17 unmodified lines
1818 #ifndef __ASM_OFFSETS_H__
1919 #include <asm/asm-offsets.h>
2020 #endif
21−#ifdef CONFIG_SMP
22−#include <proc/smp-regs.h>
23−#endif
21+#include <asm/thread_info.h>
2422
2523 #define pi break
2624
@@ -40,27 +38,15 @@ · 13 unmodified lines
4038 movm [d2,d3,a2,a3,exreg0,exreg1,exother],(sp)
4139 mov sp,fp # FRAME pointer in A3
4240 add -12,sp # allow for calls to be made
43−#ifdef CONFIG_SMP
44−#ifdef CONFIG_PREEMPT /* FIXME */
45− mov epsw,d2
46− and ~EPSW_IE,epsw
47−#endif
48− mov (CPUID),a0
49− add a0,a0
50− add a0,a0
51− mov (___frame,a0),a1
52− mov a1,(REG_NEXT,fp)
53− mov fp,(___frame,a0)
54−#ifdef CONFIG_PREEMPT /* FIXME */
55− mov d2,epsw
56−#endif
57−#else /* CONFIG_SMP */
58− mov (__frame),a1
59− mov a1,(REG_NEXT,fp)
60− mov fp,(__frame)
61−#endif /* CONFIG_SMP */
6241
63− and ~EPSW_FE,epsw # disable the FPU inside the kernel
42+ # push the exception frame onto the front of the list
43+ GET_THREAD_INFO a1
44+ mov (TI_frame,a1),a0
45+ mov a0,(REG_NEXT,fp)
46+ mov fp,(TI_frame,a1)
47+
48+ # disable the FPU inside the kernel
49+ and ~EPSW_FE,epsw
6450
6551 # we may be holding current in E2
6652 #ifdef CONFIG_MN10300_CURRENT_IN_E2
@@ -76,27 +62,11 @@ · 9 unmodified lines
7662 .macro RESTORE_ALL
7763 # peel back the stack to the calling frame
7864 # - this permits execve() to discard extra frames due to kernel syscalls
79−#ifdef CONFIG_SMP
80−#ifdef CONFIG_PREEMPT /* FIXME */
81− mov epsw,d2
82− and ~EPSW_IE,epsw
83−#endif
84− mov (CPUID),a0
85− add a0,a0
86− add a0,a0
87− mov (___frame,a0),fp
88− mov fp,sp
89− mov (REG_NEXT,fp),d0 # userspace has regs->next == 0
90− mov d0,(___frame,a0)
91−#ifdef CONFIG_PREEMPT /* FIXME */
92− mov d2,epsw
93−#endif
94−#else /* CONFIG_SMP */
95− mov (__frame),fp
65+ GET_THREAD_INFO a0
66+ mov (TI_frame,a0),fp
9667 mov fp,sp
97− mov (REG_NEXT,fp),d0 # userspace has regs->next == 0
98− mov d0,(__frame)
99−#endif /* CONFIG_SMP */
68+ mov (REG_NEXT,fp),d0
69+ mov d0,(TI_frame,a0) # userspace has regs->next == 0
10070
10171 #ifndef CONFIG_MN10300_USING_JTAG
10272 mov (REG_EPSW,fp),d0
arch/mn10300/include/asm/irq_regs.h+5−1
@@ -18,7 +18,11 @@ · 17 unmodified lines
1818 #define ARCH_HAS_OWN_IRQ_REGS
1919
2020 #ifndef __ASSEMBLY__
21−#define get_irq_regs() (__frame)
21+static inline __attribute__((const))
22+struct pt_regs *get_irq_regs(void)
23+{
24+ return current_frame();
25+}
2226 #endif
2327
2428 #endif /* _ASM_IRQ_REGS_H */
arch/mn10300/include/asm/pgalloc.h+0−1
@@ -11,7 +11,6 @@ · 10 unmodified lines
1111 #ifndef _ASM_PGALLOC_H
1212 #define _ASM_PGALLOC_H
1313
14−#include <asm/processor.h>
1514 #include <asm/page.h>
1615 #include <linux/threads.h>
1716 #include <linux/mm.h> /* for struct page */
arch/mn10300/include/asm/processor.h+18−28
@@ -13,10 +13,13 @@ · 12 unmodified lines
1313 #ifndef _ASM_PROCESSOR_H
1414 #define _ASM_PROCESSOR_H
1515
16+#include <linux/threads.h>
17+#include <linux/thread_info.h>
1618 #include <asm/page.h>
1719 #include <asm/ptrace.h>
1820 #include <asm/cpu-regs.h>
19−#include <linux/threads.h>
21+#include <asm/uaccess.h>
22+#include <asm/current.h>
2023
2124 /* Forward declaration, a strange C thing */
2225 struct task_struct;
@@ -83,10 +86,6 @@ extern void dodgy_tsc(void); · 60 unmodified lines
8386 */
8487 #define TASK_UNMAPPED_BASE 0x30000000
8588
86−typedef struct {
87− unsigned long seg;
88−} mm_segment_t;
89−
9089 struct fpu_state_struct {
9190 unsigned long fs[32]; /* fpu registers */
9291 unsigned long fpcr; /* fpu control register */
@@ -99,7 +98,6 @@ struct thread_struct { · 6 unmodified lines
9998 unsigned long a3; /* kernel FP */
10099 unsigned long wchan;
101100 unsigned long usp;
102− struct pt_regs *frame;
103101 unsigned long fpu_flags;
104102 #define THREAD_USING_FPU 0x00000001 /* T if this task is using the FPU */
105103 #define THREAD_HAS_FPU 0x00000002 /* T if this task owns the FPU right now */
@@ -113,7 +111,6 @@ struct thread_struct { · 7 unmodified lines
113111 .sp = 0, \
114112 .a3 = 0, \
115113 .wchan = 0, \
116− .frame = NULL, \
117114 }
118115
119116 #define INIT_MMAP \
@@ -125,27 +122,20 @@ struct thread_struct { · 5 unmodified lines
125122 * - need to discard the frame stacked by the kernel thread invoking the execve
126123 * syscall (see RESTORE_ALL macro)
127124 */
128−#if defined(CONFIG_SMP) && defined(CONFIG_PREEMPT) /* FIXME */
129−#define start_thread(regs, new_pc, new_sp) do { \
130− int cpu; \
131− preempt_disable(); \
132− cpu = CPUID; \
133− set_fs(USER_DS); \
134− ___frame[cpu] = current->thread.uregs; \
135− ___frame[cpu]->epsw = EPSW_nSL | EPSW_IE | EPSW_IM;\
136− ___frame[cpu]->pc = new_pc; \
137− ___frame[cpu]->sp = new_sp; \
138− preempt_enable(); \
139−} while (0)
140−#else /* CONFIG_SMP && CONFIG_PREEMPT */
141−#define start_thread(regs, new_pc, new_sp) do { \
142− set_fs(USER_DS); \
143− __frame = current->thread.uregs; \
144− __frame->epsw = EPSW_nSL | EPSW_IE | EPSW_IM; \
145− __frame->pc = new_pc; \
146− __frame->sp = new_sp; \
147−} while (0)
148−#endif /* CONFIG_SMP && CONFIG_PREEMPT */
125+static inline void start_thread(struct pt_regs *regs,
126+ unsigned long new_pc, unsigned long new_sp)
127+{
128+ struct thread_info *ti = current_thread_info();
129+ struct pt_regs *frame0;
130+ set_fs(USER_DS);
131+
132+ frame0 = thread_info_to_uregs(ti);
133+ frame0->epsw = EPSW_nSL | EPSW_IE | EPSW_IM;
134+ frame0->pc = new_pc;
135+ frame0->sp = new_sp;
136+ ti->frame = frame0;
137+}
138+
149139
150140 /* Free all resources held by a thread. */
151141 extern void release_thread(struct task_struct *);
arch/mn10300/include/asm/ptrace.h+0−6
@@ -86,12 +86,6 @@ struct pt_regs { · 85 unmodified lines
8686
8787 #ifdef __KERNEL__
8888
89−#ifdef CONFIG_SMP
90−extern struct pt_regs *___frame[]; /* current frame pointer */
91−#else
92−extern struct pt_regs *__frame; /* current frame pointer */
93−#endif
94−
9589 #define user_mode(regs) (((regs)->epsw & EPSW_nSL) == EPSW_nSL)
9690 #define instruction_pointer(regs) ((regs)->pc)
9791 #define user_stack_pointer(regs) ((regs)->sp)
arch/mn10300/include/asm/smp.h+0−13
@@ -93,19 +93,6 @@ extern int __cpu_disable(void); · 92 unmodified lines
9393 extern void __cpu_die(unsigned int cpu);
9494 #endif /* CONFIG_HOTPLUG_CPU */
9595
96−#ifdef CONFIG_PREEMPT /* FIXME */
97−#define __frame \
98− ({ \
99− struct pt_regs *f; \
100− preempt_disable(); \
101− f = ___frame[CPUID]; \
102− preempt_enable(); \
103− f; \
104− })
105−#else
106−#define __frame ___frame[CPUID]
107−#endif
108−
10996 #endif /* __ASSEMBLY__ */
11097 #else /* CONFIG_SMP */
11198 #ifndef __ASSEMBLY__
arch/mn10300/include/asm/thread_info.h+14−4
@@ -16,10 +16,6 @@ · 15 unmodified lines
1616
1717 #include <asm/page.h>
1818
19−#ifndef __ASSEMBLY__
20−#include <asm/processor.h>
21−#endif
22−
2319 #define PREEMPT_ACTIVE 0x10000000
2420
2521 #ifdef CONFIG_4KSTACKS
@@ -38,10 +34,14 @@ · 12 unmodified lines
3834 * must also be changed
3935 */
4036 #ifndef __ASSEMBLY__
37+typedef struct {
38+ unsigned long seg;
39+} mm_segment_t;
4140
4241 struct thread_info {
4342 struct task_struct *task; /* main task structure */
4443 struct exec_domain *exec_domain; /* execution domain */
44+ struct pt_regs *frame; /* current exception frame */
4545 unsigned long flags; /* low level flags */
4646 __u32 cpu; /* current CPU */
4747 __s32 preempt_count; /* 0 => preemptable, <0 => BUG */
@@ -55,6 +55,10 @@ struct thread_info { · 7 unmodified lines
5555 __u8 supervisor_stack[0];
5656 };
5757
58+#define thread_info_to_uregs(ti) \
59+ ((struct pt_regs *) \
60+ ((unsigned long)ti + THREAD_SIZE - sizeof(struct pt_regs)))
61+
5862 #else /* !__ASSEMBLY__ */
5963
6064 #ifndef __ASM_OFFSETS_H__
@@ -102,6 +106,12 @@ struct thread_info *current_thread_info(void) · 41 unmodified lines
102106 return ti;
103107 }
104108
109+static inline __attribute__((const))
110+struct pt_regs *current_frame(void)
111+{
112+ return current_thread_info()->frame;
113+}
114+
105115 /* how to get the current stack pointer from C */
106116 static inline unsigned long current_stack_pointer(void)
107117 {
arch/mn10300/include/asm/uaccess.h+1−3
@@ -14,9 +14,8 @@ · 13 unmodified lines
1414 /*
1515 * User space memory access functions
1616 */
17−#include <linux/sched.h>
17+#include <linux/thread_info.h>
1818 #include <asm/page.h>
19−#include <asm/pgtable.h>
2019 #include <asm/errno.h>
2120
2221 #define VERIFY_READ 0
@@ -29,7 +28,6 @@ · 6 unmodified lines
2928 *
3029 * For historical reasons, these macros are grossly misnamed.
3130 */
32−
3331 #define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
3432
3533 #define KERNEL_XDS MAKE_MM_SEG(0xBFFFFFFF)
arch/mn10300/kernel/asm-offsets.c+1−1
@@ -23,6 +23,7 @@ void foo(void) · 22 unmodified lines
2323
2424 OFFSET(TI_task, thread_info, task);
2525 OFFSET(TI_exec_domain, thread_info, exec_domain);
26+ OFFSET(TI_frame, thread_info, frame);
2627 OFFSET(TI_flags, thread_info, flags);
2728 OFFSET(TI_cpu, thread_info, cpu);
2829 OFFSET(TI_preempt_count, thread_info, preempt_count);
@@ -66,7 +67,6 @@ void foo(void) · 37 unmodified lines
6667 OFFSET(THREAD_SP, thread_struct, sp);
6768 OFFSET(THREAD_A3, thread_struct, a3);
6869 OFFSET(THREAD_USP, thread_struct, usp);
69− OFFSET(THREAD_FRAME, thread_struct, frame);
7070 #ifdef CONFIG_FPU
7171 OFFSET(THREAD_FPU_FLAGS, thread_struct, fpu_flags);
7272 OFFSET(THREAD_FPU_STATE, thread_struct, fpu_state);
arch/mn10300/kernel/mn10300-watchdog.c+1−1
@@ -122,7 +122,7 @@ void __init watchdog_go(void) · 121 unmodified lines
122122 static void watchdog_dump_register(void *dummy)
123123 {
124124 printk(KERN_ERR "--- Register Dump (CPU%d) ---\n", CPUID);
125− show_registers(__frame);
125+ show_registers(current_frame());
126126 }
127127 #endif
128128
arch/mn10300/kernel/process.c+11−9
@@ -228,6 +228,7 @@ int copy_thread(unsigned long clone_flags, · 227 unmodified lines
228228 unsigned long c_usp, unsigned long ustk_size,
229229 struct task_struct *p, struct pt_regs *kregs)
230230 {
231+ struct thread_info *ti = task_thread_info(p);
231232 struct pt_regs *c_uregs, *c_kregs, *uregs;
232233 unsigned long c_ksp;
233234
@@ -248,7 +249,7 @@ int copy_thread(unsigned long clone_flags, · 14 unmodified lines
248249
249250 /* the new TLS pointer is passed in as arg #5 to sys_clone() */
250251 if (clone_flags & CLONE_SETTLS)
251− c_uregs->e2 = __frame->d3;
252+ c_uregs->e2 = current_frame()->d3;
252253
253254 /* set up the return kernel frame if called from kernel_thread() */
254255 c_kregs = c_uregs;
@@ -266,7 +267,7 @@ int copy_thread(unsigned long clone_flags, · 11 unmodified lines
266267 }
267268
268269 /* set up things up so the scheduler can start the new task */
269− p->thread.frame = c_kregs;
270+ ti->frame = c_kregs;
270271 p->thread.a3 = (unsigned long) c_kregs;
271272 p->thread.sp = c_ksp;
272273 p->thread.pc = (unsigned long) ret_from_fork;
@@ -278,25 +279,26 @@ int copy_thread(unsigned long clone_flags, · 5 unmodified lines
278279
279280 /*
280281 * clone a process
281− * - tlsptr is retrieved by copy_thread() from __frame->d3
282+ * - tlsptr is retrieved by copy_thread() from current_frame()->d3
282283 */
283284 asmlinkage long sys_clone(unsigned long clone_flags, unsigned long newsp,
284285 int __user *parent_tidptr, int __user *child_tidptr,
285286 int __user *tlsptr)
286287 {
287− return do_fork(clone_flags, newsp ?: __frame->sp, __frame, 0,
288− parent_tidptr, child_tidptr);
288+ return do_fork(clone_flags, newsp ?: current_frame()->sp,
289+ current_frame(), 0, parent_tidptr, child_tidptr);
289290 }
290291
291292 asmlinkage long sys_fork(void)
292293 {
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);
294296 }
295297
296298 asmlinkage long sys_vfork(void)
297299 {
298− return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, __frame->sp, __frame,
299− 0, NULL, NULL);
300+ return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, current_frame()->sp,
301+ current_frame(), 0, NULL, NULL);
300302 }
301303
302304 asmlinkage long sys_execve(const char __user *name,
@@ -310,7 +312,7 @@ asmlinkage long sys_execve(const char __user *name, · 7 unmodified lines
310312 error = PTR_ERR(filename);
311313 if (IS_ERR(filename))
312314 return error;
313− error = do_execve(filename, argv, envp, __frame);
315+ error = do_execve(filename, argv, envp, current_frame());
314316 putname(filename);
315317 return error;
316318 }
arch/mn10300/kernel/signal.c+11−9
@@ -91,7 +91,7 @@ asmlinkage long sys_sigaction(int sig, · 90 unmodified lines
9191 */
9292 asmlinkage long sys_sigaltstack(const stack_t __user *uss, stack_t *uoss)
9393 {
94− return do_sigaltstack(uss, uoss, __frame->sp);
94+ return do_sigaltstack(uss, uoss, current_frame()->sp);
9595 }
9696
9797 /*
@@ -156,10 +156,11 @@ badframe: · 58 unmodified lines
156156 */
157157 asmlinkage long sys_sigreturn(void)
158158 {
159− struct sigframe __user *frame = (struct sigframe __user *) __frame->sp;
159+ struct sigframe __user *frame;
160160 sigset_t set;
161161 long d0;
162162
163+ frame = (struct sigframe __user *) current_frame()->sp;
163164 if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
164165 goto badframe;
165166 if (__get_user(set.sig[0], &frame->sc.oldmask))
@@ -176,7 +177,7 @@ asmlinkage long sys_sigreturn(void) · 10 unmodified lines
176177 recalc_sigpending();
177178 spin_unlock_irq(&current->sighand->siglock);
178179
179− if (restore_sigcontext(__frame, &frame->sc, &d0))
180+ if (restore_sigcontext(current_frame(), &frame->sc, &d0))
180181 goto badframe;
181182
182183 return d0;
@@ -191,11 +192,11 @@ badframe: · 8 unmodified lines
191192 */
192193 asmlinkage long sys_rt_sigreturn(void)
193194 {
194− struct rt_sigframe __user *frame =
195− (struct rt_sigframe __user *) __frame->sp;
195+ struct rt_sigframe __user *frame;
196196 sigset_t set;
197− unsigned long d0;
197+ long d0;
198198
199+ frame = (struct rt_sigframe __user *) current_frame()->sp;
199200 if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
200201 goto badframe;
201202 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
@@ -207,10 +208,11 @@ asmlinkage long sys_rt_sigreturn(void) · 5 unmodified lines
207208 recalc_sigpending();
208209 spin_unlock_irq(&current->sighand->siglock);
209210
210− if (restore_sigcontext(__frame, &frame->uc.uc_mcontext, &d0))
211+ if (restore_sigcontext(current_frame(), &frame->uc.uc_mcontext, &d0))
211212 goto badframe;
212213
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)
214216 goto badframe;
215217
216218 return d0;
@@ -572,7 +574,7 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, u32 thread_info_flags) · 355 unmodified lines
572574
573575 if (thread_info_flags & _TIF_NOTIFY_RESUME) {
574576 clear_thread_flag(TIF_NOTIFY_RESUME);
575− tracehook_notify_resume(__frame);
577+ tracehook_notify_resume(current_frame());
576578 if (current->replacement_session_keyring)
577579 key_replace_session_keyring();
578580 }
arch/mn10300/kernel/switch_to.S+0−18
@@ -38,15 +38,6 @@ ENTRY(__switch_to) · 37 unmodified lines
3838 mov d1,a1
3939
4040 # 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)
5041 mov __switch_back,d0
5142 mov d0,(THREAD_PC,a0)
5243 mov sp,a2
@@ -68,15 +59,6 @@ ENTRY(__switch_to) · 15 unmodified lines
6859 mov a2,e2
6960 #endif
7061
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 */
8062 mov (THREAD_PC,a1),a2
8163 mov d2,d0 # for ret_from_fork
8264 mov d0,a0 # for __switch_to
arch/mn10300/kernel/traps.c+0−8
@@ -45,14 +45,6 @@ · 44 unmodified lines
4545 #error "INTERRUPT_VECTOR_BASE not aligned to 16MiB boundary!"
4646 #endif
4747
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−
5648 int kstack_depth_to_print = 24;
5749
5850 spinlock_t die_lock = __SPIN_LOCK_UNLOCKED(die_lock);
mm/maccess.c+1−1
@@ -1,9 +1,9 @@
11 /*
22 * Access kernel memory without faulting.
33 */
4−#include <linux/uaccess.h>
54 #include <linux/module.h>
65 #include <linux/mm.h>
6+#include <linux/uaccess.h>
77
88 /**
99 * probe_kernel_read(): safely attempt to read from a location

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t