diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
commit | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch) | |
tree | a8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /arch/m32r/kernel | |
parent | 406089d01562f1e2bf9f089fd7637009ebaad589 (diff) |
Patched in Tegra support.
Diffstat (limited to 'arch/m32r/kernel')
-rw-r--r-- | arch/m32r/kernel/Makefile | 2 | ||||
-rw-r--r-- | arch/m32r/kernel/entry.S | 9 | ||||
-rw-r--r-- | arch/m32r/kernel/m32r_ksyms.c | 1 | ||||
-rw-r--r-- | arch/m32r/kernel/module.c | 15 | ||||
-rw-r--r-- | arch/m32r/kernel/process.c | 133 | ||||
-rw-r--r-- | arch/m32r/kernel/ptrace.c | 8 | ||||
-rw-r--r-- | arch/m32r/kernel/signal.c | 49 | ||||
-rw-r--r-- | arch/m32r/kernel/smpboot.c | 8 | ||||
-rw-r--r-- | arch/m32r/kernel/sys_m32r.c | 21 | ||||
-rw-r--r-- | arch/m32r/kernel/traps.c | 1 |
10 files changed, 202 insertions, 45 deletions
diff --git a/arch/m32r/kernel/Makefile b/arch/m32r/kernel/Makefile index 0c09dad8b1f..b1a4b603659 100644 --- a/arch/m32r/kernel/Makefile +++ b/arch/m32r/kernel/Makefile | |||
@@ -2,7 +2,7 @@ | |||
2 | # Makefile for the Linux/M32R kernel. | 2 | # Makefile for the Linux/M32R kernel. |
3 | # | 3 | # |
4 | 4 | ||
5 | extra-y := head.o vmlinux.lds | 5 | extra-y := head.o init_task.o vmlinux.lds |
6 | 6 | ||
7 | obj-y := process.o entry.o traps.o align.o irq.o setup.o time.o \ | 7 | obj-y := process.o entry.o traps.o align.o irq.o setup.o time.o \ |
8 | m32r_ksyms.o sys_m32r.o signal.o ptrace.o | 8 | m32r_ksyms.o sys_m32r.o signal.o ptrace.o |
diff --git a/arch/m32r/kernel/entry.S b/arch/m32r/kernel/entry.S index 0c01543f10c..225412bc227 100644 --- a/arch/m32r/kernel/entry.S +++ b/arch/m32r/kernel/entry.S | |||
@@ -125,15 +125,6 @@ | |||
125 | and \reg, sp | 125 | and \reg, sp |
126 | .endm | 126 | .endm |
127 | 127 | ||
128 | ENTRY(ret_from_kernel_thread) | ||
129 | pop r0 | ||
130 | bl schedule_tail | ||
131 | GET_THREAD_INFO(r8) | ||
132 | ld r0, R0(r8) | ||
133 | ld r1, R1(r8) | ||
134 | jl r1 | ||
135 | bra syscall_exit | ||
136 | |||
137 | ENTRY(ret_from_fork) | 128 | ENTRY(ret_from_fork) |
138 | pop r0 | 129 | pop r0 |
139 | bl schedule_tail | 130 | bl schedule_tail |
diff --git a/arch/m32r/kernel/m32r_ksyms.c b/arch/m32r/kernel/m32r_ksyms.c index b727e693c80..700570747a9 100644 --- a/arch/m32r/kernel/m32r_ksyms.c +++ b/arch/m32r/kernel/m32r_ksyms.c | |||
@@ -21,6 +21,7 @@ EXPORT_SYMBOL(boot_cpu_data); | |||
21 | EXPORT_SYMBOL(dump_fpu); | 21 | EXPORT_SYMBOL(dump_fpu); |
22 | EXPORT_SYMBOL(__ioremap); | 22 | EXPORT_SYMBOL(__ioremap); |
23 | EXPORT_SYMBOL(iounmap); | 23 | EXPORT_SYMBOL(iounmap); |
24 | EXPORT_SYMBOL(kernel_thread); | ||
24 | 25 | ||
25 | EXPORT_SYMBOL(strncpy_from_user); | 26 | EXPORT_SYMBOL(strncpy_from_user); |
26 | EXPORT_SYMBOL(__strncpy_from_user); | 27 | EXPORT_SYMBOL(__strncpy_from_user); |
diff --git a/arch/m32r/kernel/module.c b/arch/m32r/kernel/module.c index 38233b6596b..3071fe83ffc 100644 --- a/arch/m32r/kernel/module.c +++ b/arch/m32r/kernel/module.c | |||
@@ -201,3 +201,18 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, | |||
201 | } | 201 | } |
202 | return 0; | 202 | return 0; |
203 | } | 203 | } |
204 | |||
205 | int apply_relocate(Elf32_Shdr *sechdrs, | ||
206 | const char *strtab, | ||
207 | unsigned int symindex, | ||
208 | unsigned int relsec, | ||
209 | struct module *me) | ||
210 | { | ||
211 | #if 0 | ||
212 | printk(KERN_ERR "module %s: REL RELOCATION unsupported\n", | ||
213 | me->name); | ||
214 | return -ENOEXEC; | ||
215 | #endif | ||
216 | return 0; | ||
217 | |||
218 | } | ||
diff --git a/arch/m32r/kernel/process.c b/arch/m32r/kernel/process.c index 765d0f57c78..422bea9f1db 100644 --- a/arch/m32r/kernel/process.c +++ b/arch/m32r/kernel/process.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <linux/ptrace.h> | 26 | #include <linux/ptrace.h> |
27 | #include <linux/unistd.h> | 27 | #include <linux/unistd.h> |
28 | #include <linux/hardirq.h> | 28 | #include <linux/hardirq.h> |
29 | #include <linux/rcupdate.h> | ||
30 | 29 | ||
31 | #include <asm/io.h> | 30 | #include <asm/io.h> |
32 | #include <asm/uaccess.h> | 31 | #include <asm/uaccess.h> |
@@ -83,7 +82,6 @@ void cpu_idle (void) | |||
83 | { | 82 | { |
84 | /* endless idle loop with no priority at all */ | 83 | /* endless idle loop with no priority at all */ |
85 | while (1) { | 84 | while (1) { |
86 | rcu_idle_enter(); | ||
87 | while (!need_resched()) { | 85 | while (!need_resched()) { |
88 | void (*idle)(void) = pm_idle; | 86 | void (*idle)(void) = pm_idle; |
89 | 87 | ||
@@ -92,8 +90,9 @@ void cpu_idle (void) | |||
92 | 90 | ||
93 | idle(); | 91 | idle(); |
94 | } | 92 | } |
95 | rcu_idle_exit(); | 93 | preempt_enable_no_resched(); |
96 | schedule_preempt_disabled(); | 94 | schedule(); |
95 | preempt_disable(); | ||
97 | } | 96 | } |
98 | } | 97 | } |
99 | 98 | ||
@@ -165,6 +164,41 @@ void show_regs(struct pt_regs * regs) | |||
165 | } | 164 | } |
166 | 165 | ||
167 | /* | 166 | /* |
167 | * Create a kernel thread | ||
168 | */ | ||
169 | |||
170 | /* | ||
171 | * This is the mechanism for creating a new kernel thread. | ||
172 | * | ||
173 | * NOTE! Only a kernel-only process(ie the swapper or direct descendants | ||
174 | * who haven't done an "execve()") should use this: it will work within | ||
175 | * a system call from a "real" process, but the process memory space will | ||
176 | * not be free'd until both the parent and the child have exited. | ||
177 | */ | ||
178 | static void kernel_thread_helper(void *nouse, int (*fn)(void *), void *arg) | ||
179 | { | ||
180 | fn(arg); | ||
181 | do_exit(-1); | ||
182 | } | ||
183 | |||
184 | int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) | ||
185 | { | ||
186 | struct pt_regs regs; | ||
187 | |||
188 | memset(®s, 0, sizeof (regs)); | ||
189 | regs.r1 = (unsigned long)fn; | ||
190 | regs.r2 = (unsigned long)arg; | ||
191 | |||
192 | regs.bpc = (unsigned long)kernel_thread_helper; | ||
193 | |||
194 | regs.psw = M32R_PSW_BIE; | ||
195 | |||
196 | /* Ok, create the new process. */ | ||
197 | return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, | ||
198 | NULL); | ||
199 | } | ||
200 | |||
201 | /* | ||
168 | * Free current thread data structures etc.. | 202 | * Free current thread data structures etc.. |
169 | */ | 203 | */ |
170 | void exit_thread(void) | 204 | void exit_thread(void) |
@@ -192,31 +226,88 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu) | |||
192 | } | 226 | } |
193 | 227 | ||
194 | int copy_thread(unsigned long clone_flags, unsigned long spu, | 228 | int copy_thread(unsigned long clone_flags, unsigned long spu, |
195 | unsigned long arg, struct task_struct *tsk) | 229 | unsigned long unused, struct task_struct *tsk, struct pt_regs *regs) |
196 | { | 230 | { |
197 | struct pt_regs *childregs = task_pt_regs(tsk); | 231 | struct pt_regs *childregs = task_pt_regs(tsk); |
198 | extern void ret_from_fork(void); | 232 | extern void ret_from_fork(void); |
199 | extern void ret_from_kernel_thread(void); | 233 | |
200 | 234 | /* Copy registers */ | |
201 | if (unlikely(tsk->flags & PF_KTHREAD)) { | 235 | *childregs = *regs; |
202 | memset(childregs, 0, sizeof(struct pt_regs)); | 236 | |
203 | childregs->psw = M32R_PSW_BIE; | 237 | childregs->spu = spu; |
204 | childregs->r1 = spu; /* fn */ | 238 | childregs->r0 = 0; /* Child gets zero as return value */ |
205 | childregs->r0 = arg; | 239 | regs->r0 = tsk->pid; |
206 | tsk->thread.lr = (unsigned long)ret_from_kernel_thread; | ||
207 | } else { | ||
208 | /* Copy registers */ | ||
209 | *childregs = *current_pt_regs(); | ||
210 | if (spu) | ||
211 | childregs->spu = spu; | ||
212 | childregs->r0 = 0; /* Child gets zero as return value */ | ||
213 | tsk->thread.lr = (unsigned long)ret_from_fork; | ||
214 | } | ||
215 | tsk->thread.sp = (unsigned long)childregs; | 240 | tsk->thread.sp = (unsigned long)childregs; |
241 | tsk->thread.lr = (unsigned long)ret_from_fork; | ||
216 | 242 | ||
217 | return 0; | 243 | return 0; |
218 | } | 244 | } |
219 | 245 | ||
246 | asmlinkage int sys_fork(unsigned long r0, unsigned long r1, unsigned long r2, | ||
247 | unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, | ||
248 | struct pt_regs regs) | ||
249 | { | ||
250 | #ifdef CONFIG_MMU | ||
251 | return do_fork(SIGCHLD, regs.spu, ®s, 0, NULL, NULL); | ||
252 | #else | ||
253 | return -EINVAL; | ||
254 | #endif /* CONFIG_MMU */ | ||
255 | } | ||
256 | |||
257 | asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp, | ||
258 | unsigned long parent_tidptr, | ||
259 | unsigned long child_tidptr, | ||
260 | unsigned long r4, unsigned long r5, unsigned long r6, | ||
261 | struct pt_regs regs) | ||
262 | { | ||
263 | if (!newsp) | ||
264 | newsp = regs.spu; | ||
265 | |||
266 | return do_fork(clone_flags, newsp, ®s, 0, | ||
267 | (int __user *)parent_tidptr, (int __user *)child_tidptr); | ||
268 | } | ||
269 | |||
270 | /* | ||
271 | * This is trivial, and on the face of it looks like it | ||
272 | * could equally well be done in user mode. | ||
273 | * | ||
274 | * Not so, for quite unobvious reasons - register pressure. | ||
275 | * In user mode vfork() cannot have a stack frame, and if | ||
276 | * done by calling the "clone()" system call directly, you | ||
277 | * do not have enough call-clobbered registers to hold all | ||
278 | * the information you need. | ||
279 | */ | ||
280 | asmlinkage int sys_vfork(unsigned long r0, unsigned long r1, unsigned long r2, | ||
281 | unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, | ||
282 | struct pt_regs regs) | ||
283 | { | ||
284 | return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.spu, ®s, 0, | ||
285 | NULL, NULL); | ||
286 | } | ||
287 | |||
288 | /* | ||
289 | * sys_execve() executes a new program. | ||
290 | */ | ||
291 | asmlinkage int sys_execve(const char __user *ufilename, | ||
292 | const char __user *const __user *uargv, | ||
293 | const char __user *const __user *uenvp, | ||
294 | unsigned long r3, unsigned long r4, unsigned long r5, | ||
295 | unsigned long r6, struct pt_regs regs) | ||
296 | { | ||
297 | int error; | ||
298 | char *filename; | ||
299 | |||
300 | filename = getname(ufilename); | ||
301 | error = PTR_ERR(filename); | ||
302 | if (IS_ERR(filename)) | ||
303 | goto out; | ||
304 | |||
305 | error = do_execve(filename, uargv, uenvp, ®s); | ||
306 | putname(filename); | ||
307 | out: | ||
308 | return error; | ||
309 | } | ||
310 | |||
220 | /* | 311 | /* |
221 | * These bracket the sleeping functions.. | 312 | * These bracket the sleeping functions.. |
222 | */ | 313 | */ |
diff --git a/arch/m32r/kernel/ptrace.c b/arch/m32r/kernel/ptrace.c index 51f5e9aa490..20743754f2b 100644 --- a/arch/m32r/kernel/ptrace.c +++ b/arch/m32r/kernel/ptrace.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <asm/io.h> | 29 | #include <asm/io.h> |
30 | #include <asm/uaccess.h> | 30 | #include <asm/uaccess.h> |
31 | #include <asm/pgtable.h> | 31 | #include <asm/pgtable.h> |
32 | #include <asm/system.h> | ||
32 | #include <asm/processor.h> | 33 | #include <asm/processor.h> |
33 | #include <asm/mmu_context.h> | 34 | #include <asm/mmu_context.h> |
34 | 35 | ||
@@ -591,16 +592,17 @@ void user_enable_single_step(struct task_struct *child) | |||
591 | 592 | ||
592 | if (access_process_vm(child, pc&~3, &insn, sizeof(insn), 0) | 593 | if (access_process_vm(child, pc&~3, &insn, sizeof(insn), 0) |
593 | != sizeof(insn)) | 594 | != sizeof(insn)) |
594 | return; | 595 | return -EIO; |
595 | 596 | ||
596 | compute_next_pc(insn, pc, &next_pc, child); | 597 | compute_next_pc(insn, pc, &next_pc, child); |
597 | if (next_pc & 0x80000000) | 598 | if (next_pc & 0x80000000) |
598 | return; | 599 | return -EIO; |
599 | 600 | ||
600 | if (embed_debug_trap(child, next_pc)) | 601 | if (embed_debug_trap(child, next_pc)) |
601 | return; | 602 | return -EIO; |
602 | 603 | ||
603 | invalidate_cache(); | 604 | invalidate_cache(); |
605 | return 0; | ||
604 | } | 606 | } |
605 | 607 | ||
606 | void user_disable_single_step(struct task_struct *child) | 608 | void user_disable_single_step(struct task_struct *child) |
diff --git a/arch/m32r/kernel/signal.c b/arch/m32r/kernel/signal.c index 6e3c26a1607..a08697f0886 100644 --- a/arch/m32r/kernel/signal.c +++ b/arch/m32r/kernel/signal.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/unistd.h> | 20 | #include <linux/unistd.h> |
21 | #include <linux/stddef.h> | 21 | #include <linux/stddef.h> |
22 | #include <linux/personality.h> | 22 | #include <linux/personality.h> |
23 | #include <linux/freezer.h> | ||
23 | #include <linux/tracehook.h> | 24 | #include <linux/tracehook.h> |
24 | #include <asm/cacheflush.h> | 25 | #include <asm/cacheflush.h> |
25 | #include <asm/ucontext.h> | 26 | #include <asm/ucontext.h> |
@@ -27,6 +28,8 @@ | |||
27 | 28 | ||
28 | #define DEBUG_SIG 0 | 29 | #define DEBUG_SIG 0 |
29 | 30 | ||
31 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) | ||
32 | |||
30 | asmlinkage int | 33 | asmlinkage int |
31 | sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, | 34 | sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, |
32 | unsigned long r2, unsigned long r3, unsigned long r4, | 35 | unsigned long r2, unsigned long r3, unsigned long r4, |
@@ -108,7 +111,11 @@ sys_rt_sigreturn(unsigned long r0, unsigned long r1, | |||
108 | if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) | 111 | if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) |
109 | goto badframe; | 112 | goto badframe; |
110 | 113 | ||
111 | set_current_blocked(&set); | 114 | sigdelsetmask(&set, ~_BLOCKABLE); |
115 | spin_lock_irq(¤t->sighand->siglock); | ||
116 | current->blocked = set; | ||
117 | recalc_sigpending(); | ||
118 | spin_unlock_irq(¤t->sighand->siglock); | ||
112 | 119 | ||
113 | if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &result)) | 120 | if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &result)) |
114 | goto badframe; | 121 | goto badframe; |
@@ -263,9 +270,9 @@ static int prev_insn(struct pt_regs *regs) | |||
263 | * OK, we're invoking a handler | 270 | * OK, we're invoking a handler |
264 | */ | 271 | */ |
265 | 272 | ||
266 | static void | 273 | static int |
267 | handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, | 274 | handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, |
268 | struct pt_regs *regs) | 275 | sigset_t *oldset, struct pt_regs *regs) |
269 | { | 276 | { |
270 | /* Are we from a system call? */ | 277 | /* Are we from a system call? */ |
271 | if (regs->syscall_nr >= 0) { | 278 | if (regs->syscall_nr >= 0) { |
@@ -285,15 +292,21 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, | |||
285 | case -ERESTARTNOINTR: | 292 | case -ERESTARTNOINTR: |
286 | regs->r0 = regs->orig_r0; | 293 | regs->r0 = regs->orig_r0; |
287 | if (prev_insn(regs) < 0) | 294 | if (prev_insn(regs) < 0) |
288 | return; | 295 | return -EFAULT; |
289 | } | 296 | } |
290 | } | 297 | } |
291 | 298 | ||
292 | /* Set up the stack frame */ | 299 | /* Set up the stack frame */ |
293 | if (setup_rt_frame(sig, ka, info, sigmask_to_save(), regs)) | 300 | if (setup_rt_frame(sig, ka, info, oldset, regs)) |
294 | return; | 301 | return -EFAULT; |
295 | 302 | ||
296 | signal_delivered(sig, info, ka, regs, 0); | 303 | spin_lock_irq(¤t->sighand->siglock); |
304 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | ||
305 | if (!(ka->sa.sa_flags & SA_NODEFER)) | ||
306 | sigaddset(¤t->blocked,sig); | ||
307 | recalc_sigpending(); | ||
308 | spin_unlock_irq(¤t->sighand->siglock); | ||
309 | return 0; | ||
297 | } | 310 | } |
298 | 311 | ||
299 | /* | 312 | /* |
@@ -306,6 +319,7 @@ static void do_signal(struct pt_regs *regs) | |||
306 | siginfo_t info; | 319 | siginfo_t info; |
307 | int signr; | 320 | int signr; |
308 | struct k_sigaction ka; | 321 | struct k_sigaction ka; |
322 | sigset_t *oldset; | ||
309 | 323 | ||
310 | /* | 324 | /* |
311 | * We want the common case to go fast, which | 325 | * We want the common case to go fast, which |
@@ -316,6 +330,14 @@ static void do_signal(struct pt_regs *regs) | |||
316 | if (!user_mode(regs)) | 330 | if (!user_mode(regs)) |
317 | return; | 331 | return; |
318 | 332 | ||
333 | if (try_to_freeze()) | ||
334 | goto no_signal; | ||
335 | |||
336 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) | ||
337 | oldset = ¤t->saved_sigmask; | ||
338 | else | ||
339 | oldset = ¤t->blocked; | ||
340 | |||
319 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); | 341 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); |
320 | if (signr > 0) { | 342 | if (signr > 0) { |
321 | /* Re-enable any watchpoints before delivering the | 343 | /* Re-enable any watchpoints before delivering the |
@@ -325,11 +347,13 @@ static void do_signal(struct pt_regs *regs) | |||
325 | */ | 347 | */ |
326 | 348 | ||
327 | /* Whee! Actually deliver the signal. */ | 349 | /* Whee! Actually deliver the signal. */ |
328 | handle_signal(signr, &ka, &info, regs); | 350 | if (handle_signal(signr, &ka, &info, oldset, regs) == 0) |
351 | clear_thread_flag(TIF_RESTORE_SIGMASK); | ||
329 | 352 | ||
330 | return; | 353 | return; |
331 | } | 354 | } |
332 | 355 | ||
356 | no_signal: | ||
333 | /* Did we come from a system call? */ | 357 | /* Did we come from a system call? */ |
334 | if (regs->syscall_nr >= 0) { | 358 | if (regs->syscall_nr >= 0) { |
335 | /* Restart the system call - no handlers present */ | 359 | /* Restart the system call - no handlers present */ |
@@ -344,7 +368,10 @@ static void do_signal(struct pt_regs *regs) | |||
344 | prev_insn(regs); | 368 | prev_insn(regs); |
345 | } | 369 | } |
346 | } | 370 | } |
347 | restore_saved_sigmask(); | 371 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) { |
372 | clear_thread_flag(TIF_RESTORE_SIGMASK); | ||
373 | sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); | ||
374 | } | ||
348 | } | 375 | } |
349 | 376 | ||
350 | /* | 377 | /* |
@@ -364,5 +391,9 @@ void do_notify_resume(struct pt_regs *regs, __u32 thread_info_flags) | |||
364 | if (thread_info_flags & _TIF_NOTIFY_RESUME) { | 391 | if (thread_info_flags & _TIF_NOTIFY_RESUME) { |
365 | clear_thread_flag(TIF_NOTIFY_RESUME); | 392 | clear_thread_flag(TIF_NOTIFY_RESUME); |
366 | tracehook_notify_resume(regs); | 393 | tracehook_notify_resume(regs); |
394 | if (current->replacement_session_keyring) | ||
395 | key_replace_session_keyring(); | ||
367 | } | 396 | } |
397 | |||
398 | clear_thread_flag(TIF_IRET); | ||
368 | } | 399 | } |
diff --git a/arch/m32r/kernel/smpboot.c b/arch/m32r/kernel/smpboot.c index 13168a769f8..cfdbe5d1500 100644 --- a/arch/m32r/kernel/smpboot.c +++ b/arch/m32r/kernel/smpboot.c | |||
@@ -109,8 +109,12 @@ static unsigned int calibration_result; | |||
109 | /* Function Prototypes */ | 109 | /* Function Prototypes */ |
110 | /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ | 110 | /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ |
111 | 111 | ||
112 | void smp_prepare_boot_cpu(void); | ||
113 | void smp_prepare_cpus(unsigned int); | ||
112 | static void init_ipi_lock(void); | 114 | static void init_ipi_lock(void); |
113 | static void do_boot_cpu(int); | 115 | static void do_boot_cpu(int); |
116 | int __cpu_up(unsigned int); | ||
117 | void smp_cpus_done(unsigned int); | ||
114 | 118 | ||
115 | int start_secondary(void *); | 119 | int start_secondary(void *); |
116 | static void smp_callin(void); | 120 | static void smp_callin(void); |
@@ -127,7 +131,7 @@ static void unmap_cpu_to_physid(int, int); | |||
127 | /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ | 131 | /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ |
128 | /* Boot up APs Routines : BSP */ | 132 | /* Boot up APs Routines : BSP */ |
129 | /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ | 133 | /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ |
130 | void smp_prepare_boot_cpu(void) | 134 | void __devinit smp_prepare_boot_cpu(void) |
131 | { | 135 | { |
132 | bsp_phys_id = hard_smp_processor_id(); | 136 | bsp_phys_id = hard_smp_processor_id(); |
133 | physid_set(bsp_phys_id, phys_cpu_present_map); | 137 | physid_set(bsp_phys_id, phys_cpu_present_map); |
@@ -343,7 +347,7 @@ static void __init do_boot_cpu(int phys_id) | |||
343 | } | 347 | } |
344 | } | 348 | } |
345 | 349 | ||
346 | int __cpuinit __cpu_up(unsigned int cpu_id, struct task_struct *tidle) | 350 | int __cpuinit __cpu_up(unsigned int cpu_id) |
347 | { | 351 | { |
348 | int timeout; | 352 | int timeout; |
349 | 353 | ||
diff --git a/arch/m32r/kernel/sys_m32r.c b/arch/m32r/kernel/sys_m32r.c index c3fdd632fba..d841fb6cc70 100644 --- a/arch/m32r/kernel/sys_m32r.c +++ b/arch/m32r/kernel/sys_m32r.c | |||
@@ -88,3 +88,24 @@ asmlinkage int sys_cachectl(char *addr, int nbytes, int op) | |||
88 | /* Not implemented yet. */ | 88 | /* Not implemented yet. */ |
89 | return -ENOSYS; | 89 | return -ENOSYS; |
90 | } | 90 | } |
91 | |||
92 | /* | ||
93 | * Do a system call from kernel instead of calling sys_execve so we | ||
94 | * end up with proper pt_regs. | ||
95 | */ | ||
96 | int kernel_execve(const char *filename, | ||
97 | const char *const argv[], | ||
98 | const char *const envp[]) | ||
99 | { | ||
100 | register long __scno __asm__ ("r7") = __NR_execve; | ||
101 | register long __arg3 __asm__ ("r2") = (long)(envp); | ||
102 | register long __arg2 __asm__ ("r1") = (long)(argv); | ||
103 | register long __res __asm__ ("r0") = (long)(filename); | ||
104 | __asm__ __volatile__ ( | ||
105 | "trap #" SYSCALL_VECTOR "|| nop" | ||
106 | : "=r" (__res) | ||
107 | : "r" (__scno), "0" (__res), "r" (__arg2), | ||
108 | "r" (__arg3) | ||
109 | : "memory"); | ||
110 | return __res; | ||
111 | } | ||
diff --git a/arch/m32r/kernel/traps.c b/arch/m32r/kernel/traps.c index 3bcb207e5b6..ee6a9199561 100644 --- a/arch/m32r/kernel/traps.c +++ b/arch/m32r/kernel/traps.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <asm/page.h> | 18 | #include <asm/page.h> |
19 | #include <asm/processor.h> | 19 | #include <asm/processor.h> |
20 | 20 | ||
21 | #include <asm/system.h> | ||
21 | #include <asm/uaccess.h> | 22 | #include <asm/uaccess.h> |
22 | #include <asm/io.h> | 23 | #include <asm/io.h> |
23 | #include <linux/atomic.h> | 24 | #include <linux/atomic.h> |