From de06d3c70c203dbf05a0e82adebfd8b0735fe0bc Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 26 Sep 2012 01:21:14 -0400 Subject: [PATCH] --- yaml --- r: 340244 b: refs/heads/master c: dff933da765fd4855393846fa55286d1ff2d024a h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/arch/c6x/Kconfig | 1 - trunk/arch/c6x/include/uapi/asm/unistd.h | 1 + trunk/arch/c6x/kernel/entry.S | 12 +++- trunk/arch/mips/Kconfig | 2 - trunk/arch/mips/include/asm/processor.h | 2 + trunk/arch/mips/include/asm/ptrace.h | 6 -- trunk/arch/mips/include/asm/unistd.h | 1 - trunk/arch/mips/kernel/entry.S | 6 -- trunk/arch/mips/kernel/linux32.c | 21 +++++++ trunk/arch/mips/kernel/mips_ksyms.c | 2 + trunk/arch/mips/kernel/process.c | 62 ++++++++++++------- trunk/arch/mips/kernel/scall64-n32.S | 2 +- trunk/arch/mips/kernel/scall64-o32.S | 2 +- trunk/arch/mips/kernel/syscall.c | 53 ++++++++++++++++ trunk/arch/sparc/include/asm/ptrace.h | 4 +- trunk/arch/sparc/include/asm/switch_to_64.h | 2 +- trunk/arch/sparc/include/asm/thread_info_64.h | 25 ++++---- trunk/arch/sparc/include/asm/uaccess_64.h | 4 +- trunk/arch/sparc/kernel/etrap_64.S | 8 ++- trunk/arch/sparc/kernel/process_64.c | 9 ++- trunk/arch/sparc/kernel/syscalls.S | 1 - trunk/arch/sparc/kernel/traps_64.c | 4 +- trunk/arch/sparc/mm/init_64.c | 2 +- 24 files changed, 162 insertions(+), 72 deletions(-) diff --git a/[refs] b/[refs] index 3789cd363141..ec5cff282178 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: fefec52b98b55b0bfc31aac39befe8200db0f047 +refs/heads/master: dff933da765fd4855393846fa55286d1ff2d024a diff --git a/trunk/arch/c6x/Kconfig b/trunk/arch/c6x/Kconfig index 66eab3703c75..aee1b569ee6e 100644 --- a/trunk/arch/c6x/Kconfig +++ b/trunk/arch/c6x/Kconfig @@ -18,7 +18,6 @@ config C6X select OF_EARLY_FLATTREE select GENERIC_CLOCKEVENTS select GENERIC_KERNEL_THREAD - select GENERIC_KERNEL_EXECVE select MODULES_USE_ELF_RELA config MMU diff --git a/trunk/arch/c6x/include/uapi/asm/unistd.h b/trunk/arch/c6x/include/uapi/asm/unistd.h index 625beafb9cd1..4ff747d12dad 100644 --- a/trunk/arch/c6x/include/uapi/asm/unistd.h +++ b/trunk/arch/c6x/include/uapi/asm/unistd.h @@ -14,6 +14,7 @@ * more details. */ +#define __ARCH_WANT_KERNEL_EXECVE #define __ARCH_WANT_SYS_EXECVE /* Use the standard ABI for syscalls. */ diff --git a/trunk/arch/c6x/kernel/entry.S b/trunk/arch/c6x/kernel/entry.S index 75f6f36472cf..5449c36018fe 100644 --- a/trunk/arch/c6x/kernel/entry.S +++ b/trunk/arch/c6x/kernel/entry.S @@ -413,9 +413,19 @@ ENTRY(ret_from_kernel_thread) 0: B .S2 B10 /* call fn */ LDW .D2T1 *+SP(REGS_A1+8),A4 /* get arg */ - ADDKPC .S2 ret_from_fork_2,B3,3 + MVKL .S2 sys_exit,B11 + MVKH .S2 sys_exit,B11 + ADDKPC .S2 0f,B3,1 +0: + BNOP .S2 B11,5 /* jump to sys_exit */ ENDPROC(ret_from_kernel_thread) +ENTRY(ret_from_kernel_execve) + GET_THREAD_INFO A12 + BNOP .S2 syscall_exit,4 + ADD .D2X A4,-8,SP +ENDPROC(ret_from_kernel_execve) + ;; ;; These are the interrupt handlers, responsible for calling __do_IRQ() ;; int6 is used for syscalls (see _system_call entry) diff --git a/trunk/arch/mips/Kconfig b/trunk/arch/mips/Kconfig index 4183e62f178c..dba9390d37cf 100644 --- a/trunk/arch/mips/Kconfig +++ b/trunk/arch/mips/Kconfig @@ -40,8 +40,6 @@ config MIPS select HAVE_MOD_ARCH_SPECIFIC select MODULES_USE_ELF_REL select MODULES_USE_ELF_RELA if 64BIT - select GENERIC_KERNEL_THREAD - select GENERIC_KERNEL_EXECVE menu "Machine selection" diff --git a/trunk/arch/mips/include/asm/processor.h b/trunk/arch/mips/include/asm/processor.h index d28c41e0887c..5e33fabe354d 100644 --- a/trunk/arch/mips/include/asm/processor.h +++ b/trunk/arch/mips/include/asm/processor.h @@ -310,6 +310,8 @@ struct task_struct; /* Free all resources held by a thread. */ #define release_thread(thread) do { } while(0) +extern long kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); + extern unsigned long thread_saved_pc(struct task_struct *tsk); /* diff --git a/trunk/arch/mips/include/asm/ptrace.h b/trunk/arch/mips/include/asm/ptrace.h index cec5e125f7e4..4f5da948a777 100644 --- a/trunk/arch/mips/include/asm/ptrace.h +++ b/trunk/arch/mips/include/asm/ptrace.h @@ -61,10 +61,4 @@ static inline void die_if_kernel(const char *str, struct pt_regs *regs) die(str, regs); } -#define current_pt_regs() \ -({ \ - unsigned long sp = (unsigned long)__builtin_frame_address(0); \ - (struct pt_regs *)((sp | (THREAD_SIZE - 1)) + 1 - 32) - 1; \ -}) - #endif /* _ASM_PTRACE_H */ diff --git a/trunk/arch/mips/include/asm/unistd.h b/trunk/arch/mips/include/asm/unistd.h index b306e2081cad..9e47cc11aa26 100644 --- a/trunk/arch/mips/include/asm/unistd.h +++ b/trunk/arch/mips/include/asm/unistd.h @@ -20,7 +20,6 @@ #define __ARCH_OMIT_COMPAT_SYS_GETDENTS64 #define __ARCH_WANT_OLD_READDIR #define __ARCH_WANT_SYS_ALARM -#define __ARCH_WANT_SYS_EXECVE #define __ARCH_WANT_SYS_GETHOSTNAME #define __ARCH_WANT_SYS_IPC #define __ARCH_WANT_SYS_PAUSE diff --git a/trunk/arch/mips/kernel/entry.S b/trunk/arch/mips/kernel/entry.S index 3320cb4ac1d4..a6c133212003 100644 --- a/trunk/arch/mips/kernel/entry.S +++ b/trunk/arch/mips/kernel/entry.S @@ -65,12 +65,6 @@ need_resched: b need_resched #endif -FEXPORT(ret_from_kernel_thread) - jal schedule_tail # a0 = struct task_struct *prev - move a0, s1 - jal s0 - j syscall_exit - FEXPORT(ret_from_fork) jal schedule_tail # a0 = struct task_struct *prev diff --git a/trunk/arch/mips/kernel/linux32.c b/trunk/arch/mips/kernel/linux32.c index 8796dbc7e358..3a21acedf882 100644 --- a/trunk/arch/mips/kernel/linux32.c +++ b/trunk/arch/mips/kernel/linux32.c @@ -3,6 +3,7 @@ * * Copyright (C) 2000 Silicon Graphics, Inc. * Written by Ulf Carlsson (ulfc@engr.sgi.com) + * sys32_execve from ia64/ia32 code, Feb 2000, Kanoj Sarcar (kanoj@sgi.com) */ #include #include @@ -76,6 +77,26 @@ SYSCALL_DEFINE6(32_mmap2, unsigned long, addr, unsigned long, len, return error; } +/* + * sys_execve() executes a new program. + */ +asmlinkage int sys32_execve(nabi_no_regargs struct pt_regs regs) +{ + int error; + struct filename *filename; + + filename = getname(compat_ptr(regs.regs[4])); + error = PTR_ERR(filename); + if (IS_ERR(filename)) + goto out; + error = compat_do_execve(filename->name, compat_ptr(regs.regs[5]), + compat_ptr(regs.regs[6]), ®s); + putname(filename); + +out: + return error; +} + #define RLIM_INFINITY32 0x7fffffff #define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x) diff --git a/trunk/arch/mips/kernel/mips_ksyms.c b/trunk/arch/mips/kernel/mips_ksyms.c index 2d9304c2b54c..3fc1691110dc 100644 --- a/trunk/arch/mips/kernel/mips_ksyms.c +++ b/trunk/arch/mips/kernel/mips_ksyms.c @@ -32,6 +32,8 @@ EXPORT_SYMBOL(memset); EXPORT_SYMBOL(memcpy); EXPORT_SYMBOL(memmove); +EXPORT_SYMBOL(kernel_thread); + /* * Functions that operate on entire pages. Mostly used by memory management. */ diff --git a/trunk/arch/mips/kernel/process.c b/trunk/arch/mips/kernel/process.c index d13720ac656f..e9a5fd7277f4 100644 --- a/trunk/arch/mips/kernel/process.c +++ b/trunk/arch/mips/kernel/process.c @@ -84,7 +84,6 @@ void __noreturn cpu_idle(void) } asmlinkage void ret_from_fork(void); -asmlinkage void ret_from_kernel_thread(void); void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp) { @@ -114,7 +113,7 @@ void flush_thread(void) } int copy_thread(unsigned long clone_flags, unsigned long usp, - unsigned long arg, struct task_struct *p, struct pt_regs *regs) + unsigned long unused, struct task_struct *p, struct pt_regs *regs) { struct thread_info *ti = task_thread_info(p); struct pt_regs *childregs; @@ -137,30 +136,19 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, childregs = (struct pt_regs *) childksp - 1; /* Put the stack after the struct pt_regs. */ childksp = (unsigned long) childregs; - p->thread.cp0_status = read_c0_status() & ~(ST0_CU2|ST0_CU1); - if (unlikely(p->flags & PF_KTHREAD)) { - unsigned long status = p->thread.cp0_status; - memset(childregs, 0, sizeof(struct pt_regs)); - ti->addr_limit = KERNEL_DS; - p->thread.reg16 = usp; /* fn */ - p->thread.reg17 = arg; - p->thread.reg29 = childksp; - p->thread.reg31 = (unsigned long) ret_from_kernel_thread; -#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) - status = (status & ~(ST0_KUP | ST0_IEP | ST0_IEC)) | - ((status & (ST0_KUC | ST0_IEC)) << 2); -#else - status |= ST0_EXL; -#endif - childregs->cp0_status = status; - return 0; - } *childregs = *regs; childregs->regs[7] = 0; /* Clear error flag */ + childregs->regs[2] = 0; /* Child gets zero as return value */ - childregs->regs[29] = usp; - ti->addr_limit = USER_DS; + if (childregs->cp0_status & ST0_CU0) { + childregs->regs[28] = (unsigned long) ti; + childregs->regs[29] = childksp; + ti->addr_limit = KERNEL_DS; + } else { + childregs->regs[29] = usp; + ti->addr_limit = USER_DS; + } p->thread.reg29 = (unsigned long) childregs; p->thread.reg31 = (unsigned long) ret_from_fork; @@ -168,6 +156,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, * New tasks lose permission to use the fpu. This accelerates context * switching for most programs since they don't use the fpu. */ + p->thread.cp0_status = read_c0_status() & ~(ST0_CU2|ST0_CU1); childregs->cp0_status &= ~(ST0_CU2|ST0_CU1); #ifdef CONFIG_MIPS_MT_SMTC @@ -232,6 +221,35 @@ int dump_task_fpu(struct task_struct *t, elf_fpregset_t *fpr) return 1; } +/* + * Create a kernel thread + */ +static void __noreturn kernel_thread_helper(void *arg, int (*fn)(void *)) +{ + do_exit(fn(arg)); +} + +long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) +{ + struct pt_regs regs; + + memset(®s, 0, sizeof(regs)); + + regs.regs[4] = (unsigned long) arg; + regs.regs[5] = (unsigned long) fn; + regs.cp0_epc = (unsigned long) kernel_thread_helper; + regs.cp0_status = read_c0_status(); +#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) + regs.cp0_status = (regs.cp0_status & ~(ST0_KUP | ST0_IEP | ST0_IEC)) | + ((regs.cp0_status & (ST0_KUC | ST0_IEC)) << 2); +#else + regs.cp0_status |= ST0_EXL; +#endif + + /* Ok, create the new process.. */ + return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); +} + /* * */ diff --git a/trunk/arch/mips/kernel/scall64-n32.S b/trunk/arch/mips/kernel/scall64-n32.S index d27ca340d46d..f6ba8381ee01 100644 --- a/trunk/arch/mips/kernel/scall64-n32.S +++ b/trunk/arch/mips/kernel/scall64-n32.S @@ -167,7 +167,7 @@ EXPORT(sysn32_call_table) PTR sys_getsockopt PTR sys_clone /* 6055 */ PTR sys_fork - PTR compat_sys_execve + PTR sys32_execve PTR sys_exit PTR compat_sys_wait4 PTR sys_kill /* 6060 */ diff --git a/trunk/arch/mips/kernel/scall64-o32.S b/trunk/arch/mips/kernel/scall64-o32.S index 9601be6afa3d..53c2d7245764 100644 --- a/trunk/arch/mips/kernel/scall64-o32.S +++ b/trunk/arch/mips/kernel/scall64-o32.S @@ -203,7 +203,7 @@ sys_call_table: PTR sys_creat PTR sys_link PTR sys_unlink /* 4010 */ - PTR compat_sys_execve + PTR sys32_execve PTR sys_chdir PTR compat_sys_time PTR sys_mknod diff --git a/trunk/arch/mips/kernel/syscall.c b/trunk/arch/mips/kernel/syscall.c index c611e2df7767..2bd561bc05ae 100644 --- a/trunk/arch/mips/kernel/syscall.c +++ b/trunk/arch/mips/kernel/syscall.c @@ -127,6 +127,28 @@ _sys_clone(nabi_no_regargs struct pt_regs regs) parent_tidptr, child_tidptr); } +/* + * sys_execve() executes a new program. + */ +asmlinkage int sys_execve(nabi_no_regargs struct pt_regs regs) +{ + int error; + struct filename *filename; + + filename = getname((const char __user *) (long)regs.regs[4]); + error = PTR_ERR(filename); + if (IS_ERR(filename)) + goto out; + error = do_execve(filename->name, + (const char __user *const __user *) (long)regs.regs[5], + (const char __user *const __user *) (long)regs.regs[6], + ®s); + putname(filename); + +out: + return error; +} + SYSCALL_DEFINE1(set_thread_area, unsigned long, addr) { struct thread_info *ti = task_thread_info(current); @@ -291,3 +313,34 @@ asmlinkage void bad_stack(void) { do_exit(SIGSEGV); } + +/* + * Do a system call from kernel instead of calling sys_execve so we + * end up with proper pt_regs. + */ +int kernel_execve(const char *filename, + const char *const argv[], + const char *const envp[]) +{ + register unsigned long __a0 asm("$4") = (unsigned long) filename; + register unsigned long __a1 asm("$5") = (unsigned long) argv; + register unsigned long __a2 asm("$6") = (unsigned long) envp; + register unsigned long __a3 asm("$7"); + unsigned long __v0; + + __asm__ volatile (" \n" + " .set noreorder \n" + " li $2, %5 # __NR_execve \n" + " syscall \n" + " move %0, $2 \n" + " .set reorder \n" + : "=&r" (__v0), "=r" (__a3) + : "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_execve) + : "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", + "memory"); + + if (__a3 == 0) + return __v0; + + return -__v0; +} diff --git a/trunk/arch/sparc/include/asm/ptrace.h b/trunk/arch/sparc/include/asm/ptrace.h index 0c6f6b068289..5b6019e327e5 100644 --- a/trunk/arch/sparc/include/asm/ptrace.h +++ b/trunk/arch/sparc/include/asm/ptrace.h @@ -44,9 +44,7 @@ struct global_reg_snapshot { }; extern struct global_reg_snapshot global_reg_snapshot[NR_CPUS]; -#define force_successful_syscall_return() \ -do { current_thread_info()->syscall_noerror = 1; \ -} while (0) +#define force_successful_syscall_return() set_thread_noerror(1) #define user_mode(regs) (!((regs)->tstate & TSTATE_PRIV)) #define instruction_pointer(regs) ((regs)->tpc) #define instruction_pointer_set(regs, val) ((regs)->tpc = (val)) diff --git a/trunk/arch/sparc/include/asm/switch_to_64.h b/trunk/arch/sparc/include/asm/switch_to_64.h index 7923c4a2be38..cad36f56fa03 100644 --- a/trunk/arch/sparc/include/asm/switch_to_64.h +++ b/trunk/arch/sparc/include/asm/switch_to_64.h @@ -23,7 +23,7 @@ do { flush_tlb_pending(); \ /* If you are tempted to conditionalize the following */ \ /* so that ASI is only written if it changes, think again. */ \ __asm__ __volatile__("wr %%g0, %0, %%asi" \ - : : "r" (__thread_flag_byte_ptr(task_thread_info(next))[TI_FLAG_BYTE_CURRENT_DS]));\ + : : "r" (task_thread_info(next)->current_ds));\ trap_block[current_thread_info()->cpu].thread = \ task_thread_info(next); \ __asm__ __volatile__( \ diff --git a/trunk/arch/sparc/include/asm/thread_info_64.h b/trunk/arch/sparc/include/asm/thread_info_64.h index 4e2276631081..ea2ba22d595a 100644 --- a/trunk/arch/sparc/include/asm/thread_info_64.h +++ b/trunk/arch/sparc/include/asm/thread_info_64.h @@ -14,12 +14,12 @@ #define TI_FLAG_FAULT_CODE_SHIFT 56 #define TI_FLAG_BYTE_WSTATE 1 #define TI_FLAG_WSTATE_SHIFT 48 -#define TI_FLAG_BYTE_CWP 2 -#define TI_FLAG_CWP_SHIFT 40 -#define TI_FLAG_BYTE_CURRENT_DS 3 -#define TI_FLAG_CURRENT_DS_SHIFT 32 -#define TI_FLAG_BYTE_FPDEPTH 4 -#define TI_FLAG_FPDEPTH_SHIFT 24 +#define TI_FLAG_BYTE_NOERROR 2 +#define TI_FLAG_BYTE_NOERROR_SHIFT 40 +#define TI_FLAG_BYTE_FPDEPTH 3 +#define TI_FLAG_FPDEPTH_SHIFT 32 +#define TI_FLAG_BYTE_CWP 4 +#define TI_FLAG_CWP_SHIFT 24 #define TI_FLAG_BYTE_WSAVED 5 #define TI_FLAG_WSAVED_SHIFT 16 @@ -47,7 +47,7 @@ struct thread_info { struct exec_domain *exec_domain; int preempt_count; /* 0 => preemptable, <0 => BUG */ __u8 new_child; - __u8 syscall_noerror; + __u8 current_ds; __u16 cpu; unsigned long *utraps; @@ -74,9 +74,9 @@ struct thread_info { #define TI_FAULT_CODE (TI_FLAGS + TI_FLAG_BYTE_FAULT_CODE) #define TI_WSTATE (TI_FLAGS + TI_FLAG_BYTE_WSTATE) #define TI_CWP (TI_FLAGS + TI_FLAG_BYTE_CWP) -#define TI_CURRENT_DS (TI_FLAGS + TI_FLAG_BYTE_CURRENT_DS) #define TI_FPDEPTH (TI_FLAGS + TI_FLAG_BYTE_FPDEPTH) #define TI_WSAVED (TI_FLAGS + TI_FLAG_BYTE_WSAVED) +#define TI_SYS_NOERROR (TI_FLAGS + TI_FLAG_BYTE_NOERROR) #define TI_FPSAVED 0x00000010 #define TI_KSP 0x00000018 #define TI_FAULT_ADDR 0x00000020 @@ -84,7 +84,7 @@ struct thread_info { #define TI_EXEC_DOMAIN 0x00000030 #define TI_PRE_COUNT 0x00000038 #define TI_NEW_CHILD 0x0000003c -#define TI_SYS_NOERROR 0x0000003d +#define TI_CURRENT_DS 0x0000003d #define TI_CPU 0x0000003e #define TI_UTRAPS 0x00000040 #define TI_REG_WINDOW 0x00000048 @@ -121,7 +121,7 @@ struct thread_info { #define INIT_THREAD_INFO(tsk) \ { \ .task = &tsk, \ - .flags = ((unsigned long)ASI_P) << TI_FLAG_CURRENT_DS_SHIFT, \ + .current_ds = ASI_P, \ .exec_domain = &default_exec_domain, \ .preempt_count = INIT_PREEMPT_COUNT, \ .restart_block = { \ @@ -153,13 +153,12 @@ register struct thread_info *current_thread_info_reg asm("g6"); #define set_thread_wstate(val) (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_WSTATE] = (val)) #define get_thread_cwp() (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_CWP]) #define set_thread_cwp(val) (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_CWP] = (val)) -#define get_thread_current_ds() (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_CURRENT_DS]) -#define set_thread_current_ds(val) (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_CURRENT_DS] = (val)) +#define get_thread_noerror() (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_NOERROR]) +#define set_thread_noerror(val) (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_NOERROR] = (val)) #define get_thread_fpdepth() (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_FPDEPTH]) #define set_thread_fpdepth(val) (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_FPDEPTH] = (val)) #define get_thread_wsaved() (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_WSAVED]) #define set_thread_wsaved(val) (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_WSAVED] = (val)) - #endif /* !(__ASSEMBLY__) */ /* diff --git a/trunk/arch/sparc/include/asm/uaccess_64.h b/trunk/arch/sparc/include/asm/uaccess_64.h index 73083e1d38d9..e562d3caee57 100644 --- a/trunk/arch/sparc/include/asm/uaccess_64.h +++ b/trunk/arch/sparc/include/asm/uaccess_64.h @@ -38,14 +38,14 @@ #define VERIFY_READ 0 #define VERIFY_WRITE 1 -#define get_fs() ((mm_segment_t) { get_thread_current_ds() }) +#define get_fs() ((mm_segment_t){(current_thread_info()->current_ds)}) #define get_ds() (KERNEL_DS) #define segment_eq(a,b) ((a).seg == (b).seg) #define set_fs(val) \ do { \ - set_thread_current_ds((val).seg); \ + current_thread_info()->current_ds =(val).seg; \ __asm__ __volatile__ ("wr %%g0, %0, %%asi" : : "r" ((val).seg)); \ } while(0) diff --git a/trunk/arch/sparc/kernel/etrap_64.S b/trunk/arch/sparc/kernel/etrap_64.S index 786b185e6e3f..1276ca2567ba 100644 --- a/trunk/arch/sparc/kernel/etrap_64.S +++ b/trunk/arch/sparc/kernel/etrap_64.S @@ -92,8 +92,10 @@ etrap_save: save %g2, -STACK_BIAS, %sp rdpr %wstate, %g2 wrpr %g0, 0, %canrestore sll %g2, 3, %g2 + + /* Set TI_SYS_FPDEPTH to 1 and clear TI_SYS_NOERROR. */ mov 1, %l5 - stb %l5, [%l6 + TI_FPDEPTH] + sth %l5, [%l6 + TI_SYS_NOERROR] wrpr %g3, 0, %otherwin wrpr %g2, 0, %wstate @@ -152,7 +154,9 @@ etrap_save: save %g2, -STACK_BIAS, %sp add %l6, TI_FPSAVED + 1, %l4 srl %l5, 1, %l3 add %l5, 2, %l5 - stb %l5, [%l6 + TI_FPDEPTH] + + /* Set TI_SYS_FPDEPTH to %l5 and clear TI_SYS_NOERROR. */ + sth %l5, [%l6 + TI_SYS_NOERROR] ba,pt %xcc, 2b stb %g0, [%l4 + %l3] nop diff --git a/trunk/arch/sparc/kernel/process_64.c b/trunk/arch/sparc/kernel/process_64.c index fcaa59421126..4c864c796507 100644 --- a/trunk/arch/sparc/kernel/process_64.c +++ b/trunk/arch/sparc/kernel/process_64.c @@ -557,9 +557,8 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, (THREAD_SIZE - child_stack_sz)); memcpy(child_trap_frame, parent_sf, child_stack_sz); - t->flags = (t->flags & ~((0xffUL << TI_FLAG_CWP_SHIFT) | - (0xffUL << TI_FLAG_CURRENT_DS_SHIFT))) | - (((regs->tstate + 1) & TSTATE_CWP) << TI_FLAG_CWP_SHIFT); + __thread_flag_byte_ptr(t)[TI_FLAG_BYTE_CWP] = + (regs->tstate + 1) & TSTATE_CWP; t->new_child = 1; t->ksp = ((unsigned long) child_trap_frame) - STACK_BIAS; t->kregs = (struct pt_regs *) (child_trap_frame + @@ -575,7 +574,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, t->kregs->u_regs[UREG_FP] = ((unsigned long) child_sf) - STACK_BIAS; - t->flags |= ((long)ASI_P << TI_FLAG_CURRENT_DS_SHIFT); + t->current_ds = ASI_P; t->kregs->u_regs[UREG_G6] = (unsigned long) t; t->kregs->u_regs[UREG_G4] = (unsigned long) t->task; } else { @@ -584,7 +583,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL; } t->kregs->u_regs[UREG_FP] = sp; - t->flags |= ((long)ASI_AIUS << TI_FLAG_CURRENT_DS_SHIFT); + t->current_ds = ASI_AIUS; if (sp != regs->u_regs[UREG_FP]) { unsigned long csp; diff --git a/trunk/arch/sparc/kernel/syscalls.S b/trunk/arch/sparc/kernel/syscalls.S index 7f5f65d0b3fd..b0ac10306425 100644 --- a/trunk/arch/sparc/kernel/syscalls.S +++ b/trunk/arch/sparc/kernel/syscalls.S @@ -222,7 +222,6 @@ ret_sys_call: ldx [%sp + PTREGS_OFF + PT_V9_TNPC], %l1 ! pc = npc 2: - stb %g0, [%g6 + TI_SYS_NOERROR] /* System call success, clear Carry condition code. */ andn %g3, %g2, %g3 3: diff --git a/trunk/arch/sparc/kernel/traps_64.c b/trunk/arch/sparc/kernel/traps_64.c index b66a77968f35..e7ecf1507d90 100644 --- a/trunk/arch/sparc/kernel/traps_64.c +++ b/trunk/arch/sparc/kernel/traps_64.c @@ -2688,8 +2688,8 @@ void __init trap_init(void) TI_PRE_COUNT != offsetof(struct thread_info, preempt_count) || TI_NEW_CHILD != offsetof(struct thread_info, new_child) || - TI_SYS_NOERROR != offsetof(struct thread_info, - syscall_noerror) || + TI_CURRENT_DS != offsetof(struct thread_info, + current_ds) || TI_RESTART_BLOCK != offsetof(struct thread_info, restart_block) || TI_KUNA_REGS != offsetof(struct thread_info, diff --git a/trunk/arch/sparc/mm/init_64.c b/trunk/arch/sparc/mm/init_64.c index 9e28a118e6a4..85be1ca539b2 100644 --- a/trunk/arch/sparc/mm/init_64.c +++ b/trunk/arch/sparc/mm/init_64.c @@ -624,7 +624,7 @@ static void __init inherit_prom_mappings(void) void prom_world(int enter) { if (!enter) - set_fs((mm_segment_t) { get_thread_current_ds() }); + set_fs(get_fs()); __asm__ __volatile__("flushw"); }