aboutsummaryrefslogtreecommitdiffstats
path: root/arch/avr32/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/avr32/kernel')
-rw-r--r--arch/avr32/kernel/Makefile2
-rw-r--r--arch/avr32/kernel/entry-avr32b.S14
-rw-r--r--arch/avr32/kernel/process.c88
-rw-r--r--arch/avr32/kernel/sys_avr32.c24
-rw-r--r--arch/avr32/kernel/syscall-stubs.S6
-rw-r--r--arch/avr32/kernel/syscall_table.S2
6 files changed, 27 insertions, 109 deletions
diff --git a/arch/avr32/kernel/Makefile b/arch/avr32/kernel/Makefile
index 9e2c465ef3a..119a2e41def 100644
--- a/arch/avr32/kernel/Makefile
+++ b/arch/avr32/kernel/Makefile
@@ -7,7 +7,7 @@ extra-y := head.o vmlinux.lds
7obj-$(CONFIG_SUBARCH_AVR32B) += entry-avr32b.o 7obj-$(CONFIG_SUBARCH_AVR32B) += entry-avr32b.o
8obj-y += syscall_table.o syscall-stubs.o irq.o 8obj-y += syscall_table.o syscall-stubs.o irq.o
9obj-y += setup.o traps.o ocd.o ptrace.o 9obj-y += setup.o traps.o ocd.o ptrace.o
10obj-y += signal.o sys_avr32.o process.o time.o 10obj-y += signal.o process.o time.o
11obj-y += switch_to.o cpu.o 11obj-y += switch_to.o cpu.o
12obj-$(CONFIG_MODULES) += module.o avr32_ksyms.o 12obj-$(CONFIG_MODULES) += module.o avr32_ksyms.o
13obj-$(CONFIG_KPROBES) += kprobes.o 13obj-$(CONFIG_KPROBES) += kprobes.o
diff --git a/arch/avr32/kernel/entry-avr32b.S b/arch/avr32/kernel/entry-avr32b.S
index df288418131..9899d3cc6f0 100644
--- a/arch/avr32/kernel/entry-avr32b.S
+++ b/arch/avr32/kernel/entry-avr32b.S
@@ -251,13 +251,15 @@ syscall_badsys:
251 .global ret_from_fork 251 .global ret_from_fork
252ret_from_fork: 252ret_from_fork:
253 call schedule_tail 253 call schedule_tail
254 mov r12, 0
255 rjmp syscall_return
254 256
255 /* check for syscall tracing */ 257 .global ret_from_kernel_thread
256 get_thread_info r0 258ret_from_kernel_thread:
257 ld.w r1, r0[TI_flags] 259 call schedule_tail
258 andl r1, _TIF_ALLWORK_MASK, COH 260 mov r12, r0
259 brne syscall_exit_work 261 mov lr, r2 /* syscall_return */
260 rjmp syscall_exit_cont 262 mov pc, r1
261 263
262syscall_trace_enter: 264syscall_trace_enter:
263 pushm r8-r12 265 pushm r8-r12
diff --git a/arch/avr32/kernel/process.c b/arch/avr32/kernel/process.c
index 1bb0a8abd79..09b894d96d6 100644
--- a/arch/avr32/kernel/process.c
+++ b/arch/avr32/kernel/process.c
@@ -69,44 +69,6 @@ void machine_restart(char *cmd)
69} 69}
70 70
71/* 71/*
72 * PC is actually discarded when returning from a system call -- the
73 * return address must be stored in LR. This function will make sure
74 * LR points to do_exit before starting the thread.
75 *
76 * Also, when returning from fork(), r12 is 0, so we must copy the
77 * argument as well.
78 *
79 * r0 : The argument to the main thread function
80 * r1 : The address of do_exit
81 * r2 : The address of the main thread function
82 */
83asmlinkage extern void kernel_thread_helper(void);
84__asm__(" .type kernel_thread_helper, @function\n"
85 "kernel_thread_helper:\n"
86 " mov r12, r0\n"
87 " mov lr, r2\n"
88 " mov pc, r1\n"
89 " .size kernel_thread_helper, . - kernel_thread_helper");
90
91int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
92{
93 struct pt_regs regs;
94
95 memset(&regs, 0, sizeof(regs));
96
97 regs.r0 = (unsigned long)arg;
98 regs.r1 = (unsigned long)fn;
99 regs.r2 = (unsigned long)do_exit;
100 regs.lr = (unsigned long)kernel_thread_helper;
101 regs.pc = (unsigned long)kernel_thread_helper;
102 regs.sr = MODE_SUPERVISOR;
103
104 return do_fork(flags | CLONE_VM | CLONE_UNTRACED,
105 0, &regs, 0, NULL, NULL);
106}
107EXPORT_SYMBOL(kernel_thread);
108
109/*
110 * Free current thread data structures etc 72 * Free current thread data structures etc
111 */ 73 */
112void exit_thread(void) 74void exit_thread(void)
@@ -332,26 +294,31 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu)
332} 294}
333 295
334asmlinkage void ret_from_fork(void); 296asmlinkage void ret_from_fork(void);
297asmlinkage void ret_from_kernel_thread(void);
298asmlinkage void syscall_return(void);
335 299
336int copy_thread(unsigned long clone_flags, unsigned long usp, 300int copy_thread(unsigned long clone_flags, unsigned long usp,
337 unsigned long unused, 301 unsigned long arg,
338 struct task_struct *p, struct pt_regs *regs) 302 struct task_struct *p, struct pt_regs *regs)
339{ 303{
340 struct pt_regs *childregs; 304 struct pt_regs *childregs = task_pt_regs(p);
341 305
342 childregs = ((struct pt_regs *)(THREAD_SIZE + (unsigned long)task_stack_page(p))) - 1; 306 if (unlikely(!regs)) {
343 *childregs = *regs; 307 memset(childregs, 0, sizeof(struct pt_regs));
344 308 p->thread.cpu_context.r0 = arg;
345 if (user_mode(regs)) 309 p->thread.cpu_context.r1 = usp; /* fn */
310 p->thread.cpu_context.r2 = syscall_return;
311 p->thread.cpu_context.pc = (unsigned long)ret_from_kernel_thread;
312 childregs->sr = MODE_SUPERVISOR;
313 } else {
314 *childregs = *regs;
346 childregs->sp = usp; 315 childregs->sp = usp;
347 else 316 childregs->r12 = 0; /* Set return value for child */
348 childregs->sp = (unsigned long)task_stack_page(p) + THREAD_SIZE; 317 p->thread.cpu_context.pc = (unsigned long)ret_from_fork;
349 318 }
350 childregs->r12 = 0; /* Set return value for child */
351 319
352 p->thread.cpu_context.sr = MODE_SUPERVISOR | SR_GM; 320 p->thread.cpu_context.sr = MODE_SUPERVISOR | SR_GM;
353 p->thread.cpu_context.ksp = (unsigned long)childregs; 321 p->thread.cpu_context.ksp = (unsigned long)childregs;
354 p->thread.cpu_context.pc = (unsigned long)ret_from_fork;
355 322
356 clear_tsk_thread_flag(p, TIF_DEBUG); 323 clear_tsk_thread_flag(p, TIF_DEBUG);
357 if ((clone_flags & CLONE_PTRACE) && test_thread_flag(TIF_DEBUG)) 324 if ((clone_flags & CLONE_PTRACE) && test_thread_flag(TIF_DEBUG))
@@ -382,27 +349,6 @@ asmlinkage int sys_vfork(struct pt_regs *regs)
382 0, NULL, NULL); 349 0, NULL, NULL);
383} 350}
384 351
385asmlinkage int sys_execve(const char __user *ufilename,
386 const char __user *const __user *uargv,
387 const char __user *const __user *uenvp,
388 struct pt_regs *regs)
389{
390 int error;
391 struct filename *filename;
392
393 filename = getname(ufilename);
394 error = PTR_ERR(filename);
395 if (IS_ERR(filename))
396 goto out;
397
398 error = do_execve(filename->name, uargv, uenvp, regs);
399 putname(filename);
400
401out:
402 return error;
403}
404
405
406/* 352/*
407 * This function is supposed to answer the question "who called 353 * This function is supposed to answer the question "who called
408 * schedule()?" 354 * schedule()?"
diff --git a/arch/avr32/kernel/sys_avr32.c b/arch/avr32/kernel/sys_avr32.c
deleted file mode 100644
index 62635a09ae3..00000000000
--- a/arch/avr32/kernel/sys_avr32.c
+++ /dev/null
@@ -1,24 +0,0 @@
1/*
2 * Copyright (C) 2004-2006 Atmel Corporation
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8#include <linux/unistd.h>
9
10int kernel_execve(const char *file,
11 const char *const *argv,
12 const char *const *envp)
13{
14 register long scno asm("r8") = __NR_execve;
15 register long sc1 asm("r12") = (long)file;
16 register long sc2 asm("r11") = (long)argv;
17 register long sc3 asm("r10") = (long)envp;
18
19 asm volatile("scall"
20 : "=r"(sc1)
21 : "r"(scno), "0"(sc1), "r"(sc2), "r"(sc3)
22 : "cc", "memory");
23 return sc1;
24}
diff --git a/arch/avr32/kernel/syscall-stubs.S b/arch/avr32/kernel/syscall-stubs.S
index 0447a3e2ba6..285a61b9194 100644
--- a/arch/avr32/kernel/syscall-stubs.S
+++ b/arch/avr32/kernel/syscall-stubs.S
@@ -50,12 +50,6 @@ __sys_vfork:
50 mov r12, sp 50 mov r12, sp
51 rjmp sys_vfork 51 rjmp sys_vfork
52 52
53 .global __sys_execve
54 .type __sys_execve,@function
55__sys_execve:
56 mov r9, sp
57 rjmp sys_execve
58
59 .global __sys_mmap2 53 .global __sys_mmap2
60 .type __sys_mmap2,@function 54 .type __sys_mmap2,@function
61__sys_mmap2: 55__sys_mmap2:
diff --git a/arch/avr32/kernel/syscall_table.S b/arch/avr32/kernel/syscall_table.S
index 6eba53530d1..fc649770681 100644
--- a/arch/avr32/kernel/syscall_table.S
+++ b/arch/avr32/kernel/syscall_table.S
@@ -24,7 +24,7 @@ sys_call_table:
24 .long sys_creat 24 .long sys_creat
25 .long sys_link 25 .long sys_link
26 .long sys_unlink /* 10 */ 26 .long sys_unlink /* 10 */
27 .long __sys_execve 27 .long sys_execve
28 .long sys_chdir 28 .long sys_chdir
29 .long sys_time 29 .long sys_time
30 .long sys_mknod 30 .long sys_mknod