diff options
Diffstat (limited to 'arch/avr32/kernel')
-rw-r--r-- | arch/avr32/kernel/Makefile | 2 | ||||
-rw-r--r-- | arch/avr32/kernel/entry-avr32b.S | 14 | ||||
-rw-r--r-- | arch/avr32/kernel/process.c | 88 | ||||
-rw-r--r-- | arch/avr32/kernel/sys_avr32.c | 24 | ||||
-rw-r--r-- | arch/avr32/kernel/syscall-stubs.S | 6 | ||||
-rw-r--r-- | arch/avr32/kernel/syscall_table.S | 2 |
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 | |||
7 | obj-$(CONFIG_SUBARCH_AVR32B) += entry-avr32b.o | 7 | obj-$(CONFIG_SUBARCH_AVR32B) += entry-avr32b.o |
8 | obj-y += syscall_table.o syscall-stubs.o irq.o | 8 | obj-y += syscall_table.o syscall-stubs.o irq.o |
9 | obj-y += setup.o traps.o ocd.o ptrace.o | 9 | obj-y += setup.o traps.o ocd.o ptrace.o |
10 | obj-y += signal.o sys_avr32.o process.o time.o | 10 | obj-y += signal.o process.o time.o |
11 | obj-y += switch_to.o cpu.o | 11 | obj-y += switch_to.o cpu.o |
12 | obj-$(CONFIG_MODULES) += module.o avr32_ksyms.o | 12 | obj-$(CONFIG_MODULES) += module.o avr32_ksyms.o |
13 | obj-$(CONFIG_KPROBES) += kprobes.o | 13 | obj-$(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 |
252 | ret_from_fork: | 252 | ret_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 | 258 | ret_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 | ||
262 | syscall_trace_enter: | 264 | syscall_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 | */ | ||
83 | asmlinkage 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 | |||
91 | int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) | ||
92 | { | ||
93 | struct pt_regs regs; | ||
94 | |||
95 | memset(®s, 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, ®s, 0, NULL, NULL); | ||
106 | } | ||
107 | EXPORT_SYMBOL(kernel_thread); | ||
108 | |||
109 | /* | ||
110 | * Free current thread data structures etc | 72 | * Free current thread data structures etc |
111 | */ | 73 | */ |
112 | void exit_thread(void) | 74 | void exit_thread(void) |
@@ -332,26 +294,31 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu) | |||
332 | } | 294 | } |
333 | 295 | ||
334 | asmlinkage void ret_from_fork(void); | 296 | asmlinkage void ret_from_fork(void); |
297 | asmlinkage void ret_from_kernel_thread(void); | ||
298 | asmlinkage void syscall_return(void); | ||
335 | 299 | ||
336 | int copy_thread(unsigned long clone_flags, unsigned long usp, | 300 | int 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 | ||
385 | asmlinkage 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 | |||
401 | out: | ||
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 | |||
10 | int 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 |