diff options
| author | Russell King <rmk@flint.arm.linux.org.uk> | 2002-05-29 18:06:54 +0100 |
|---|---|---|
| committer | Russell King <rmk@flint.arm.linux.org.uk> | 2002-05-29 18:06:54 +0100 |
| commit | 415395e19fd197ce4f248902dba54f4065af547c (patch) | |
| tree | e1c8c080ac83c3ca26aac461a444c8eb4ea6a18b /include | |
| parent | baa522c86b6f08c9bdab5a966a8726a7a5f665c2 (diff) | |
[ARM] Context switch improvements
- We don't need to save the CPSR.
- Rearrange thread_info members so we can pull the fields out of
thread_info more efficiently.
- Allocate a couple of extra words for CPU specific context saving
(eg, for Xscale ACC registers)
- Always leave 8 bytes free at the top of the kernel stack. This
prevents the stack becoming completely empty when do_exit() is
called from an exiting nfsd() thread, and causing the wrong
pointer to be returned from current_thread_info()
Diffstat (limited to 'include')
| -rw-r--r-- | include/asm-arm/proc-armo/processor.h | 22 | ||||
| -rw-r--r-- | include/asm-arm/proc-armv/processor.h | 24 | ||||
| -rw-r--r-- | include/asm-arm/thread_info.h | 53 |
3 files changed, 31 insertions, 68 deletions
diff --git a/include/asm-arm/proc-armo/processor.h b/include/asm-arm/proc-armo/processor.h index abaccf51239f..675fe0f51592 100644 --- a/include/asm-arm/proc-armo/processor.h +++ b/include/asm-arm/proc-armo/processor.h @@ -20,27 +20,9 @@ #define __ASM_PROC_PROCESSOR_H #include <linux/string.h> -#include <asm/proc/ptrace.h> #define KERNEL_STACK_SIZE 4096 -struct cpu_context_save { - unsigned long r4; - unsigned long r5; - unsigned long r6; - unsigned long r7; - unsigned long r8; - unsigned long r9; - unsigned long sl; - unsigned long fp; - unsigned long pc; -}; - -static inline void init_pc_psr(struct cpu_context_save *s, void *fn) -{ - s->pc = ((unsigned long)fn) | PSR_I_BIT | SVC26_MODE; -} - typedef struct { void (*put_byte)(void); /* Special calling convention */ void (*get_byte)(void); /* Special calling convention */ @@ -75,7 +57,7 @@ extern uaccess_t uaccess_user, uaccess_kernel; regs->ARM_r0 = stack[0]; /* r0 (argc) */ \ }) -#define KSTK_EIP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1022]) -#define KSTK_ESP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1020]) +#define KSTK_EIP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1020]) +#define KSTK_ESP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1018]) #endif diff --git a/include/asm-arm/proc-armv/processor.h b/include/asm-arm/proc-armv/processor.h index e9de5db23146..0e8c4bfee6dc 100644 --- a/include/asm-arm/proc-armv/processor.h +++ b/include/asm-arm/proc-armv/processor.h @@ -19,29 +19,9 @@ #define __ASM_PROC_PROCESSOR_H #include <asm/proc/domain.h> -#include <asm/proc/ptrace.h> #define KERNEL_STACK_SIZE PAGE_SIZE -struct cpu_context_save { - unsigned long cpsr; - unsigned long r4; - unsigned long r5; - unsigned long r6; - unsigned long r7; - unsigned long r8; - unsigned long r9; - unsigned long sl; - unsigned long fp; - unsigned long pc; -}; - -static inline void init_pc_psr(struct cpu_context_save *s, void *fn) -{ - s->pc = (unsigned long)fn; - s->cpsr = PSR_I_BIT | SVC_MODE; -} - #define INIT_EXTRA_THREAD_INFO \ cpu_domain: domain_val(DOMAIN_USER, DOMAIN_CLIENT) | \ domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \ @@ -63,7 +43,7 @@ static inline void init_pc_psr(struct cpu_context_save *s, void *fn) regs->ARM_r0 = stack[0]; /* r0 (argc) */ \ }) -#define KSTK_EIP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1021]) -#define KSTK_ESP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1019]) +#define KSTK_EIP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1019]) +#define KSTK_ESP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1017]) #endif diff --git a/include/asm-arm/thread_info.h b/include/asm-arm/thread_info.h index 154a688c170f..ebed4a570599 100644 --- a/include/asm-arm/thread_info.h +++ b/include/asm-arm/thread_info.h @@ -22,20 +22,35 @@ struct exec_domain; #include <asm/ptrace.h> #include <asm/types.h> -typedef unsigned long mm_segment_t; /* domain register */ +typedef unsigned long mm_segment_t; + +struct cpu_context_save { + __u32 r4; + __u32 r5; + __u32 r6; + __u32 r7; + __u32 r8; + __u32 r9; + __u32 sl; + __u32 fp; + __u32 sp; + __u32 pc; + __u32 extra[2]; /* Xscale 'acc' register, etc */ +}; /* * low level task data that entry.S needs immediate access to. + * We assume cpu_context follows immedately after cpu_domain. */ struct thread_info { unsigned long flags; /* low level flags */ __s32 preempt_count; /* 0 => preemptable, <0 => bug */ mm_segment_t addr_limit; /* address limit */ - __u32 cpu; /* cpu */ - struct cpu_context_save *cpu_context; /* cpu context */ - __u32 cpu_domain; /* cpu domain */ struct task_struct *task; /* main task structure */ struct exec_domain *exec_domain; /* execution domain */ + __u32 cpu; /* cpu */ + __u32 cpu_domain; /* cpu domain */ + struct cpu_context_save cpu_context; /* cpu context */ union fp_state fpstate; }; @@ -71,34 +86,20 @@ extern void free_thread_info(struct thread_info *); #define get_thread_info(ti) get_task_struct((ti)->task) #define put_thread_info(ti) put_task_struct((ti)->task) -static inline unsigned long __thread_saved_pc(struct thread_info *thread) -{ - struct cpu_context_save *context = thread->cpu_context; - - return context ? pc_pointer(context->pc) : 0; -} - -static inline unsigned long __thread_saved_fp(struct thread_info *thread) -{ - struct cpu_context_save *context = thread->cpu_context; - - return context ? context->fp : 0; -} - -#define thread_saved_pc(tsk) __thread_saved_pc((tsk)->thread_info) -#define thread_saved_fp(tsk) __thread_saved_fp((tsk)->thread_info) +#define thread_saved_pc(tsk) (pc_pointer((tsk)->thread_info->cpu_context.pc)) +#define thread_saved_fp(tsk) ((tsk)->thread_info->cpu_context.fp) #else /* !__ASSEMBLY__ */ #define TI_FLAGS 0 #define TI_PREEMPT 4 #define TI_ADDR_LIMIT 8 -#define TI_CPU 12 -#define TI_CPU_SAVE 16 -#define TI_CPU_DOMAIN 20 -#define TI_TASK 24 -#define TI_EXEC_DOMAIN 28 -#define TI_FPSTATE 32 +#define TI_TASK 12 +#define TI_EXEC_DOMAIN 16 +#define TI_CPU 20 +#define TI_CPU_DOMAIN 24 +#define TI_CPU_SAVE 28 +#define TI_FPSTATE 76 #endif |
