aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mn10300/include/asm
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/include/asm
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/include/asm')
-rw-r--r--arch/mn10300/include/asm/frame.inc56
-rw-r--r--arch/mn10300/include/asm/irq_regs.h6
-rw-r--r--arch/mn10300/include/asm/pgalloc.h1
-rw-r--r--arch/mn10300/include/asm/processor.h46
-rw-r--r--arch/mn10300/include/asm/ptrace.h6
-rw-r--r--arch/mn10300/include/asm/smp.h13
-rw-r--r--arch/mn10300/include/asm/thread_info.h18
-rw-r--r--arch/mn10300/include/asm/uaccess.h4
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) 21static inline __attribute__((const))
22struct 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 */
22struct task_struct; 25struct 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
86typedef struct {
87 unsigned long seg;
88} mm_segment_t;
89
90struct fpu_state_struct { 89struct 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 */ 125static 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. */
151extern void release_thread(struct task_struct *); 141extern 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
90extern struct pt_regs *___frame[]; /* current frame pointer */
91#else
92extern 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);
93extern void __cpu_die(unsigned int cpu); 93extern 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__
37typedef struct {
38 unsigned long seg;
39} mm_segment_t;
41 40
42struct thread_info { 41struct 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
109static inline __attribute__((const))
110struct 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 */
106static inline unsigned long current_stack_pointer(void) 116static 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)