diff options
Diffstat (limited to 'arch/cris')
-rw-r--r-- | arch/cris/Kconfig | 2 | ||||
-rw-r--r-- | arch/cris/arch-v10/kernel/entry.S | 17 | ||||
-rw-r--r-- | arch/cris/arch-v10/kernel/process.c | 106 | ||||
-rw-r--r-- | arch/cris/arch-v32/kernel/entry.S | 22 | ||||
-rw-r--r-- | arch/cris/arch-v32/kernel/process.c | 96 | ||||
-rw-r--r-- | arch/cris/include/asm/processor.h | 2 | ||||
-rw-r--r-- | arch/cris/include/asm/unistd.h | 1 | ||||
-rw-r--r-- | arch/cris/kernel/crisksyms.c | 1 |
8 files changed, 71 insertions, 176 deletions
diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig index a67244473a39..81b59d18867e 100644 --- a/arch/cris/Kconfig +++ b/arch/cris/Kconfig | |||
@@ -49,6 +49,8 @@ config CRIS | |||
49 | select GENERIC_SMP_IDLE_THREAD if ETRAX_ARCH_V32 | 49 | select GENERIC_SMP_IDLE_THREAD if ETRAX_ARCH_V32 |
50 | select GENERIC_CMOS_UPDATE | 50 | select GENERIC_CMOS_UPDATE |
51 | select MODULES_USE_ELF_RELA | 51 | select MODULES_USE_ELF_RELA |
52 | select GENERIC_KERNEL_THREAD | ||
53 | select GENERIC_KERNEL_EXECVE | ||
52 | 54 | ||
53 | config HZ | 55 | config HZ |
54 | int | 56 | int |
diff --git a/arch/cris/arch-v10/kernel/entry.S b/arch/cris/arch-v10/kernel/entry.S index 592fbe9dfb62..897bba67bf7a 100644 --- a/arch/cris/arch-v10/kernel/entry.S +++ b/arch/cris/arch-v10/kernel/entry.S | |||
@@ -35,6 +35,7 @@ | |||
35 | .globl system_call | 35 | .globl system_call |
36 | .globl ret_from_intr | 36 | .globl ret_from_intr |
37 | .globl ret_from_fork | 37 | .globl ret_from_fork |
38 | .globl ret_from_kernel_thread | ||
38 | .globl resume | 39 | .globl resume |
39 | .globl multiple_interrupt | 40 | .globl multiple_interrupt |
40 | .globl hwbreakpoint | 41 | .globl hwbreakpoint |
@@ -81,7 +82,14 @@ ret_from_fork: | |||
81 | jsr schedule_tail | 82 | jsr schedule_tail |
82 | ba ret_from_sys_call | 83 | ba ret_from_sys_call |
83 | nop | 84 | nop |
84 | 85 | ||
86 | ret_from_kernel_thread: | ||
87 | jsr schedule_tail | ||
88 | move.d $r2, $r10 ; argument is here | ||
89 | jsr $r1 ; call the payload | ||
90 | moveq 0, $r9 ; no syscall restarts, TYVM... | ||
91 | ba ret_from_sys_call | ||
92 | |||
85 | ret_from_intr: | 93 | ret_from_intr: |
86 | ;; check for resched if preemptive kernel or if we're going back to user-mode | 94 | ;; check for resched if preemptive kernel or if we're going back to user-mode |
87 | ;; this test matches the user_regs(regs) macro | 95 | ;; this test matches the user_regs(regs) macro |
@@ -586,13 +594,6 @@ _ugdb_handle_breakpoint: | |||
586 | ba do_sigtrap ; SIGTRAP the offending process. | 594 | ba do_sigtrap ; SIGTRAP the offending process. |
587 | pop $dccr ; Restore dccr in delay slot. | 595 | pop $dccr ; Restore dccr in delay slot. |
588 | 596 | ||
589 | .global kernel_execve | ||
590 | kernel_execve: | ||
591 | move.d __NR_execve, $r9 | ||
592 | break 13 | ||
593 | ret | ||
594 | nop | ||
595 | |||
596 | .data | 597 | .data |
597 | 598 | ||
598 | hw_bp_trigs: | 599 | hw_bp_trigs: |
diff --git a/arch/cris/arch-v10/kernel/process.c b/arch/cris/arch-v10/kernel/process.c index 15ac7150371f..1d6458287f38 100644 --- a/arch/cris/arch-v10/kernel/process.c +++ b/arch/cris/arch-v10/kernel/process.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <arch/svinto.h> | 17 | #include <arch/svinto.h> |
18 | #include <linux/init.h> | 18 | #include <linux/init.h> |
19 | #include <arch/system.h> | 19 | #include <arch/system.h> |
20 | #include <asm/ptrace.h> | ||
20 | 21 | ||
21 | #ifdef CONFIG_ETRAX_GPIO | 22 | #ifdef CONFIG_ETRAX_GPIO |
22 | void etrax_gpio_wake_up_check(void); /* drivers/gpio.c */ | 23 | void etrax_gpio_wake_up_check(void); /* drivers/gpio.c */ |
@@ -81,31 +82,6 @@ unsigned long thread_saved_pc(struct task_struct *t) | |||
81 | return task_pt_regs(t)->irp; | 82 | return task_pt_regs(t)->irp; |
82 | } | 83 | } |
83 | 84 | ||
84 | static void kernel_thread_helper(void* dummy, int (*fn)(void *), void * arg) | ||
85 | { | ||
86 | fn(arg); | ||
87 | do_exit(-1); /* Should never be called, return bad exit value */ | ||
88 | } | ||
89 | |||
90 | /* | ||
91 | * Create a kernel thread | ||
92 | */ | ||
93 | int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) | ||
94 | { | ||
95 | struct pt_regs regs; | ||
96 | |||
97 | memset(®s, 0, sizeof(regs)); | ||
98 | |||
99 | /* Don't use r10 since that is set to 0 in copy_thread */ | ||
100 | regs.r11 = (unsigned long)fn; | ||
101 | regs.r12 = (unsigned long)arg; | ||
102 | regs.irp = (unsigned long)kernel_thread_helper; | ||
103 | regs.dccr = 1 << I_DCCR_BITNR; | ||
104 | |||
105 | /* Ok, create the new process.. */ | ||
106 | return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); | ||
107 | } | ||
108 | |||
109 | /* setup the child's kernel stack with a pt_regs and switch_stack on it. | 85 | /* setup the child's kernel stack with a pt_regs and switch_stack on it. |
110 | * it will be un-nested during _resume and _ret_from_sys_call when the | 86 | * it will be un-nested during _resume and _ret_from_sys_call when the |
111 | * new thread is scheduled. | 87 | * new thread is scheduled. |
@@ -115,29 +91,35 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) | |||
115 | * | 91 | * |
116 | */ | 92 | */ |
117 | asmlinkage void ret_from_fork(void); | 93 | asmlinkage void ret_from_fork(void); |
94 | asmlinkage void ret_from_kernel_thread(void); | ||
118 | 95 | ||
119 | int copy_thread(unsigned long clone_flags, unsigned long usp, | 96 | int copy_thread(unsigned long clone_flags, unsigned long usp, |
120 | unsigned long unused, | 97 | unsigned long arg, |
121 | struct task_struct *p, struct pt_regs *regs) | 98 | struct task_struct *p, struct pt_regs *regs) |
122 | { | 99 | { |
123 | struct pt_regs * childregs; | 100 | struct pt_regs *childregs = task_pt_regs(p); |
124 | struct switch_stack *swstack; | 101 | struct switch_stack *swstack = ((struct switch_stack *)childregs) - 1; |
125 | 102 | ||
126 | /* put the pt_regs structure at the end of the new kernel stack page and fix it up | 103 | /* put the pt_regs structure at the end of the new kernel stack page and fix it up |
127 | * remember that the task_struct doubles as the kernel stack for the task | 104 | * remember that the task_struct doubles as the kernel stack for the task |
128 | */ | 105 | */ |
129 | 106 | ||
130 | childregs = task_pt_regs(p); | 107 | if (unlikely(p->flags & PF_KTHREAD)) { |
131 | 108 | memset(swstack, 0, | |
109 | sizeof(struct switch_stack) + sizeof(struct pt_regs)); | ||
110 | swstack->r1 = usp; | ||
111 | swstack->r2 = arg; | ||
112 | childregs->dccr = 1 << I_DCCR_BITNR; | ||
113 | swstack->return_ip = (unsigned long) ret_from_kernel_thread; | ||
114 | p->thread.ksp = (unsigned long) swstack; | ||
115 | p->thread.usp = 0; | ||
116 | return 0; | ||
117 | } | ||
132 | *childregs = *regs; /* struct copy of pt_regs */ | 118 | *childregs = *regs; /* struct copy of pt_regs */ |
133 | |||
134 | p->set_child_tid = p->clear_child_tid = NULL; | ||
135 | 119 | ||
136 | childregs->r10 = 0; /* child returns 0 after a fork/clone */ | 120 | childregs->r10 = 0; /* child returns 0 after a fork/clone */ |
137 | |||
138 | /* put the switch stack right below the pt_regs */ | ||
139 | 121 | ||
140 | swstack = ((struct switch_stack *)childregs) - 1; | 122 | /* put the switch stack right below the pt_regs */ |
141 | 123 | ||
142 | swstack->r9 = 0; /* parameter to ret_from_sys_call, 0 == dont restart the syscall */ | 124 | swstack->r9 = 0; /* parameter to ret_from_sys_call, 0 == dont restart the syscall */ |
143 | 125 | ||
@@ -147,7 +129,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, | |||
147 | 129 | ||
148 | /* fix the user-mode stackpointer */ | 130 | /* fix the user-mode stackpointer */ |
149 | 131 | ||
150 | p->thread.usp = usp; | 132 | p->thread.usp = usp; |
151 | 133 | ||
152 | /* and the kernel-mode one */ | 134 | /* and the kernel-mode one */ |
153 | 135 | ||
@@ -161,68 +143,28 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, | |||
161 | return 0; | 143 | return 0; |
162 | } | 144 | } |
163 | 145 | ||
164 | /* | 146 | asmlinkage int sys_fork(void) |
165 | * Be aware of the "magic" 7th argument in the four system-calls below. | ||
166 | * They need the latest stackframe, which is put as the 7th argument by | ||
167 | * entry.S. The previous arguments are dummies or actually used, but need | ||
168 | * to be defined to reach the 7th argument. | ||
169 | * | ||
170 | * N.B.: Another method to get the stackframe is to use current_regs(). But | ||
171 | * it returns the latest stack-frame stacked when going from _user mode_ and | ||
172 | * some of these (at least sys_clone) are called from kernel-mode sometimes | ||
173 | * (for example during kernel_thread, above) and thus cannot use it. Thus, | ||
174 | * to be sure not to get any surprises, we use the method for the other calls | ||
175 | * as well. | ||
176 | */ | ||
177 | |||
178 | asmlinkage int sys_fork(long r10, long r11, long r12, long r13, long mof, long srp, | ||
179 | struct pt_regs *regs) | ||
180 | { | 147 | { |
181 | return do_fork(SIGCHLD, rdusp(), regs, 0, NULL, NULL); | 148 | return do_fork(SIGCHLD, rdusp(), current_pt_regs(), 0, NULL, NULL); |
182 | } | 149 | } |
183 | 150 | ||
184 | /* if newusp is 0, we just grab the old usp */ | 151 | /* if newusp is 0, we just grab the old usp */ |
185 | /* FIXME: Is parent_tid/child_tid really third/fourth argument? Update lib? */ | 152 | /* FIXME: Is parent_tid/child_tid really third/fourth argument? Update lib? */ |
186 | asmlinkage int sys_clone(unsigned long newusp, unsigned long flags, | 153 | asmlinkage int sys_clone(unsigned long newusp, unsigned long flags, |
187 | int* parent_tid, int* child_tid, long mof, long srp, | 154 | int* parent_tid, int* child_tid) |
188 | struct pt_regs *regs) | ||
189 | { | 155 | { |
190 | if (!newusp) | 156 | if (!newusp) |
191 | newusp = rdusp(); | 157 | newusp = rdusp(); |
192 | return do_fork(flags, newusp, regs, 0, parent_tid, child_tid); | 158 | return do_fork(flags, newusp, current_pt_regs(), 0, parent_tid, child_tid); |
193 | } | 159 | } |
194 | 160 | ||
195 | /* vfork is a system call in i386 because of register-pressure - maybe | 161 | /* vfork is a system call in i386 because of register-pressure - maybe |
196 | * we can remove it and handle it in libc but we put it here until then. | 162 | * we can remove it and handle it in libc but we put it here until then. |
197 | */ | 163 | */ |
198 | 164 | ||
199 | asmlinkage int sys_vfork(long r10, long r11, long r12, long r13, long mof, long srp, | 165 | asmlinkage int sys_vfork(void) |
200 | struct pt_regs *regs) | ||
201 | { | ||
202 | return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), regs, 0, NULL, NULL); | ||
203 | } | ||
204 | |||
205 | /* | ||
206 | * sys_execve() executes a new program. | ||
207 | */ | ||
208 | asmlinkage int sys_execve(const char *fname, | ||
209 | const char *const *argv, | ||
210 | const char *const *envp, | ||
211 | long r13, long mof, long srp, | ||
212 | struct pt_regs *regs) | ||
213 | { | 166 | { |
214 | int error; | 167 | return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), current_pt_regs(), 0, NULL, NULL); |
215 | struct filename *filename; | ||
216 | |||
217 | filename = getname(fname); | ||
218 | error = PTR_ERR(filename); | ||
219 | |||
220 | if (IS_ERR(filename)) | ||
221 | goto out; | ||
222 | error = do_execve(filename->name, argv, envp, regs); | ||
223 | putname(filename); | ||
224 | out: | ||
225 | return error; | ||
226 | } | 168 | } |
227 | 169 | ||
228 | unsigned long get_wchan(struct task_struct *p) | 170 | unsigned long get_wchan(struct task_struct *p) |
diff --git a/arch/cris/arch-v32/kernel/entry.S b/arch/cris/arch-v32/kernel/entry.S index c3ea4694fbaf..faa644111feb 100644 --- a/arch/cris/arch-v32/kernel/entry.S +++ b/arch/cris/arch-v32/kernel/entry.S | |||
@@ -31,6 +31,7 @@ | |||
31 | .globl system_call | 31 | .globl system_call |
32 | .globl ret_from_intr | 32 | .globl ret_from_intr |
33 | .globl ret_from_fork | 33 | .globl ret_from_fork |
34 | .globl ret_from_kernel_thread | ||
34 | .globl resume | 35 | .globl resume |
35 | .globl multiple_interrupt | 36 | .globl multiple_interrupt |
36 | .globl nmi_interrupt | 37 | .globl nmi_interrupt |
@@ -84,6 +85,18 @@ ret_from_fork: | |||
84 | nop | 85 | nop |
85 | .size ret_from_fork, . - ret_from_fork | 86 | .size ret_from_fork, . - ret_from_fork |
86 | 87 | ||
88 | .type ret_from_kernel_thread,@function | ||
89 | ret_from_kernel_thread: | ||
90 | jsr schedule_tail | ||
91 | nop | ||
92 | move.d $r2, $r10 | ||
93 | jsr $r1 | ||
94 | nop | ||
95 | moveq 0, $r9 ; no syscall restarts, TYVM... | ||
96 | ba ret_from_sys_call | ||
97 | nop | ||
98 | .size ret_from_kernel_thread, . - ret_from_kernel_thread | ||
99 | |||
87 | .type ret_from_intr,@function | 100 | .type ret_from_intr,@function |
88 | ret_from_intr: | 101 | ret_from_intr: |
89 | ;; Check for resched if preemptive kernel, or if we're going back to | 102 | ;; Check for resched if preemptive kernel, or if we're going back to |
@@ -531,15 +544,6 @@ _ugdb_handle_exception: | |||
531 | ba do_sigtrap ; SIGTRAP the offending process. | 544 | ba do_sigtrap ; SIGTRAP the offending process. |
532 | move.d [$sp+], $r0 ; Restore R0 in delay slot. | 545 | move.d [$sp+], $r0 ; Restore R0 in delay slot. |
533 | 546 | ||
534 | .global kernel_execve | ||
535 | .type kernel_execve,@function | ||
536 | kernel_execve: | ||
537 | move.d __NR_execve, $r9 | ||
538 | break 13 | ||
539 | ret | ||
540 | nop | ||
541 | .size kernel_execve, . - kernel_execve | ||
542 | |||
543 | .data | 547 | .data |
544 | 548 | ||
545 | .section .rodata,"a" | 549 | .section .rodata,"a" |
diff --git a/arch/cris/arch-v32/kernel/process.c b/arch/cris/arch-v32/kernel/process.c index 4e9992246359..fe465401b6ec 100644 --- a/arch/cris/arch-v32/kernel/process.c +++ b/arch/cris/arch-v32/kernel/process.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <hwregs/reg_map.h> | 16 | #include <hwregs/reg_map.h> |
17 | #include <hwregs/timer_defs.h> | 17 | #include <hwregs/timer_defs.h> |
18 | #include <hwregs/intr_vect_defs.h> | 18 | #include <hwregs/intr_vect_defs.h> |
19 | #include <asm/ptrace.h> | ||
19 | 20 | ||
20 | extern void stop_watchdog(void); | 21 | extern void stop_watchdog(void); |
21 | 22 | ||
@@ -94,31 +95,6 @@ unsigned long thread_saved_pc(struct task_struct *t) | |||
94 | return task_pt_regs(t)->erp; | 95 | return task_pt_regs(t)->erp; |
95 | } | 96 | } |
96 | 97 | ||
97 | static void | ||
98 | kernel_thread_helper(void* dummy, int (*fn)(void *), void * arg) | ||
99 | { | ||
100 | fn(arg); | ||
101 | do_exit(-1); /* Should never be called, return bad exit value. */ | ||
102 | } | ||
103 | |||
104 | /* Create a kernel thread. */ | ||
105 | int | ||
106 | kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) | ||
107 | { | ||
108 | struct pt_regs regs; | ||
109 | |||
110 | memset(®s, 0, sizeof(regs)); | ||
111 | |||
112 | /* Don't use r10 since that is set to 0 in copy_thread. */ | ||
113 | regs.r11 = (unsigned long) fn; | ||
114 | regs.r12 = (unsigned long) arg; | ||
115 | regs.erp = (unsigned long) kernel_thread_helper; | ||
116 | regs.ccs = 1 << (I_CCS_BITNR + CCS_SHIFT); | ||
117 | |||
118 | /* Create the new process. */ | ||
119 | return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); | ||
120 | } | ||
121 | |||
122 | /* | 98 | /* |
123 | * Setup the child's kernel stack with a pt_regs and call switch_stack() on it. | 99 | * Setup the child's kernel stack with a pt_regs and call switch_stack() on it. |
124 | * It will be unnested during _resume and _ret_from_sys_call when the new thread | 100 | * It will be unnested during _resume and _ret_from_sys_call when the new thread |
@@ -129,23 +105,33 @@ kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) | |||
129 | */ | 105 | */ |
130 | 106 | ||
131 | extern asmlinkage void ret_from_fork(void); | 107 | extern asmlinkage void ret_from_fork(void); |
108 | extern asmlinkage void ret_from_kernel_thread(void); | ||
132 | 109 | ||
133 | int | 110 | int |
134 | copy_thread(unsigned long clone_flags, unsigned long usp, | 111 | copy_thread(unsigned long clone_flags, unsigned long usp, |
135 | unsigned long unused, | 112 | unsigned long arg, |
136 | struct task_struct *p, struct pt_regs *regs) | 113 | struct task_struct *p, struct pt_regs *regs) |
137 | { | 114 | { |
138 | struct pt_regs *childregs; | 115 | struct pt_regs *childregs = task_pt_regs(p); |
139 | struct switch_stack *swstack; | 116 | struct switch_stack *swstack = ((struct switch_stack *) childregs) - 1; |
140 | 117 | ||
141 | /* | 118 | /* |
142 | * Put the pt_regs structure at the end of the new kernel stack page and | 119 | * Put the pt_regs structure at the end of the new kernel stack page and |
143 | * fix it up. Note: the task_struct doubles as the kernel stack for the | 120 | * fix it up. Note: the task_struct doubles as the kernel stack for the |
144 | * task. | 121 | * task. |
145 | */ | 122 | */ |
146 | childregs = task_pt_regs(p); | 123 | if (unlikely(p->flags & PF_KTHREAD)) { |
124 | memset(swstack, 0, | ||
125 | sizeof(struct switch_stack) + sizeof(struct pt_regs)); | ||
126 | swstack->r1 = usp; | ||
127 | swstack->r2 = arg; | ||
128 | childregs->ccs = 1 << (I_CCS_BITNR + CCS_SHIFT); | ||
129 | swstack->return_ip = (unsigned long) ret_from_kernel_thread; | ||
130 | p->thread.ksp = (unsigned long) swstack; | ||
131 | p->thread.usp = 0; | ||
132 | return 0; | ||
133 | } | ||
147 | *childregs = *regs; /* Struct copy of pt_regs. */ | 134 | *childregs = *regs; /* Struct copy of pt_regs. */ |
148 | p->set_child_tid = p->clear_child_tid = NULL; | ||
149 | childregs->r10 = 0; /* Child returns 0 after a fork/clone. */ | 135 | childregs->r10 = 0; /* Child returns 0 after a fork/clone. */ |
150 | 136 | ||
151 | /* Set a new TLS ? | 137 | /* Set a new TLS ? |
@@ -156,7 +142,6 @@ copy_thread(unsigned long clone_flags, unsigned long usp, | |||
156 | } | 142 | } |
157 | 143 | ||
158 | /* Put the switch stack right below the pt_regs. */ | 144 | /* Put the switch stack right below the pt_regs. */ |
159 | swstack = ((struct switch_stack *) childregs) - 1; | ||
160 | 145 | ||
161 | /* Parameter to ret_from_sys_call. 0 is don't restart the syscall. */ | 146 | /* Parameter to ret_from_sys_call. 0 is don't restart the syscall. */ |
162 | swstack->r9 = 0; | 147 | swstack->r9 = 0; |
@@ -174,35 +159,21 @@ copy_thread(unsigned long clone_flags, unsigned long usp, | |||
174 | return 0; | 159 | return 0; |
175 | } | 160 | } |
176 | 161 | ||
177 | /* | ||
178 | * Be aware of the "magic" 7th argument in the four system-calls below. | ||
179 | * They need the latest stackframe, which is put as the 7th argument by | ||
180 | * entry.S. The previous arguments are dummies or actually used, but need | ||
181 | * to be defined to reach the 7th argument. | ||
182 | * | ||
183 | * N.B.: Another method to get the stackframe is to use current_regs(). But | ||
184 | * it returns the latest stack-frame stacked when going from _user mode_ and | ||
185 | * some of these (at least sys_clone) are called from kernel-mode sometimes | ||
186 | * (for example during kernel_thread, above) and thus cannot use it. Thus, | ||
187 | * to be sure not to get any surprises, we use the method for the other calls | ||
188 | * as well. | ||
189 | */ | ||
190 | asmlinkage int | 162 | asmlinkage int |
191 | sys_fork(long r10, long r11, long r12, long r13, long mof, long srp, | 163 | sys_fork(void) |
192 | struct pt_regs *regs) | ||
193 | { | 164 | { |
194 | return do_fork(SIGCHLD, rdusp(), regs, 0, NULL, NULL); | 165 | return do_fork(SIGCHLD, rdusp(), current_pt_regs(), 0, NULL, NULL); |
195 | } | 166 | } |
196 | 167 | ||
197 | /* FIXME: Is parent_tid/child_tid really third/fourth argument? Update lib? */ | 168 | /* FIXME: Is parent_tid/child_tid really third/fourth argument? Update lib? */ |
198 | asmlinkage int | 169 | asmlinkage int |
199 | sys_clone(unsigned long newusp, unsigned long flags, int *parent_tid, int *child_tid, | 170 | sys_clone(unsigned long newusp, unsigned long flags, int *parent_tid, int *child_tid, |
200 | unsigned long tls, long srp, struct pt_regs *regs) | 171 | unsigned long tls) |
201 | { | 172 | { |
202 | if (!newusp) | 173 | if (!newusp) |
203 | newusp = rdusp(); | 174 | newusp = rdusp(); |
204 | 175 | ||
205 | return do_fork(flags, newusp, regs, 0, parent_tid, child_tid); | 176 | return do_fork(flags, newusp, current_pt_regs(), 0, parent_tid, child_tid); |
206 | } | 177 | } |
207 | 178 | ||
208 | /* | 179 | /* |
@@ -210,32 +181,9 @@ sys_clone(unsigned long newusp, unsigned long flags, int *parent_tid, int *child | |||
210 | * we can remove it and handle it in libc but we put it here until then. | 181 | * we can remove it and handle it in libc but we put it here until then. |
211 | */ | 182 | */ |
212 | asmlinkage int | 183 | asmlinkage int |
213 | sys_vfork(long r10, long r11, long r12, long r13, long mof, long srp, | 184 | sys_vfork(void) |
214 | struct pt_regs *regs) | ||
215 | { | ||
216 | return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), regs, 0, NULL, NULL); | ||
217 | } | ||
218 | |||
219 | /* sys_execve() executes a new program. */ | ||
220 | asmlinkage int | ||
221 | sys_execve(const char *fname, | ||
222 | const char *const *argv, | ||
223 | const char *const *envp, long r13, long mof, long srp, | ||
224 | struct pt_regs *regs) | ||
225 | { | 185 | { |
226 | int error; | 186 | return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), current_pt_regs(), 0, NULL, NULL); |
227 | struct filename *filename; | ||
228 | |||
229 | filename = getname(fname); | ||
230 | error = PTR_ERR(filename); | ||
231 | |||
232 | if (IS_ERR(filename)) | ||
233 | goto out; | ||
234 | |||
235 | error = do_execve(filename->name, argv, envp, regs); | ||
236 | putname(filename); | ||
237 | out: | ||
238 | return error; | ||
239 | } | 187 | } |
240 | 188 | ||
241 | unsigned long | 189 | unsigned long |
diff --git a/arch/cris/include/asm/processor.h b/arch/cris/include/asm/processor.h index ef4e1bc3efc8..675823f70c0f 100644 --- a/arch/cris/include/asm/processor.h +++ b/arch/cris/include/asm/processor.h | |||
@@ -49,8 +49,6 @@ struct task_struct; | |||
49 | #define task_pt_regs(task) user_regs(task_thread_info(task)) | 49 | #define task_pt_regs(task) user_regs(task_thread_info(task)) |
50 | #define current_regs() task_pt_regs(current) | 50 | #define current_regs() task_pt_regs(current) |
51 | 51 | ||
52 | extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); | ||
53 | |||
54 | unsigned long get_wchan(struct task_struct *p); | 52 | unsigned long get_wchan(struct task_struct *p); |
55 | 53 | ||
56 | #define KSTK_ESP(tsk) ((tsk) == current ? rdusp() : (tsk)->thread.usp) | 54 | #define KSTK_ESP(tsk) ((tsk) == current ? rdusp() : (tsk)->thread.usp) |
diff --git a/arch/cris/include/asm/unistd.h b/arch/cris/include/asm/unistd.h index 51873a446f87..f181d1fc7632 100644 --- a/arch/cris/include/asm/unistd.h +++ b/arch/cris/include/asm/unistd.h | |||
@@ -371,6 +371,7 @@ | |||
371 | #define __ARCH_WANT_SYS_SIGPROCMASK | 371 | #define __ARCH_WANT_SYS_SIGPROCMASK |
372 | #define __ARCH_WANT_SYS_RT_SIGACTION | 372 | #define __ARCH_WANT_SYS_RT_SIGACTION |
373 | #define __ARCH_WANT_SYS_RT_SIGSUSPEND | 373 | #define __ARCH_WANT_SYS_RT_SIGSUSPEND |
374 | #define __ARCH_WANT_SYS_EXECVE | ||
374 | 375 | ||
375 | /* | 376 | /* |
376 | * "Conditional" syscalls | 377 | * "Conditional" syscalls |
diff --git a/arch/cris/kernel/crisksyms.c b/arch/cris/kernel/crisksyms.c index 7ac000f6a888..5868cee20ebd 100644 --- a/arch/cris/kernel/crisksyms.c +++ b/arch/cris/kernel/crisksyms.c | |||
@@ -30,7 +30,6 @@ extern void __negdi2(void); | |||
30 | extern void iounmap(volatile void * __iomem); | 30 | extern void iounmap(volatile void * __iomem); |
31 | 31 | ||
32 | /* Platform dependent support */ | 32 | /* Platform dependent support */ |
33 | EXPORT_SYMBOL(kernel_thread); | ||
34 | EXPORT_SYMBOL(get_cmos_time); | 33 | EXPORT_SYMBOL(get_cmos_time); |
35 | EXPORT_SYMBOL(loops_per_usec); | 34 | EXPORT_SYMBOL(loops_per_usec); |
36 | 35 | ||