summaryrefslogtreecommitdiffstats
path: root/arch/mn10300/include
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2010-10-27 17:29:01 +0100
committerDavid Howells <dhowells@redhat.com>2010-10-27 17:29:01 +0100
commit7c7fcf762e405eb040ee10d22d656a791f616122 (patch)
tree2ec4f320fe2d348ffbdab6aebc9a36bcbf13da34 /arch/mn10300/include
parenta5e03ca2fd57a5823b759981bff8d19b46ddad4d (diff)
downloadblackbird-op-linux-7c7fcf762e405eb040ee10d22d656a791f616122.tar.gz
blackbird-op-linux-7c7fcf762e405eb040ee10d22d656a791f616122.zip
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')
-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 @@
#ifndef __ASM_OFFSETS_H__
#include <asm/asm-offsets.h>
#endif
-#ifdef CONFIG_SMP
-#include <proc/smp-regs.h>
-#endif
+#include <asm/thread_info.h>
#define pi break
@@ -40,27 +38,15 @@
movm [d2,d3,a2,a3,exreg0,exreg1,exother],(sp)
mov sp,fp # FRAME pointer in A3
add -12,sp # allow for calls to be made
-#ifdef CONFIG_SMP
-#ifdef CONFIG_PREEMPT /* FIXME */
- mov epsw,d2
- and ~EPSW_IE,epsw
-#endif
- mov (CPUID),a0
- add a0,a0
- add a0,a0
- mov (___frame,a0),a1
- mov a1,(REG_NEXT,fp)
- mov fp,(___frame,a0)
-#ifdef CONFIG_PREEMPT /* FIXME */
- mov d2,epsw
-#endif
-#else /* CONFIG_SMP */
- mov (__frame),a1
- mov a1,(REG_NEXT,fp)
- mov fp,(__frame)
-#endif /* CONFIG_SMP */
- and ~EPSW_FE,epsw # disable the FPU inside the kernel
+ # push the exception frame onto the front of the list
+ GET_THREAD_INFO a1
+ mov (TI_frame,a1),a0
+ mov a0,(REG_NEXT,fp)
+ mov fp,(TI_frame,a1)
+
+ # disable the FPU inside the kernel
+ and ~EPSW_FE,epsw
# we may be holding current in E2
#ifdef CONFIG_MN10300_CURRENT_IN_E2
@@ -76,27 +62,11 @@
.macro RESTORE_ALL
# peel back the stack to the calling frame
# - this permits execve() to discard extra frames due to kernel syscalls
-#ifdef CONFIG_SMP
-#ifdef CONFIG_PREEMPT /* FIXME */
- mov epsw,d2
- and ~EPSW_IE,epsw
-#endif
- mov (CPUID),a0
- add a0,a0
- add a0,a0
- mov (___frame,a0),fp
- mov fp,sp
- mov (REG_NEXT,fp),d0 # userspace has regs->next == 0
- mov d0,(___frame,a0)
-#ifdef CONFIG_PREEMPT /* FIXME */
- mov d2,epsw
-#endif
-#else /* CONFIG_SMP */
- mov (__frame),fp
+ GET_THREAD_INFO a0
+ mov (TI_frame,a0),fp
mov fp,sp
- mov (REG_NEXT,fp),d0 # userspace has regs->next == 0
- mov d0,(__frame)
-#endif /* CONFIG_SMP */
+ mov (REG_NEXT,fp),d0
+ mov d0,(TI_frame,a0) # userspace has regs->next == 0
#ifndef CONFIG_MN10300_USING_JTAG
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 @@
#define ARCH_HAS_OWN_IRQ_REGS
#ifndef __ASSEMBLY__
-#define get_irq_regs() (__frame)
+static inline __attribute__((const))
+struct pt_regs *get_irq_regs(void)
+{
+ return current_frame();
+}
#endif
#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 @@
#ifndef _ASM_PGALLOC_H
#define _ASM_PGALLOC_H
-#include <asm/processor.h>
#include <asm/page.h>
#include <linux/threads.h>
#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 @@
#ifndef _ASM_PROCESSOR_H
#define _ASM_PROCESSOR_H
+#include <linux/threads.h>
+#include <linux/thread_info.h>
#include <asm/page.h>
#include <asm/ptrace.h>
#include <asm/cpu-regs.h>
-#include <linux/threads.h>
+#include <asm/uaccess.h>
+#include <asm/current.h>
/* Forward declaration, a strange C thing */
struct task_struct;
@@ -83,10 +86,6 @@ extern void dodgy_tsc(void);
*/
#define TASK_UNMAPPED_BASE 0x30000000
-typedef struct {
- unsigned long seg;
-} mm_segment_t;
-
struct fpu_state_struct {
unsigned long fs[32]; /* fpu registers */
unsigned long fpcr; /* fpu control register */
@@ -99,7 +98,6 @@ struct thread_struct {
unsigned long a3; /* kernel FP */
unsigned long wchan;
unsigned long usp;
- struct pt_regs *frame;
unsigned long fpu_flags;
#define THREAD_USING_FPU 0x00000001 /* T if this task is using the FPU */
#define THREAD_HAS_FPU 0x00000002 /* T if this task owns the FPU right now */
@@ -113,7 +111,6 @@ struct thread_struct {
.sp = 0, \
.a3 = 0, \
.wchan = 0, \
- .frame = NULL, \
}
#define INIT_MMAP \
@@ -125,27 +122,20 @@ struct thread_struct {
* - need to discard the frame stacked by the kernel thread invoking the execve
* syscall (see RESTORE_ALL macro)
*/
-#if defined(CONFIG_SMP) && defined(CONFIG_PREEMPT) /* FIXME */
-#define start_thread(regs, new_pc, new_sp) do { \
- int cpu; \
- preempt_disable(); \
- cpu = CPUID; \
- set_fs(USER_DS); \
- ___frame[cpu] = current->thread.uregs; \
- ___frame[cpu]->epsw = EPSW_nSL | EPSW_IE | EPSW_IM;\
- ___frame[cpu]->pc = new_pc; \
- ___frame[cpu]->sp = new_sp; \
- preempt_enable(); \
-} while (0)
-#else /* CONFIG_SMP && CONFIG_PREEMPT */
-#define start_thread(regs, new_pc, new_sp) do { \
- set_fs(USER_DS); \
- __frame = current->thread.uregs; \
- __frame->epsw = EPSW_nSL | EPSW_IE | EPSW_IM; \
- __frame->pc = new_pc; \
- __frame->sp = new_sp; \
-} while (0)
-#endif /* CONFIG_SMP && CONFIG_PREEMPT */
+static inline void start_thread(struct pt_regs *regs,
+ unsigned long new_pc, unsigned long new_sp)
+{
+ struct thread_info *ti = current_thread_info();
+ struct pt_regs *frame0;
+ set_fs(USER_DS);
+
+ frame0 = thread_info_to_uregs(ti);
+ frame0->epsw = EPSW_nSL | EPSW_IE | EPSW_IM;
+ frame0->pc = new_pc;
+ frame0->sp = new_sp;
+ ti->frame = frame0;
+}
+
/* Free all resources held by a thread. */
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 {
#ifdef __KERNEL__
-#ifdef CONFIG_SMP
-extern struct pt_regs *___frame[]; /* current frame pointer */
-#else
-extern struct pt_regs *__frame; /* current frame pointer */
-#endif
-
#define user_mode(regs) (((regs)->epsw & EPSW_nSL) == EPSW_nSL)
#define instruction_pointer(regs) ((regs)->pc)
#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);
extern void __cpu_die(unsigned int cpu);
#endif /* CONFIG_HOTPLUG_CPU */
-#ifdef CONFIG_PREEMPT /* FIXME */
-#define __frame \
- ({ \
- struct pt_regs *f; \
- preempt_disable(); \
- f = ___frame[CPUID]; \
- preempt_enable(); \
- f; \
- })
-#else
-#define __frame ___frame[CPUID]
-#endif
-
#endif /* __ASSEMBLY__ */
#else /* CONFIG_SMP */
#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 @@
#include <asm/page.h>
-#ifndef __ASSEMBLY__
-#include <asm/processor.h>
-#endif
-
#define PREEMPT_ACTIVE 0x10000000
#ifdef CONFIG_4KSTACKS
@@ -38,10 +34,14 @@
* must also be changed
*/
#ifndef __ASSEMBLY__
+typedef struct {
+ unsigned long seg;
+} mm_segment_t;
struct thread_info {
struct task_struct *task; /* main task structure */
struct exec_domain *exec_domain; /* execution domain */
+ struct pt_regs *frame; /* current exception frame */
unsigned long flags; /* low level flags */
__u32 cpu; /* current CPU */
__s32 preempt_count; /* 0 => preemptable, <0 => BUG */
@@ -55,6 +55,10 @@ struct thread_info {
__u8 supervisor_stack[0];
};
+#define thread_info_to_uregs(ti) \
+ ((struct pt_regs *) \
+ ((unsigned long)ti + THREAD_SIZE - sizeof(struct pt_regs)))
+
#else /* !__ASSEMBLY__ */
#ifndef __ASM_OFFSETS_H__
@@ -102,6 +106,12 @@ struct thread_info *current_thread_info(void)
return ti;
}
+static inline __attribute__((const))
+struct pt_regs *current_frame(void)
+{
+ return current_thread_info()->frame;
+}
+
/* how to get the current stack pointer from C */
static inline unsigned long current_stack_pointer(void)
{
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 @@
/*
* User space memory access functions
*/
-#include <linux/sched.h>
+#include <linux/thread_info.h>
#include <asm/page.h>
-#include <asm/pgtable.h>
#include <asm/errno.h>
#define VERIFY_READ 0
@@ -29,7 +28,6 @@
*
* For historical reasons, these macros are grossly misnamed.
*/
-
#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
#define KERNEL_XDS MAKE_MM_SEG(0xBFFFFFFF)
OpenPOWER on IntegriCloud