diff options
author | David Howells <dhowells@redhat.com> | 2010-10-27 17:29:01 +0100 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2010-10-27 17:29:01 +0100 |
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 406060e5e1c..2ee58e3eb6b 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 a848cd232eb..97d0cb5af80 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 a19f11327cd..146bacf193e 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 75c422abcd6..4c1b5cc14c1 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 c2b77bd3064..b6961811d44 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 b8585b4e8cd..a3930e43a95 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 2001cb657a9..aa07a4a5d79 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 47e7951e689..679dee0bbd0 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) |