diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-12 10:49:08 +0900 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-12 10:49:08 +0900 |
commit | 8213a2f3eeafdecf06dd718cb4130372263f6067 (patch) | |
tree | 0d02e3201dac64d1429f8552ee1163d4a1ef1646 /arch/frv | |
parent | 40924754f2cabd5d9af4bcd4dcecc362b5e0baa1 (diff) | |
parent | 12f79be93d94698778ff2b3f921073fc5f6780d6 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal
Pull pile 2 of execve and kernel_thread unification work from Al Viro:
"Stuff in there: kernel_thread/kernel_execve/sys_execve conversions for
several more architectures plus assorted signal fixes and cleanups.
There'll be more (in particular, real fixes for the alpha
do_notify_resume() irq mess)..."
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal: (43 commits)
alpha: don't open-code trace_report_syscall_{enter,exit}
Uninclude linux/freezer.h
m32r: trim masks
avr32: trim masks
tile: don't bother with SIGTRAP in setup_frame
microblaze: don't bother with SIGTRAP in setup_rt_frame()
mn10300: don't bother with SIGTRAP in setup_frame()
frv: no need to raise SIGTRAP in setup_frame()
x86: get rid of duplicate code in case of CONFIG_VM86
unicore32: remove pointless test
h8300: trim _TIF_WORK_MASK
parisc: decide whether to go to slow path (tracesys) based on thread flags
parisc: don't bother looping in do_signal()
parisc: fix double restarts
bury the rest of TIF_IRET
sanitize tsk_is_polling()
bury _TIF_RESTORE_SIGMASK
unicore32: unobfuscate _TIF_WORK_MASK
mips: NOTIFY_RESUME is not needed in TIF masks
mips: merge the identical "return from syscall" per-ABI code
...
Conflicts:
arch/arm/include/asm/thread_info.h
Diffstat (limited to 'arch/frv')
-rw-r--r-- | arch/frv/Kconfig | 1 | ||||
-rw-r--r-- | arch/frv/include/asm/processor.h | 9 | ||||
-rw-r--r-- | arch/frv/include/asm/ptrace.h | 1 | ||||
-rw-r--r-- | arch/frv/include/asm/thread_info.h | 3 | ||||
-rw-r--r-- | arch/frv/include/asm/unistd.h | 2 | ||||
-rw-r--r-- | arch/frv/kernel/Makefile | 4 | ||||
-rw-r--r-- | arch/frv/kernel/entry.S | 13 | ||||
-rw-r--r-- | arch/frv/kernel/frv_ksyms.c | 1 | ||||
-rw-r--r-- | arch/frv/kernel/kernel_execve.S | 33 | ||||
-rw-r--r-- | arch/frv/kernel/kernel_thread.S | 77 | ||||
-rw-r--r-- | arch/frv/kernel/process.c | 66 | ||||
-rw-r--r-- | arch/frv/kernel/signal.c | 9 |
12 files changed, 45 insertions, 174 deletions
diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig index 9d262645f66..b7412504f08 100644 --- a/arch/frv/Kconfig +++ b/arch/frv/Kconfig @@ -12,6 +12,7 @@ config FRV select ARCH_HAVE_NMI_SAFE_CMPXCHG select GENERIC_CPU_DEVICES select ARCH_WANT_IPC_PARSE_VERSION + select GENERIC_KERNEL_THREAD config ZONE_DMA bool diff --git a/arch/frv/include/asm/processor.h b/arch/frv/include/asm/processor.h index dccb9d16231..a34f309e580 100644 --- a/arch/frv/include/asm/processor.h +++ b/arch/frv/include/asm/processor.h @@ -92,14 +92,12 @@ extern struct task_struct *__kernel_current_task; /* * do necessary setup to start up a newly executed thread. - * - need to discard the frame stacked by init() invoking the execve syscall */ #define start_thread(_regs, _pc, _usp) \ do { \ - __frame = __kernel_frame0_ptr; \ - __frame->pc = (_pc); \ - __frame->psr &= ~PSR_S; \ - __frame->sp = (_usp); \ + _regs->pc = (_pc); \ + _regs->psr &= ~PSR_S; \ + _regs->sp = (_usp); \ } while(0) /* Free all resources held by a thread. */ @@ -107,7 +105,6 @@ static inline void release_thread(struct task_struct *dead_task) { } -extern asmlinkage int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); extern asmlinkage void save_user_regs(struct user_context *target); extern asmlinkage void *restore_user_regs(const struct user_context *target, ...); diff --git a/arch/frv/include/asm/ptrace.h b/arch/frv/include/asm/ptrace.h index ef6635ca4ec..bd534b2d025 100644 --- a/arch/frv/include/asm/ptrace.h +++ b/arch/frv/include/asm/ptrace.h @@ -76,6 +76,7 @@ register struct pt_regs *__frame asm("gr28"); #define user_mode(regs) (!((regs)->psr & PSR_S)) #define instruction_pointer(regs) ((regs)->pc) #define user_stack_pointer(regs) ((regs)->sp) +#define current_pt_regs() (__frame) extern unsigned long user_stack(const struct pt_regs *); #define profile_pc(regs) ((regs)->pc) diff --git a/arch/frv/include/asm/thread_info.h b/arch/frv/include/asm/thread_info.h index 0ff03a33c81..bebd7eadc77 100644 --- a/arch/frv/include/asm/thread_info.h +++ b/arch/frv/include/asm/thread_info.h @@ -94,7 +94,6 @@ register struct thread_info *__current_thread_info asm("gr15"); #define TIF_NEED_RESCHED 3 /* rescheduling necessary */ #define TIF_SINGLESTEP 4 /* restore singlestep on return to user mode */ #define TIF_RESTORE_SIGMASK 5 /* restore signal mask in do_signal() */ -#define TIF_POLLING_NRFLAG 6 /* true if poll_idle() is polling TIF_NEED_RESCHED */ #define TIF_MEMDIE 7 /* is terminating due to OOM killer */ #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) @@ -102,8 +101,6 @@ register struct thread_info *__current_thread_info asm("gr15"); #define _TIF_SIGPENDING (1 << TIF_SIGPENDING) #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) #define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP) -#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK) -#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) /* work to do on interrupt/exception return */ #define _TIF_WORK_MASK \ diff --git a/arch/frv/include/asm/unistd.h b/arch/frv/include/asm/unistd.h index 67f23a311db..b6b07e55e47 100644 --- a/arch/frv/include/asm/unistd.h +++ b/arch/frv/include/asm/unistd.h @@ -372,6 +372,8 @@ #define __ARCH_WANT_SYS_SIGPROCMASK #define __ARCH_WANT_SYS_RT_SIGACTION #define __ARCH_WANT_SYS_RT_SIGSUSPEND +#define __ARCH_WANT_SYS_EXECVE +#define __ARCH_WANT_KERNEL_EXECVE /* * "Conditional" syscalls diff --git a/arch/frv/kernel/Makefile b/arch/frv/kernel/Makefile index ad4087b6996..3cbb3294b9f 100644 --- a/arch/frv/kernel/Makefile +++ b/arch/frv/kernel/Makefile @@ -7,8 +7,8 @@ heads-$(CONFIG_MMU) := head-mmu-fr451.o extra-y:= head.o vmlinux.lds -obj-y := $(heads-y) entry.o entry-table.o break.o switch_to.o kernel_thread.o \ - kernel_execve.o process.o traps.o ptrace.o signal.o dma.o \ +obj-y := $(heads-y) entry.o entry-table.o break.o switch_to.o \ + process.o traps.o ptrace.o signal.o dma.o \ sys_frv.o time.o setup.o frv_ksyms.o \ debug-stub.o irq.o sleep.o uaccess.o diff --git a/arch/frv/kernel/entry.S b/arch/frv/kernel/entry.S index 7d5e000fd32..00273296031 100644 --- a/arch/frv/kernel/entry.S +++ b/arch/frv/kernel/entry.S @@ -863,6 +863,19 @@ ret_from_fork: setlos.p #0,gr8 bra __syscall_exit + .globl ret_from_kernel_thread +ret_from_kernel_thread: + lddi.p @(gr28,#REG_GR(8)),gr20 + call schedule_tail + or.p gr20,gr20,gr8 + calll @(gr21,gr0) + bra sys_exit + + .globl ret_from_kernel_execve +ret_from_kernel_execve: + ori gr28,0,sp + bra __syscall_exit + ################################################################################################### # # Return to user mode is not as complex as all this looks, diff --git a/arch/frv/kernel/frv_ksyms.c b/arch/frv/kernel/frv_ksyms.c index a89803b58b9..86c516d96dc 100644 --- a/arch/frv/kernel/frv_ksyms.c +++ b/arch/frv/kernel/frv_ksyms.c @@ -30,7 +30,6 @@ EXPORT_SYMBOL(ip_fast_csum); EXPORT_SYMBOL(local_irq_count); EXPORT_SYMBOL(local_bh_count); #endif -EXPORT_SYMBOL(kernel_thread); EXPORT_SYMBOL(__res_bus_clock_speed_HZ); EXPORT_SYMBOL(__page_offset); diff --git a/arch/frv/kernel/kernel_execve.S b/arch/frv/kernel/kernel_execve.S deleted file mode 100644 index 9b074a16a05..00000000000 --- a/arch/frv/kernel/kernel_execve.S +++ /dev/null @@ -1,33 +0,0 @@ -/* in-kernel program execution - * - * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved. - * Written by David Howells (dhowells@redhat.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - -#include <linux/linkage.h> -#include <asm/unistd.h> - -############################################################################### -# -# 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, char *const argv[], char *const envp[]) -# -# On entry: GR8/GR9/GR10: arguments to function -# On return: GR8: syscall return. -# -############################################################################### - .globl kernel_execve - .type kernel_execve,@function -kernel_execve: - setlos __NR_execve,gr7 - tira gr0,#0 - bralr - - .size kernel_execve,.-kernel_execve diff --git a/arch/frv/kernel/kernel_thread.S b/arch/frv/kernel/kernel_thread.S deleted file mode 100644 index f0e52943f92..00000000000 --- a/arch/frv/kernel/kernel_thread.S +++ /dev/null @@ -1,77 +0,0 @@ -/* kernel_thread.S: kernel thread creation - * - * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved. - * Written by David Howells (dhowells@redhat.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - -#include <linux/linkage.h> -#include <linux/kern_levels.h> -#include <asm/unistd.h> - -#define CLONE_VM 0x00000100 /* set if VM shared between processes */ - - .section .rodata -kernel_thread_emsg: - .asciz KERN_ERR "failed to create kernel thread: error=%d\n" - - .text - .balign 4 - -############################################################################### -# -# Create a kernel thread -# -# int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) -# -############################################################################### - .globl kernel_thread - .type kernel_thread,@function -kernel_thread: - or.p gr8,gr0,gr4 - or gr9,gr0,gr5 - - # start by forking the current process, but with shared VM - setlos.p #__NR_clone,gr7 ; syscall number - ori gr10,#CLONE_VM,gr8 ; first syscall arg [clone_flags] - sethi.p #0xe4e4,gr9 ; second syscall arg [newsp] - setlo #0xe4e4,gr9 - setlos.p #0,gr10 ; third syscall arg [parent_tidptr] - setlos #0,gr11 ; fourth syscall arg [child_tidptr] - tira gr0,#0 - setlos.p #4095,gr7 - andcc gr8,gr8,gr0,icc0 - addcc.p gr8,gr7,gr0,icc1 - bnelr icc0,#2 - bc icc1,#0,kernel_thread_error - - # now invoke the work function - or gr5,gr0,gr8 - calll @(gr4,gr0) - - # and finally exit the thread - setlos #__NR_exit,gr7 ; syscall number - tira gr0,#0 - -kernel_thread_error: - subi sp,#8,sp - movsg lr,gr4 - sti gr8,@(sp,#0) - sti.p gr4,@(sp,#4) - - or gr8,gr0,gr9 - sethi.p %hi(kernel_thread_emsg),gr8 - setlo %lo(kernel_thread_emsg),gr8 - - call printk - - ldi @(sp,#4),gr4 - ldi @(sp,#0),gr8 - subi sp,#8,sp - jmpl @(gr4,gr0) - - .size kernel_thread,.-kernel_thread diff --git a/arch/frv/kernel/process.c b/arch/frv/kernel/process.c index 2eb7fa5bf9d..655d90d20bb 100644 --- a/arch/frv/kernel/process.c +++ b/arch/frv/kernel/process.c @@ -38,6 +38,7 @@ #include "local.h" asmlinkage void ret_from_fork(void); +asmlinkage void ret_from_kernel_thread(void); #include <asm/pgalloc.h> @@ -172,32 +173,13 @@ asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp, * set up the kernel stack and exception frames for a new process */ int copy_thread(unsigned long clone_flags, - unsigned long usp, unsigned long topstk, + unsigned long usp, unsigned long arg, struct task_struct *p, struct pt_regs *regs) { - struct pt_regs *childregs0, *childregs, *regs0; + struct pt_regs *childregs; - regs0 = __kernel_frame0_ptr; - childregs0 = (struct pt_regs *) + childregs = (struct pt_regs *) (task_stack_page(p) + THREAD_SIZE - FRV_FRAME0_SIZE); - childregs = childregs0; - - /* set up the userspace frame (the only place that the USP is stored) */ - *childregs0 = *regs0; - - childregs0->gr8 = 0; - childregs0->sp = usp; - childregs0->next_frame = NULL; - - /* set up the return kernel frame if called from kernel_thread() */ - if (regs != regs0) { - childregs--; - *childregs = *regs; - childregs->sp = (unsigned long) childregs0; - childregs->next_frame = childregs0; - childregs->gr15 = (unsigned long) task_thread_info(p); - childregs->gr29 = (unsigned long) p; - } p->set_child_tid = p->clear_child_tid = NULL; @@ -206,8 +188,25 @@ int copy_thread(unsigned long clone_flags, p->thread.sp = (unsigned long) childregs; p->thread.fp = 0; p->thread.lr = 0; - p->thread.pc = (unsigned long) ret_from_fork; - p->thread.frame0 = childregs0; + p->thread.frame0 = childregs; + + if (unlikely(!regs)) { + memset(childregs, 0, sizeof(struct pt_regs)); + childregs->gr9 = usp; /* function */ + childregs->gr8 = arg; + chilregs->psr = PSR_S; + p->thread.pc = (unsigned long) ret_from_kernel_thread; + save_user_regs(p->thread.user); + return 0; + } + + /* set up the userspace frame (the only place that the USP is stored) */ + *childregs = *regs; + + childregs->sp = usp; + childregs->next_frame = NULL; + + p->thread.pc = (unsigned long) ret_from_fork; /* the new TLS pointer is passed in as arg #5 to sys_clone() */ if (clone_flags & CLONE_SETTLS) @@ -218,25 +217,6 @@ int copy_thread(unsigned long clone_flags, return 0; } /* end copy_thread() */ -/* - * sys_execve() executes a new program. - */ -asmlinkage int sys_execve(const char __user *name, - const char __user *const __user *argv, - const char __user *const __user *envp) -{ - int error; - char * filename; - - filename = getname(name); - error = PTR_ERR(filename); - if (IS_ERR(filename)) - return error; - error = do_execve(filename, argv, envp, __frame); - putname(filename); - return error; -} - unsigned long get_wchan(struct task_struct *p) { struct pt_regs *regs0; diff --git a/arch/frv/kernel/signal.c b/arch/frv/kernel/signal.c index 864c2f0d497..535810a3217 100644 --- a/arch/frv/kernel/signal.c +++ b/arch/frv/kernel/signal.c @@ -20,7 +20,6 @@ #include <linux/ptrace.h> #include <linux/unistd.h> #include <linux/personality.h> -#include <linux/freezer.h> #include <linux/tracehook.h> #include <asm/ucontext.h> #include <asm/uaccess.h> @@ -298,10 +297,6 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set) __frame->lr = (unsigned long) &frame->retcode; __frame->gr8 = sig; - /* the tracer may want to single-step inside the handler */ - if (test_thread_flag(TIF_SINGLESTEP)) - ptrace_notify(SIGTRAP); - #if DEBUG_SIG printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n", sig, current->comm, current->pid, frame, __frame->pc, @@ -400,10 +395,6 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, __frame->gr8 = sig; __frame->gr9 = (unsigned long) &frame->info; - /* the tracer may want to single-step inside the handler */ - if (test_thread_flag(TIF_SINGLESTEP)) - ptrace_notify(SIGTRAP); - #if DEBUG_SIG printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n", sig, current->comm, current->pid, frame, __frame->pc, |