aboutsummaryrefslogtreecommitdiffstats
path: root/arch/frv
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-10-11 21:49:08 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-11 21:49:08 -0400
commit8213a2f3eeafdecf06dd718cb4130372263f6067 (patch)
tree0d02e3201dac64d1429f8552ee1163d4a1ef1646 /arch/frv
parent40924754f2cabd5d9af4bcd4dcecc362b5e0baa1 (diff)
parent12f79be93d94698778ff2b3f921073fc5f6780d6 (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/Kconfig1
-rw-r--r--arch/frv/include/asm/processor.h9
-rw-r--r--arch/frv/include/asm/ptrace.h1
-rw-r--r--arch/frv/include/asm/thread_info.h3
-rw-r--r--arch/frv/include/asm/unistd.h2
-rw-r--r--arch/frv/kernel/Makefile4
-rw-r--r--arch/frv/kernel/entry.S13
-rw-r--r--arch/frv/kernel/frv_ksyms.c1
-rw-r--r--arch/frv/kernel/kernel_execve.S33
-rw-r--r--arch/frv/kernel/kernel_thread.S77
-rw-r--r--arch/frv/kernel/process.c66
-rw-r--r--arch/frv/kernel/signal.c9
12 files changed, 45 insertions, 174 deletions
diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig
index 9d262645f667..b7412504f08a 100644
--- a/arch/frv/Kconfig
+++ b/arch/frv/Kconfig
@@ -12,6 +12,7 @@ config FRV
12 select ARCH_HAVE_NMI_SAFE_CMPXCHG 12 select ARCH_HAVE_NMI_SAFE_CMPXCHG
13 select GENERIC_CPU_DEVICES 13 select GENERIC_CPU_DEVICES
14 select ARCH_WANT_IPC_PARSE_VERSION 14 select ARCH_WANT_IPC_PARSE_VERSION
15 select GENERIC_KERNEL_THREAD
15 16
16config ZONE_DMA 17config ZONE_DMA
17 bool 18 bool
diff --git a/arch/frv/include/asm/processor.h b/arch/frv/include/asm/processor.h
index dccb9d162318..a34f309e5801 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;
92 92
93/* 93/*
94 * do necessary setup to start up a newly executed thread. 94 * do necessary setup to start up a newly executed thread.
95 * - need to discard the frame stacked by init() invoking the execve syscall
96 */ 95 */
97#define start_thread(_regs, _pc, _usp) \ 96#define start_thread(_regs, _pc, _usp) \
98do { \ 97do { \
99 __frame = __kernel_frame0_ptr; \ 98 _regs->pc = (_pc); \
100 __frame->pc = (_pc); \ 99 _regs->psr &= ~PSR_S; \
101 __frame->psr &= ~PSR_S; \ 100 _regs->sp = (_usp); \
102 __frame->sp = (_usp); \
103} while(0) 101} while(0)
104 102
105/* Free all resources held by a thread. */ 103/* Free all resources held by a thread. */
@@ -107,7 +105,6 @@ static inline void release_thread(struct task_struct *dead_task)
107{ 105{
108} 106}
109 107
110extern asmlinkage int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
111extern asmlinkage void save_user_regs(struct user_context *target); 108extern asmlinkage void save_user_regs(struct user_context *target);
112extern asmlinkage void *restore_user_regs(const struct user_context *target, ...); 109extern asmlinkage void *restore_user_regs(const struct user_context *target, ...);
113 110
diff --git a/arch/frv/include/asm/ptrace.h b/arch/frv/include/asm/ptrace.h
index ef6635ca4ecb..bd534b2d0258 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");
76#define user_mode(regs) (!((regs)->psr & PSR_S)) 76#define user_mode(regs) (!((regs)->psr & PSR_S))
77#define instruction_pointer(regs) ((regs)->pc) 77#define instruction_pointer(regs) ((regs)->pc)
78#define user_stack_pointer(regs) ((regs)->sp) 78#define user_stack_pointer(regs) ((regs)->sp)
79#define current_pt_regs() (__frame)
79 80
80extern unsigned long user_stack(const struct pt_regs *); 81extern unsigned long user_stack(const struct pt_regs *);
81#define profile_pc(regs) ((regs)->pc) 82#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 0ff03a33c81e..bebd7eadc772 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");
94#define TIF_NEED_RESCHED 3 /* rescheduling necessary */ 94#define TIF_NEED_RESCHED 3 /* rescheduling necessary */
95#define TIF_SINGLESTEP 4 /* restore singlestep on return to user mode */ 95#define TIF_SINGLESTEP 4 /* restore singlestep on return to user mode */
96#define TIF_RESTORE_SIGMASK 5 /* restore signal mask in do_signal() */ 96#define TIF_RESTORE_SIGMASK 5 /* restore signal mask in do_signal() */
97#define TIF_POLLING_NRFLAG 6 /* true if poll_idle() is polling TIF_NEED_RESCHED */
98#define TIF_MEMDIE 7 /* is terminating due to OOM killer */ 97#define TIF_MEMDIE 7 /* is terminating due to OOM killer */
99 98
100#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) 99#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
@@ -102,8 +101,6 @@ register struct thread_info *__current_thread_info asm("gr15");
102#define _TIF_SIGPENDING (1 << TIF_SIGPENDING) 101#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
103#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) 102#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
104#define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP) 103#define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP)
105#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK)
106#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
107 104
108/* work to do on interrupt/exception return */ 105/* work to do on interrupt/exception return */
109#define _TIF_WORK_MASK \ 106#define _TIF_WORK_MASK \
diff --git a/arch/frv/include/asm/unistd.h b/arch/frv/include/asm/unistd.h
index 67f23a311db6..b6b07e55e473 100644
--- a/arch/frv/include/asm/unistd.h
+++ b/arch/frv/include/asm/unistd.h
@@ -372,6 +372,8 @@
372#define __ARCH_WANT_SYS_SIGPROCMASK 372#define __ARCH_WANT_SYS_SIGPROCMASK
373#define __ARCH_WANT_SYS_RT_SIGACTION 373#define __ARCH_WANT_SYS_RT_SIGACTION
374#define __ARCH_WANT_SYS_RT_SIGSUSPEND 374#define __ARCH_WANT_SYS_RT_SIGSUSPEND
375#define __ARCH_WANT_SYS_EXECVE
376#define __ARCH_WANT_KERNEL_EXECVE
375 377
376/* 378/*
377 * "Conditional" syscalls 379 * "Conditional" syscalls
diff --git a/arch/frv/kernel/Makefile b/arch/frv/kernel/Makefile
index ad4087b69968..3cbb3294b9f9 100644
--- a/arch/frv/kernel/Makefile
+++ b/arch/frv/kernel/Makefile
@@ -7,8 +7,8 @@ heads-$(CONFIG_MMU) := head-mmu-fr451.o
7 7
8extra-y:= head.o vmlinux.lds 8extra-y:= head.o vmlinux.lds
9 9
10obj-y := $(heads-y) entry.o entry-table.o break.o switch_to.o kernel_thread.o \ 10obj-y := $(heads-y) entry.o entry-table.o break.o switch_to.o \
11 kernel_execve.o process.o traps.o ptrace.o signal.o dma.o \ 11 process.o traps.o ptrace.o signal.o dma.o \
12 sys_frv.o time.o setup.o frv_ksyms.o \ 12 sys_frv.o time.o setup.o frv_ksyms.o \
13 debug-stub.o irq.o sleep.o uaccess.o 13 debug-stub.o irq.o sleep.o uaccess.o
14 14
diff --git a/arch/frv/kernel/entry.S b/arch/frv/kernel/entry.S
index 7d5e000fd32e..002732960315 100644
--- a/arch/frv/kernel/entry.S
+++ b/arch/frv/kernel/entry.S
@@ -863,6 +863,19 @@ ret_from_fork:
863 setlos.p #0,gr8 863 setlos.p #0,gr8
864 bra __syscall_exit 864 bra __syscall_exit
865 865
866 .globl ret_from_kernel_thread
867ret_from_kernel_thread:
868 lddi.p @(gr28,#REG_GR(8)),gr20
869 call schedule_tail
870 or.p gr20,gr20,gr8
871 calll @(gr21,gr0)
872 bra sys_exit
873
874 .globl ret_from_kernel_execve
875ret_from_kernel_execve:
876 ori gr28,0,sp
877 bra __syscall_exit
878
866################################################################################################### 879###################################################################################################
867# 880#
868# Return to user mode is not as complex as all this looks, 881# 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 a89803b58b9a..86c516d96dcd 100644
--- a/arch/frv/kernel/frv_ksyms.c
+++ b/arch/frv/kernel/frv_ksyms.c
@@ -30,7 +30,6 @@ EXPORT_SYMBOL(ip_fast_csum);
30EXPORT_SYMBOL(local_irq_count); 30EXPORT_SYMBOL(local_irq_count);
31EXPORT_SYMBOL(local_bh_count); 31EXPORT_SYMBOL(local_bh_count);
32#endif 32#endif
33EXPORT_SYMBOL(kernel_thread);
34 33
35EXPORT_SYMBOL(__res_bus_clock_speed_HZ); 34EXPORT_SYMBOL(__res_bus_clock_speed_HZ);
36EXPORT_SYMBOL(__page_offset); 35EXPORT_SYMBOL(__page_offset);
diff --git a/arch/frv/kernel/kernel_execve.S b/arch/frv/kernel/kernel_execve.S
deleted file mode 100644
index 9b074a16a052..000000000000
--- a/arch/frv/kernel/kernel_execve.S
+++ /dev/null
@@ -1,33 +0,0 @@
1/* in-kernel program execution
2 *
3 * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#include <linux/linkage.h>
13#include <asm/unistd.h>
14
15###############################################################################
16#
17# Do a system call from kernel instead of calling sys_execve so we end up with
18# proper pt_regs.
19#
20# int kernel_execve(const char *filename, char *const argv[], char *const envp[])
21#
22# On entry: GR8/GR9/GR10: arguments to function
23# On return: GR8: syscall return.
24#
25###############################################################################
26 .globl kernel_execve
27 .type kernel_execve,@function
28kernel_execve:
29 setlos __NR_execve,gr7
30 tira gr0,#0
31 bralr
32
33 .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 f0e52943f923..000000000000
--- a/arch/frv/kernel/kernel_thread.S
+++ /dev/null
@@ -1,77 +0,0 @@
1/* kernel_thread.S: kernel thread creation
2 *
3 * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#include <linux/linkage.h>
13#include <linux/kern_levels.h>
14#include <asm/unistd.h>
15
16#define CLONE_VM 0x00000100 /* set if VM shared between processes */
17
18 .section .rodata
19kernel_thread_emsg:
20 .asciz KERN_ERR "failed to create kernel thread: error=%d\n"
21
22 .text
23 .balign 4
24
25###############################################################################
26#
27# Create a kernel thread
28#
29# int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
30#
31###############################################################################
32 .globl kernel_thread
33 .type kernel_thread,@function
34kernel_thread:
35 or.p gr8,gr0,gr4
36 or gr9,gr0,gr5
37
38 # start by forking the current process, but with shared VM
39 setlos.p #__NR_clone,gr7 ; syscall number
40 ori gr10,#CLONE_VM,gr8 ; first syscall arg [clone_flags]
41 sethi.p #0xe4e4,gr9 ; second syscall arg [newsp]
42 setlo #0xe4e4,gr9
43 setlos.p #0,gr10 ; third syscall arg [parent_tidptr]
44 setlos #0,gr11 ; fourth syscall arg [child_tidptr]
45 tira gr0,#0
46 setlos.p #4095,gr7
47 andcc gr8,gr8,gr0,icc0
48 addcc.p gr8,gr7,gr0,icc1
49 bnelr icc0,#2
50 bc icc1,#0,kernel_thread_error
51
52 # now invoke the work function
53 or gr5,gr0,gr8
54 calll @(gr4,gr0)
55
56 # and finally exit the thread
57 setlos #__NR_exit,gr7 ; syscall number
58 tira gr0,#0
59
60kernel_thread_error:
61 subi sp,#8,sp
62 movsg lr,gr4
63 sti gr8,@(sp,#0)
64 sti.p gr4,@(sp,#4)
65
66 or gr8,gr0,gr9
67 sethi.p %hi(kernel_thread_emsg),gr8
68 setlo %lo(kernel_thread_emsg),gr8
69
70 call printk
71
72 ldi @(sp,#4),gr4
73 ldi @(sp,#0),gr8
74 subi sp,#8,sp
75 jmpl @(gr4,gr0)
76
77 .size kernel_thread,.-kernel_thread
diff --git a/arch/frv/kernel/process.c b/arch/frv/kernel/process.c
index 2eb7fa5bf9d8..655d90d20bb0 100644
--- a/arch/frv/kernel/process.c
+++ b/arch/frv/kernel/process.c
@@ -38,6 +38,7 @@
38#include "local.h" 38#include "local.h"
39 39
40asmlinkage void ret_from_fork(void); 40asmlinkage void ret_from_fork(void);
41asmlinkage void ret_from_kernel_thread(void);
41 42
42#include <asm/pgalloc.h> 43#include <asm/pgalloc.h>
43 44
@@ -172,32 +173,13 @@ asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
172 * set up the kernel stack and exception frames for a new process 173 * set up the kernel stack and exception frames for a new process
173 */ 174 */
174int copy_thread(unsigned long clone_flags, 175int copy_thread(unsigned long clone_flags,
175 unsigned long usp, unsigned long topstk, 176 unsigned long usp, unsigned long arg,
176 struct task_struct *p, struct pt_regs *regs) 177 struct task_struct *p, struct pt_regs *regs)
177{ 178{
178 struct pt_regs *childregs0, *childregs, *regs0; 179 struct pt_regs *childregs;
179 180
180 regs0 = __kernel_frame0_ptr; 181 childregs = (struct pt_regs *)
181 childregs0 = (struct pt_regs *)
182 (task_stack_page(p) + THREAD_SIZE - FRV_FRAME0_SIZE); 182 (task_stack_page(p) + THREAD_SIZE - FRV_FRAME0_SIZE);
183 childregs = childregs0;
184
185 /* set up the userspace frame (the only place that the USP is stored) */
186 *childregs0 = *regs0;
187
188 childregs0->gr8 = 0;
189 childregs0->sp = usp;
190 childregs0->next_frame = NULL;
191
192 /* set up the return kernel frame if called from kernel_thread() */
193 if (regs != regs0) {
194 childregs--;
195 *childregs = *regs;
196 childregs->sp = (unsigned long) childregs0;
197 childregs->next_frame = childregs0;
198 childregs->gr15 = (unsigned long) task_thread_info(p);
199 childregs->gr29 = (unsigned long) p;
200 }
201 183
202 p->set_child_tid = p->clear_child_tid = NULL; 184 p->set_child_tid = p->clear_child_tid = NULL;
203 185
@@ -206,8 +188,25 @@ int copy_thread(unsigned long clone_flags,
206 p->thread.sp = (unsigned long) childregs; 188 p->thread.sp = (unsigned long) childregs;
207 p->thread.fp = 0; 189 p->thread.fp = 0;
208 p->thread.lr = 0; 190 p->thread.lr = 0;
209 p->thread.pc = (unsigned long) ret_from_fork; 191 p->thread.frame0 = childregs;
210 p->thread.frame0 = childregs0; 192
193 if (unlikely(!regs)) {
194 memset(childregs, 0, sizeof(struct pt_regs));
195 childregs->gr9 = usp; /* function */
196 childregs->gr8 = arg;
197 chilregs->psr = PSR_S;
198 p->thread.pc = (unsigned long) ret_from_kernel_thread;
199 save_user_regs(p->thread.user);
200 return 0;
201 }
202
203 /* set up the userspace frame (the only place that the USP is stored) */
204 *childregs = *regs;
205
206 childregs->sp = usp;
207 childregs->next_frame = NULL;
208
209 p->thread.pc = (unsigned long) ret_from_fork;
211 210
212 /* the new TLS pointer is passed in as arg #5 to sys_clone() */ 211 /* the new TLS pointer is passed in as arg #5 to sys_clone() */
213 if (clone_flags & CLONE_SETTLS) 212 if (clone_flags & CLONE_SETTLS)
@@ -218,25 +217,6 @@ int copy_thread(unsigned long clone_flags,
218 return 0; 217 return 0;
219} /* end copy_thread() */ 218} /* end copy_thread() */
220 219
221/*
222 * sys_execve() executes a new program.
223 */
224asmlinkage int sys_execve(const char __user *name,
225 const char __user *const __user *argv,
226 const char __user *const __user *envp)
227{
228 int error;
229 char * filename;
230
231 filename = getname(name);
232 error = PTR_ERR(filename);
233 if (IS_ERR(filename))
234 return error;
235 error = do_execve(filename, argv, envp, __frame);
236 putname(filename);
237 return error;
238}
239
240unsigned long get_wchan(struct task_struct *p) 220unsigned long get_wchan(struct task_struct *p)
241{ 221{
242 struct pt_regs *regs0; 222 struct pt_regs *regs0;
diff --git a/arch/frv/kernel/signal.c b/arch/frv/kernel/signal.c
index 864c2f0d497b..535810a3217a 100644
--- a/arch/frv/kernel/signal.c
+++ b/arch/frv/kernel/signal.c
@@ -20,7 +20,6 @@
20#include <linux/ptrace.h> 20#include <linux/ptrace.h>
21#include <linux/unistd.h> 21#include <linux/unistd.h>
22#include <linux/personality.h> 22#include <linux/personality.h>
23#include <linux/freezer.h>
24#include <linux/tracehook.h> 23#include <linux/tracehook.h>
25#include <asm/ucontext.h> 24#include <asm/ucontext.h>
26#include <asm/uaccess.h> 25#include <asm/uaccess.h>
@@ -298,10 +297,6 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set)
298 __frame->lr = (unsigned long) &frame->retcode; 297 __frame->lr = (unsigned long) &frame->retcode;
299 __frame->gr8 = sig; 298 __frame->gr8 = sig;
300 299
301 /* the tracer may want to single-step inside the handler */
302 if (test_thread_flag(TIF_SINGLESTEP))
303 ptrace_notify(SIGTRAP);
304
305#if DEBUG_SIG 300#if DEBUG_SIG
306 printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n", 301 printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n",
307 sig, current->comm, current->pid, frame, __frame->pc, 302 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,
400 __frame->gr8 = sig; 395 __frame->gr8 = sig;
401 __frame->gr9 = (unsigned long) &frame->info; 396 __frame->gr9 = (unsigned long) &frame->info;
402 397
403 /* the tracer may want to single-step inside the handler */
404 if (test_thread_flag(TIF_SINGLESTEP))
405 ptrace_notify(SIGTRAP);
406
407#if DEBUG_SIG 398#if DEBUG_SIG
408 printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n", 399 printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n",
409 sig, current->comm, current->pid, frame, __frame->pc, 400 sig, current->comm, current->pid, frame, __frame->pc,