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/include/asm/processor.h | |
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/include/asm/processor.h')
-rw-r--r-- | arch/mn10300/include/asm/processor.h | 46 |
1 files changed, 18 insertions, 28 deletions
diff --git a/arch/mn10300/include/asm/processor.h b/arch/mn10300/include/asm/processor.h index 75c422abcd6b..4c1b5cc14c19 100644 --- a/arch/mn10300/include/asm/processor.h +++ b/arch/mn10300/include/asm/processor.h | |||
@@ -13,10 +13,13 @@ | |||
13 | #ifndef _ASM_PROCESSOR_H | 13 | #ifndef _ASM_PROCESSOR_H |
14 | #define _ASM_PROCESSOR_H | 14 | #define _ASM_PROCESSOR_H |
15 | 15 | ||
16 | #include <linux/threads.h> | ||
17 | #include <linux/thread_info.h> | ||
16 | #include <asm/page.h> | 18 | #include <asm/page.h> |
17 | #include <asm/ptrace.h> | 19 | #include <asm/ptrace.h> |
18 | #include <asm/cpu-regs.h> | 20 | #include <asm/cpu-regs.h> |
19 | #include <linux/threads.h> | 21 | #include <asm/uaccess.h> |
22 | #include <asm/current.h> | ||
20 | 23 | ||
21 | /* Forward declaration, a strange C thing */ | 24 | /* Forward declaration, a strange C thing */ |
22 | struct task_struct; | 25 | struct task_struct; |
@@ -83,10 +86,6 @@ extern void dodgy_tsc(void); | |||
83 | */ | 86 | */ |
84 | #define TASK_UNMAPPED_BASE 0x30000000 | 87 | #define TASK_UNMAPPED_BASE 0x30000000 |
85 | 88 | ||
86 | typedef struct { | ||
87 | unsigned long seg; | ||
88 | } mm_segment_t; | ||
89 | |||
90 | struct fpu_state_struct { | 89 | struct fpu_state_struct { |
91 | unsigned long fs[32]; /* fpu registers */ | 90 | unsigned long fs[32]; /* fpu registers */ |
92 | unsigned long fpcr; /* fpu control register */ | 91 | unsigned long fpcr; /* fpu control register */ |
@@ -99,7 +98,6 @@ struct thread_struct { | |||
99 | unsigned long a3; /* kernel FP */ | 98 | unsigned long a3; /* kernel FP */ |
100 | unsigned long wchan; | 99 | unsigned long wchan; |
101 | unsigned long usp; | 100 | unsigned long usp; |
102 | struct pt_regs *frame; | ||
103 | unsigned long fpu_flags; | 101 | unsigned long fpu_flags; |
104 | #define THREAD_USING_FPU 0x00000001 /* T if this task is using the FPU */ | 102 | #define THREAD_USING_FPU 0x00000001 /* T if this task is using the FPU */ |
105 | #define THREAD_HAS_FPU 0x00000002 /* T if this task owns the FPU right now */ | 103 | #define THREAD_HAS_FPU 0x00000002 /* T if this task owns the FPU right now */ |
@@ -113,7 +111,6 @@ struct thread_struct { | |||
113 | .sp = 0, \ | 111 | .sp = 0, \ |
114 | .a3 = 0, \ | 112 | .a3 = 0, \ |
115 | .wchan = 0, \ | 113 | .wchan = 0, \ |
116 | .frame = NULL, \ | ||
117 | } | 114 | } |
118 | 115 | ||
119 | #define INIT_MMAP \ | 116 | #define INIT_MMAP \ |
@@ -125,27 +122,20 @@ struct thread_struct { | |||
125 | * - need to discard the frame stacked by the kernel thread invoking the execve | 122 | * - need to discard the frame stacked by the kernel thread invoking the execve |
126 | * syscall (see RESTORE_ALL macro) | 123 | * syscall (see RESTORE_ALL macro) |
127 | */ | 124 | */ |
128 | #if defined(CONFIG_SMP) && defined(CONFIG_PREEMPT) /* FIXME */ | 125 | static inline void start_thread(struct pt_regs *regs, |
129 | #define start_thread(regs, new_pc, new_sp) do { \ | 126 | unsigned long new_pc, unsigned long new_sp) |
130 | int cpu; \ | 127 | { |
131 | preempt_disable(); \ | 128 | struct thread_info *ti = current_thread_info(); |
132 | cpu = CPUID; \ | 129 | struct pt_regs *frame0; |
133 | set_fs(USER_DS); \ | 130 | set_fs(USER_DS); |
134 | ___frame[cpu] = current->thread.uregs; \ | 131 | |
135 | ___frame[cpu]->epsw = EPSW_nSL | EPSW_IE | EPSW_IM;\ | 132 | frame0 = thread_info_to_uregs(ti); |
136 | ___frame[cpu]->pc = new_pc; \ | 133 | frame0->epsw = EPSW_nSL | EPSW_IE | EPSW_IM; |
137 | ___frame[cpu]->sp = new_sp; \ | 134 | frame0->pc = new_pc; |
138 | preempt_enable(); \ | 135 | frame0->sp = new_sp; |
139 | } while (0) | 136 | ti->frame = frame0; |
140 | #else /* CONFIG_SMP && CONFIG_PREEMPT */ | 137 | } |
141 | #define start_thread(regs, new_pc, new_sp) do { \ | 138 | |
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 */ | ||
149 | 139 | ||
150 | /* Free all resources held by a thread. */ | 140 | /* Free all resources held by a thread. */ |
151 | extern void release_thread(struct task_struct *); | 141 | extern void release_thread(struct task_struct *); |