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 | |
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')
-rw-r--r-- | arch/mn10300/include/asm/frame.inc | 56 | ||||
-rw-r--r-- | arch/mn10300/include/asm/irq_regs.h | 6 | ||||
-rw-r--r-- | arch/mn10300/include/asm/pgalloc.h | 1 | ||||
-rw-r--r-- | arch/mn10300/include/asm/processor.h | 46 | ||||
-rw-r--r-- | arch/mn10300/include/asm/ptrace.h | 6 | ||||
-rw-r--r-- | arch/mn10300/include/asm/smp.h | 13 | ||||
-rw-r--r-- | arch/mn10300/include/asm/thread_info.h | 18 | ||||
-rw-r--r-- | arch/mn10300/include/asm/uaccess.h | 4 |
8 files changed, 51 insertions, 99 deletions
diff --git a/arch/mn10300/include/asm/frame.inc b/arch/mn10300/include/asm/frame.inc index 406060e5e1c0..2ee58e3eb6b3 100644 --- a/arch/mn10300/include/asm/frame.inc +++ b/arch/mn10300/include/asm/frame.inc | |||
@@ -18,9 +18,7 @@ | |||
18 | #ifndef __ASM_OFFSETS_H__ | 18 | #ifndef __ASM_OFFSETS_H__ |
19 | #include <asm/asm-offsets.h> | 19 | #include <asm/asm-offsets.h> |
20 | #endif | 20 | #endif |
21 | #ifdef CONFIG_SMP | 21 | #include <asm/thread_info.h> |
22 | #include <proc/smp-regs.h> | ||
23 | #endif | ||
24 | 22 | ||
25 | #define pi break | 23 | #define pi break |
26 | 24 | ||
@@ -40,27 +38,15 @@ | |||
40 | movm [d2,d3,a2,a3,exreg0,exreg1,exother],(sp) | 38 | movm [d2,d3,a2,a3,exreg0,exreg1,exother],(sp) |
41 | mov sp,fp # FRAME pointer in A3 | 39 | mov sp,fp # FRAME pointer in A3 |
42 | add -12,sp # allow for calls to be made | 40 | 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 */ | ||
62 | 41 | ||
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 | ||
64 | 50 | ||
65 | # we may be holding current in E2 | 51 | # we may be holding current in E2 |
66 | #ifdef CONFIG_MN10300_CURRENT_IN_E2 | 52 | #ifdef CONFIG_MN10300_CURRENT_IN_E2 |
@@ -76,27 +62,11 @@ | |||
76 | .macro RESTORE_ALL | 62 | .macro RESTORE_ALL |
77 | # peel back the stack to the calling frame | 63 | # peel back the stack to the calling frame |
78 | # - this permits execve() to discard extra frames due to kernel syscalls | 64 | # - this permits execve() to discard extra frames due to kernel syscalls |
79 | #ifdef CONFIG_SMP | 65 | GET_THREAD_INFO a0 |
80 | #ifdef CONFIG_PREEMPT /* FIXME */ | 66 | mov (TI_frame,a0),fp |
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 | ||
96 | mov fp,sp | 67 | mov fp,sp |
97 | mov (REG_NEXT,fp),d0 # userspace has regs->next == 0 | 68 | mov (REG_NEXT,fp),d0 |
98 | mov d0,(__frame) | 69 | mov d0,(TI_frame,a0) # userspace has regs->next == 0 |
99 | #endif /* CONFIG_SMP */ | ||
100 | 70 | ||
101 | #ifndef CONFIG_MN10300_USING_JTAG | 71 | #ifndef CONFIG_MN10300_USING_JTAG |
102 | mov (REG_EPSW,fp),d0 | 72 | mov (REG_EPSW,fp),d0 |
diff --git a/arch/mn10300/include/asm/irq_regs.h b/arch/mn10300/include/asm/irq_regs.h index a848cd232eb4..97d0cb5af807 100644 --- a/arch/mn10300/include/asm/irq_regs.h +++ b/arch/mn10300/include/asm/irq_regs.h | |||
@@ -18,7 +18,11 @@ | |||
18 | #define ARCH_HAS_OWN_IRQ_REGS | 18 | #define ARCH_HAS_OWN_IRQ_REGS |
19 | 19 | ||
20 | #ifndef __ASSEMBLY__ | 20 | #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 | } | ||
22 | #endif | 26 | #endif |
23 | 27 | ||
24 | #endif /* _ASM_IRQ_REGS_H */ | 28 | #endif /* _ASM_IRQ_REGS_H */ |
diff --git a/arch/mn10300/include/asm/pgalloc.h b/arch/mn10300/include/asm/pgalloc.h index a19f11327cd8..146bacf193ea 100644 --- a/arch/mn10300/include/asm/pgalloc.h +++ b/arch/mn10300/include/asm/pgalloc.h | |||
@@ -11,7 +11,6 @@ | |||
11 | #ifndef _ASM_PGALLOC_H | 11 | #ifndef _ASM_PGALLOC_H |
12 | #define _ASM_PGALLOC_H | 12 | #define _ASM_PGALLOC_H |
13 | 13 | ||
14 | #include <asm/processor.h> | ||
15 | #include <asm/page.h> | 14 | #include <asm/page.h> |
16 | #include <linux/threads.h> | 15 | #include <linux/threads.h> |
17 | #include <linux/mm.h> /* for struct page */ | 16 | #include <linux/mm.h> /* for struct page */ |
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 *); |
diff --git a/arch/mn10300/include/asm/ptrace.h b/arch/mn10300/include/asm/ptrace.h index c2b77bd3064a..b6961811d445 100644 --- a/arch/mn10300/include/asm/ptrace.h +++ b/arch/mn10300/include/asm/ptrace.h | |||
@@ -86,12 +86,6 @@ struct pt_regs { | |||
86 | 86 | ||
87 | #ifdef __KERNEL__ | 87 | #ifdef __KERNEL__ |
88 | 88 | ||
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 | |||
95 | #define user_mode(regs) (((regs)->epsw & EPSW_nSL) == EPSW_nSL) | 89 | #define user_mode(regs) (((regs)->epsw & EPSW_nSL) == EPSW_nSL) |
96 | #define instruction_pointer(regs) ((regs)->pc) | 90 | #define instruction_pointer(regs) ((regs)->pc) |
97 | #define user_stack_pointer(regs) ((regs)->sp) | 91 | #define user_stack_pointer(regs) ((regs)->sp) |
diff --git a/arch/mn10300/include/asm/smp.h b/arch/mn10300/include/asm/smp.h index b8585b4e8cdf..a3930e43a958 100644 --- a/arch/mn10300/include/asm/smp.h +++ b/arch/mn10300/include/asm/smp.h | |||
@@ -93,19 +93,6 @@ extern int __cpu_disable(void); | |||
93 | extern void __cpu_die(unsigned int cpu); | 93 | extern void __cpu_die(unsigned int cpu); |
94 | #endif /* CONFIG_HOTPLUG_CPU */ | 94 | #endif /* CONFIG_HOTPLUG_CPU */ |
95 | 95 | ||
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 | |||
109 | #endif /* __ASSEMBLY__ */ | 96 | #endif /* __ASSEMBLY__ */ |
110 | #else /* CONFIG_SMP */ | 97 | #else /* CONFIG_SMP */ |
111 | #ifndef __ASSEMBLY__ | 98 | #ifndef __ASSEMBLY__ |
diff --git a/arch/mn10300/include/asm/thread_info.h b/arch/mn10300/include/asm/thread_info.h index 2001cb657a95..aa07a4a5d794 100644 --- a/arch/mn10300/include/asm/thread_info.h +++ b/arch/mn10300/include/asm/thread_info.h | |||
@@ -16,10 +16,6 @@ | |||
16 | 16 | ||
17 | #include <asm/page.h> | 17 | #include <asm/page.h> |
18 | 18 | ||
19 | #ifndef __ASSEMBLY__ | ||
20 | #include <asm/processor.h> | ||
21 | #endif | ||
22 | |||
23 | #define PREEMPT_ACTIVE 0x10000000 | 19 | #define PREEMPT_ACTIVE 0x10000000 |
24 | 20 | ||
25 | #ifdef CONFIG_4KSTACKS | 21 | #ifdef CONFIG_4KSTACKS |
@@ -38,10 +34,14 @@ | |||
38 | * must also be changed | 34 | * must also be changed |
39 | */ | 35 | */ |
40 | #ifndef __ASSEMBLY__ | 36 | #ifndef __ASSEMBLY__ |
37 | typedef struct { | ||
38 | unsigned long seg; | ||
39 | } mm_segment_t; | ||
41 | 40 | ||
42 | struct thread_info { | 41 | struct thread_info { |
43 | struct task_struct *task; /* main task structure */ | 42 | struct task_struct *task; /* main task structure */ |
44 | struct exec_domain *exec_domain; /* execution domain */ | 43 | struct exec_domain *exec_domain; /* execution domain */ |
44 | struct pt_regs *frame; /* current exception frame */ | ||
45 | unsigned long flags; /* low level flags */ | 45 | unsigned long flags; /* low level flags */ |
46 | __u32 cpu; /* current CPU */ | 46 | __u32 cpu; /* current CPU */ |
47 | __s32 preempt_count; /* 0 => preemptable, <0 => BUG */ | 47 | __s32 preempt_count; /* 0 => preemptable, <0 => BUG */ |
@@ -55,6 +55,10 @@ struct thread_info { | |||
55 | __u8 supervisor_stack[0]; | 55 | __u8 supervisor_stack[0]; |
56 | }; | 56 | }; |
57 | 57 | ||
58 | #define thread_info_to_uregs(ti) \ | ||
59 | ((struct pt_regs *) \ | ||
60 | ((unsigned long)ti + THREAD_SIZE - sizeof(struct pt_regs))) | ||
61 | |||
58 | #else /* !__ASSEMBLY__ */ | 62 | #else /* !__ASSEMBLY__ */ |
59 | 63 | ||
60 | #ifndef __ASM_OFFSETS_H__ | 64 | #ifndef __ASM_OFFSETS_H__ |
@@ -102,6 +106,12 @@ struct thread_info *current_thread_info(void) | |||
102 | return ti; | 106 | return ti; |
103 | } | 107 | } |
104 | 108 | ||
109 | static inline __attribute__((const)) | ||
110 | struct pt_regs *current_frame(void) | ||
111 | { | ||
112 | return current_thread_info()->frame; | ||
113 | } | ||
114 | |||
105 | /* how to get the current stack pointer from C */ | 115 | /* how to get the current stack pointer from C */ |
106 | static inline unsigned long current_stack_pointer(void) | 116 | static inline unsigned long current_stack_pointer(void) |
107 | { | 117 | { |
diff --git a/arch/mn10300/include/asm/uaccess.h b/arch/mn10300/include/asm/uaccess.h index 47e7951e6893..679dee0bbd08 100644 --- a/arch/mn10300/include/asm/uaccess.h +++ b/arch/mn10300/include/asm/uaccess.h | |||
@@ -14,9 +14,8 @@ | |||
14 | /* | 14 | /* |
15 | * User space memory access functions | 15 | * User space memory access functions |
16 | */ | 16 | */ |
17 | #include <linux/sched.h> | 17 | #include <linux/thread_info.h> |
18 | #include <asm/page.h> | 18 | #include <asm/page.h> |
19 | #include <asm/pgtable.h> | ||
20 | #include <asm/errno.h> | 19 | #include <asm/errno.h> |
21 | 20 | ||
22 | #define VERIFY_READ 0 | 21 | #define VERIFY_READ 0 |
@@ -29,7 +28,6 @@ | |||
29 | * | 28 | * |
30 | * For historical reasons, these macros are grossly misnamed. | 29 | * For historical reasons, these macros are grossly misnamed. |
31 | */ | 30 | */ |
32 | |||
33 | #define MAKE_MM_SEG(s) ((mm_segment_t) { (s) }) | 31 | #define MAKE_MM_SEG(s) ((mm_segment_t) { (s) }) |
34 | 32 | ||
35 | #define KERNEL_XDS MAKE_MM_SEG(0xBFFFFFFF) | 33 | #define KERNEL_XDS MAKE_MM_SEG(0xBFFFFFFF) |