aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mn10300/kernel
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/mn10300/kernel
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/mn10300/kernel')
-rw-r--r--arch/mn10300/kernel/Makefile4
-rw-r--r--arch/mn10300/kernel/entry.S18
-rw-r--r--arch/mn10300/kernel/internal.h6
-rw-r--r--arch/mn10300/kernel/kernel_execve.S37
-rw-r--r--arch/mn10300/kernel/kthread.S31
-rw-r--r--arch/mn10300/kernel/process.c91
-rw-r--r--arch/mn10300/kernel/signal.c13
7 files changed, 44 insertions, 156 deletions
diff --git a/arch/mn10300/kernel/Makefile b/arch/mn10300/kernel/Makefile
index d06749173d63..561029f7fa44 100644
--- a/arch/mn10300/kernel/Makefile
+++ b/arch/mn10300/kernel/Makefile
@@ -7,8 +7,8 @@ fpu-obj-y := fpu-nofpu.o fpu-nofpu-low.o
7fpu-obj-$(CONFIG_FPU) := fpu.o fpu-low.o 7fpu-obj-$(CONFIG_FPU) := fpu.o fpu-low.o
8 8
9obj-y := process.o signal.o entry.o traps.o irq.o \ 9obj-y := process.o signal.o entry.o traps.o irq.o \
10 ptrace.o setup.o time.o sys_mn10300.o io.o kthread.o \ 10 ptrace.o setup.o time.o sys_mn10300.o io.o \
11 switch_to.o mn10300_ksyms.o kernel_execve.o $(fpu-obj-y) \ 11 switch_to.o mn10300_ksyms.o $(fpu-obj-y) \
12 csrc-mn10300.o cevt-mn10300.o 12 csrc-mn10300.o cevt-mn10300.o
13 13
14obj-$(CONFIG_SMP) += smp.o smp-low.o 14obj-$(CONFIG_SMP) += smp.o smp-low.o
diff --git a/arch/mn10300/kernel/entry.S b/arch/mn10300/kernel/entry.S
index 8e11f9f48999..0c631d34c8d7 100644
--- a/arch/mn10300/kernel/entry.S
+++ b/arch/mn10300/kernel/entry.S
@@ -55,6 +55,20 @@ ENTRY(ret_from_fork)
55 mov d0,(REG_D0,fp) 55 mov d0,(REG_D0,fp)
56 jmp syscall_exit 56 jmp syscall_exit
57 57
58ENTRY(ret_from_kernel_thread)
59 call schedule_tail[],0
60 mov (REG_D0,fp),d0
61 mov (REG_A0,fp),a0
62 calls (a0)
63 jmp sys_exit
64
65ENTRY(ret_from_kernel_execve)
66 add -12,d0 /* pt_regs -> frame */
67 mov d0,sp
68 GET_THREAD_INFO a2
69 clr d0
70 jmp syscall_exit
71
58############################################################################### 72###############################################################################
59# 73#
60# system call handler 74# system call handler
@@ -94,6 +108,10 @@ restore_all:
94############################################################################### 108###############################################################################
95 ALIGN 109 ALIGN
96syscall_exit_work: 110syscall_exit_work:
111 mov (REG_EPSW,fp),d0
112 and EPSW_nSL,d0
113 beq resume_kernel # returning to supervisor mode
114
97 btst _TIF_SYSCALL_TRACE,d2 115 btst _TIF_SYSCALL_TRACE,d2
98 beq work_pending 116 beq work_pending
99 LOCAL_IRQ_ENABLE # could let syscall_trace_exit() call 117 LOCAL_IRQ_ENABLE # could let syscall_trace_exit() call
diff --git a/arch/mn10300/kernel/internal.h b/arch/mn10300/kernel/internal.h
index 2df440105a80..561785581f6c 100644
--- a/arch/mn10300/kernel/internal.h
+++ b/arch/mn10300/kernel/internal.h
@@ -15,14 +15,10 @@ struct clocksource;
15struct clock_event_device; 15struct clock_event_device;
16 16
17/* 17/*
18 * kthread.S
19 */
20extern int kernel_thread_helper(int);
21
22/*
23 * entry.S 18 * entry.S
24 */ 19 */
25extern void ret_from_fork(struct task_struct *) __attribute__((noreturn)); 20extern void ret_from_fork(struct task_struct *) __attribute__((noreturn));
21extern void ret_from_kernel_thread(struct task_struct *) __attribute__((noreturn));
26 22
27/* 23/*
28 * smp-low.S 24 * smp-low.S
diff --git a/arch/mn10300/kernel/kernel_execve.S b/arch/mn10300/kernel/kernel_execve.S
deleted file mode 100644
index 86039f105268..000000000000
--- a/arch/mn10300/kernel/kernel_execve.S
+++ /dev/null
@@ -1,37 +0,0 @@
1/* MN10300 In-kernel program execution
2 *
3 * Copyright (C) 2007 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 Licence
8 * as published by the Free Software Foundation; either version
9 * 2 of the Licence, or (at your option) any later version.
10 */
11#include <linux/linkage.h>
12#include <asm/unistd.h>
13
14###############################################################################
15#
16# Do a system call from kernel instead of calling sys_execve so we end up with
17# proper pt_regs.
18#
19# int kernel_execve(const char *filename, char *const argv[],
20# char *const envp[])
21#
22# On entry: D0/D1/8(SP): arguments to function
23# On return: D0: syscall return.
24#
25###############################################################################
26 .globl kernel_execve
27 .type kernel_execve,@function
28kernel_execve:
29 mov a3,a1
30 mov d0,a0
31 mov (12,sp),a3
32 mov +__NR_execve,d0
33 syscall 0
34 mov a1,a3
35 rets
36
37 .size kernel_execve,.-kernel_execve
diff --git a/arch/mn10300/kernel/kthread.S b/arch/mn10300/kernel/kthread.S
deleted file mode 100644
index b5ae467ac5ec..000000000000
--- a/arch/mn10300/kernel/kthread.S
+++ /dev/null
@@ -1,31 +0,0 @@
1/* MN10300 Kernel thread trampoline function
2 *
3 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
4 * Written by Mark Salter (msalter@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 Licence
8 * as published by the Free Software Foundation; either version
9 * 2 of the Licence, or (at your option) any later version.
10 */
11 .text
12
13###############################################################################
14#
15# kernel_thread_helper - trampoline for kernel_thread()
16#
17# On entry:
18# A2 = address of function to call
19# D2 = function argument
20#
21###############################################################################
22 .globl kernel_thread_helper
23 .type kernel_thread_helper,@function
24kernel_thread_helper:
25 mov do_exit,d1
26 mov d1,(sp)
27 mov d1,mdr
28 mov d2,d0
29 jmp (a2)
30
31 .size kernel_thread_helper,.-kernel_thread_helper
diff --git a/arch/mn10300/kernel/process.c b/arch/mn10300/kernel/process.c
index e9cceba193b6..d0c671b6d9ff 100644
--- a/arch/mn10300/kernel/process.c
+++ b/arch/mn10300/kernel/process.c
@@ -165,27 +165,6 @@ void show_regs(struct pt_regs *regs)
165} 165}
166 166
167/* 167/*
168 * create a kernel thread
169 */
170int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
171{
172 struct pt_regs regs;
173
174 memset(&regs, 0, sizeof(regs));
175
176 regs.a2 = (unsigned long) fn;
177 regs.d2 = (unsigned long) arg;
178 regs.pc = (unsigned long) kernel_thread_helper;
179 local_save_flags(regs.epsw);
180 regs.epsw |= EPSW_IE | EPSW_IM_7;
181
182 /* Ok, create the new process.. */
183 return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0,
184 NULL, NULL);
185}
186EXPORT_SYMBOL(kernel_thread);
187
188/*
189 * free current thread data structures etc.. 168 * free current thread data structures etc..
190 */ 169 */
191void exit_thread(void) 170void exit_thread(void)
@@ -230,50 +209,42 @@ int copy_thread(unsigned long clone_flags,
230 struct task_struct *p, struct pt_regs *kregs) 209 struct task_struct *p, struct pt_regs *kregs)
231{ 210{
232 struct thread_info *ti = task_thread_info(p); 211 struct thread_info *ti = task_thread_info(p);
233 struct pt_regs *c_uregs, *c_kregs, *uregs; 212 struct pt_regs *c_regs;
234 unsigned long c_ksp; 213 unsigned long c_ksp;
235 214
236 uregs = current->thread.uregs;
237
238 c_ksp = (unsigned long) task_stack_page(p) + THREAD_SIZE; 215 c_ksp = (unsigned long) task_stack_page(p) + THREAD_SIZE;
239 216
240 /* allocate the userspace exception frame and set it up */ 217 /* allocate the userspace exception frame and set it up */
241 c_ksp -= sizeof(struct pt_regs); 218 c_ksp -= sizeof(struct pt_regs);
242 c_uregs = (struct pt_regs *) c_ksp; 219 c_regs = (struct pt_regs *) c_ksp;
220 c_ksp -= 12; /* allocate function call ABI slack */
243 221
244 p->thread.uregs = c_uregs; 222 /* set up things up so the scheduler can start the new task */
245 *c_uregs = *uregs; 223 p->thread.uregs = c_regs;
246 c_uregs->sp = c_usp; 224 ti->frame = c_regs;
247 c_uregs->epsw &= ~EPSW_FE; /* my FPU */ 225 p->thread.a3 = (unsigned long) c_regs;
226 p->thread.sp = c_ksp;
227 p->thread.wchan = p->thread.pc;
228 p->thread.usp = c_usp;
248 229
249 c_ksp -= 12; /* allocate function call ABI slack */ 230 if (unlikely(!kregs)) {
231 memset(c_regs, 0, sizeof(struct pt_regs));
232 c_regs->a0 = c_usp; /* function */
233 c_regs->d0 = ustk_size; /* argument */
234 local_save_flags(c_regs->epsw);
235 c_regs->epsw |= EPSW_IE | EPSW_IM_7;
236 p->thread.pc = (unsigned long) ret_from_kernel_thread;
237 return 0;
238 }
239 *c_regs = *kregs;
240 c_regs->sp = c_usp;
241 c_regs->epsw &= ~EPSW_FE; /* my FPU */
250 242
251 /* the new TLS pointer is passed in as arg #5 to sys_clone() */ 243 /* the new TLS pointer is passed in as arg #5 to sys_clone() */
252 if (clone_flags & CLONE_SETTLS) 244 if (clone_flags & CLONE_SETTLS)
253 c_uregs->e2 = current_frame()->d3; 245 c_regs->e2 = current_frame()->d3;
254
255 /* set up the return kernel frame if called from kernel_thread() */
256 c_kregs = c_uregs;
257 if (kregs != uregs) {
258 c_ksp -= sizeof(struct pt_regs);
259 c_kregs = (struct pt_regs *) c_ksp;
260 *c_kregs = *kregs;
261 c_kregs->sp = c_usp;
262 c_kregs->next = c_uregs;
263#ifdef CONFIG_MN10300_CURRENT_IN_E2
264 c_kregs->e2 = (unsigned long) p; /* current */
265#endif
266
267 c_ksp -= 12; /* allocate function call ABI slack */
268 }
269 246
270 /* set up things up so the scheduler can start the new task */
271 ti->frame = c_kregs;
272 p->thread.a3 = (unsigned long) c_kregs;
273 p->thread.sp = c_ksp;
274 p->thread.pc = (unsigned long) ret_from_fork; 247 p->thread.pc = (unsigned long) ret_from_fork;
275 p->thread.wchan = (unsigned long) ret_from_fork;
276 p->thread.usp = c_usp;
277 248
278 return 0; 249 return 0;
279} 250}
@@ -302,22 +273,6 @@ asmlinkage long sys_vfork(void)
302 current_frame(), 0, NULL, NULL); 273 current_frame(), 0, NULL, NULL);
303} 274}
304 275
305asmlinkage long sys_execve(const char __user *name,
306 const char __user *const __user *argv,
307 const char __user *const __user *envp)
308{
309 char *filename;
310 int error;
311
312 filename = getname(name);
313 error = PTR_ERR(filename);
314 if (IS_ERR(filename))
315 return error;
316 error = do_execve(filename, argv, envp, current_frame());
317 putname(filename);
318 return error;
319}
320
321unsigned long get_wchan(struct task_struct *p) 276unsigned long get_wchan(struct task_struct *p)
322{ 277{
323 return p->thread.wchan; 278 return p->thread.wchan;
diff --git a/arch/mn10300/kernel/signal.c b/arch/mn10300/kernel/signal.c
index 4d584ae29ae1..f570b3085ef9 100644
--- a/arch/mn10300/kernel/signal.c
+++ b/arch/mn10300/kernel/signal.c
@@ -317,10 +317,6 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
317 regs->d0 = sig; 317 regs->d0 = sig;
318 regs->d1 = (unsigned long) &frame->sc; 318 regs->d1 = (unsigned long) &frame->sc;
319 319
320 /* the tracer may want to single-step inside the handler */
321 if (test_thread_flag(TIF_SINGLESTEP))
322 ptrace_notify(SIGTRAP);
323
324#if DEBUG_SIG 320#if DEBUG_SIG
325 printk(KERN_DEBUG "SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n", 321 printk(KERN_DEBUG "SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n",
326 sig, current->comm, current->pid, frame, regs->pc, 322 sig, current->comm, current->pid, frame, regs->pc,
@@ -398,10 +394,6 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
398 regs->d0 = sig; 394 regs->d0 = sig;
399 regs->d1 = (long) &frame->info; 395 regs->d1 = (long) &frame->info;
400 396
401 /* the tracer may want to single-step inside the handler */
402 if (test_thread_flag(TIF_SINGLESTEP))
403 ptrace_notify(SIGTRAP);
404
405#if DEBUG_SIG 397#if DEBUG_SIG
406 printk(KERN_DEBUG "SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n", 398 printk(KERN_DEBUG "SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n",
407 sig, current->comm, current->pid, frame, regs->pc, 399 sig, current->comm, current->pid, frame, regs->pc,
@@ -475,11 +467,6 @@ static void do_signal(struct pt_regs *regs)
475 siginfo_t info; 467 siginfo_t info;
476 int signr; 468 int signr;
477 469
478 /* we want the common case to go fast, which is why we may in certain
479 * cases get here from kernel mode */
480 if (!user_mode(regs))
481 return;
482
483 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 470 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
484 if (signr > 0) { 471 if (signr > 0) {
485 if (handle_signal(signr, &info, &ka, regs) == 0) { 472 if (handle_signal(signr, &info, &ka, regs) == 0) {