diff options
Diffstat (limited to 'arch/sh/kernel/process.c')
-rw-r--r-- | arch/sh/kernel/process.c | 59 |
1 files changed, 33 insertions, 26 deletions
diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c index 91516dca4a85..486c06e18033 100644 --- a/arch/sh/kernel/process.c +++ b/arch/sh/kernel/process.c | |||
@@ -105,7 +105,7 @@ void show_regs(struct pt_regs * regs) | |||
105 | { | 105 | { |
106 | printk("\n"); | 106 | printk("\n"); |
107 | printk("Pid : %d, Comm: %20s\n", current->pid, current->comm); | 107 | printk("Pid : %d, Comm: %20s\n", current->pid, current->comm); |
108 | print_symbol("PC is at %s\n", regs->pc); | 108 | print_symbol("PC is at %s\n", instruction_pointer(regs)); |
109 | printk("PC : %08lx SP : %08lx SR : %08lx ", | 109 | printk("PC : %08lx SP : %08lx SR : %08lx ", |
110 | regs->pc, regs->regs[15], regs->sr); | 110 | regs->pc, regs->regs[15], regs->sr); |
111 | #ifdef CONFIG_MMU | 111 | #ifdef CONFIG_MMU |
@@ -130,15 +130,7 @@ void show_regs(struct pt_regs * regs) | |||
130 | printk("MACH: %08lx MACL: %08lx GBR : %08lx PR : %08lx\n", | 130 | printk("MACH: %08lx MACL: %08lx GBR : %08lx PR : %08lx\n", |
131 | regs->mach, regs->macl, regs->gbr, regs->pr); | 131 | regs->mach, regs->macl, regs->gbr, regs->pr); |
132 | 132 | ||
133 | /* | 133 | show_trace(NULL, (unsigned long *)regs->regs[15], regs); |
134 | * If we're in kernel mode, dump the stack too.. | ||
135 | */ | ||
136 | if (!user_mode(regs)) { | ||
137 | extern void show_task(unsigned long *sp); | ||
138 | unsigned long sp = regs->regs[15]; | ||
139 | |||
140 | show_task((unsigned long *)sp); | ||
141 | } | ||
142 | } | 134 | } |
143 | 135 | ||
144 | /* | 136 | /* |
@@ -393,10 +385,11 @@ struct task_struct *__switch_to(struct task_struct *prev, struct task_struct *ne | |||
393 | 385 | ||
394 | asmlinkage int sys_fork(unsigned long r4, unsigned long r5, | 386 | asmlinkage int sys_fork(unsigned long r4, unsigned long r5, |
395 | unsigned long r6, unsigned long r7, | 387 | unsigned long r6, unsigned long r7, |
396 | struct pt_regs regs) | 388 | struct pt_regs __regs) |
397 | { | 389 | { |
390 | struct pt_regs *regs = RELOC_HIDE(&__regs, 0); | ||
398 | #ifdef CONFIG_MMU | 391 | #ifdef CONFIG_MMU |
399 | return do_fork(SIGCHLD, regs.regs[15], ®s, 0, NULL, NULL); | 392 | return do_fork(SIGCHLD, regs->regs[15], regs, 0, NULL, NULL); |
400 | #else | 393 | #else |
401 | /* fork almost works, enough to trick you into looking elsewhere :-( */ | 394 | /* fork almost works, enough to trick you into looking elsewhere :-( */ |
402 | return -EINVAL; | 395 | return -EINVAL; |
@@ -406,11 +399,12 @@ asmlinkage int sys_fork(unsigned long r4, unsigned long r5, | |||
406 | asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp, | 399 | asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp, |
407 | unsigned long parent_tidptr, | 400 | unsigned long parent_tidptr, |
408 | unsigned long child_tidptr, | 401 | unsigned long child_tidptr, |
409 | struct pt_regs regs) | 402 | struct pt_regs __regs) |
410 | { | 403 | { |
404 | struct pt_regs *regs = RELOC_HIDE(&__regs, 0); | ||
411 | if (!newsp) | 405 | if (!newsp) |
412 | newsp = regs.regs[15]; | 406 | newsp = regs->regs[15]; |
413 | return do_fork(clone_flags, newsp, ®s, 0, | 407 | return do_fork(clone_flags, newsp, regs, 0, |
414 | (int __user *)parent_tidptr, (int __user *)child_tidptr); | 408 | (int __user *)parent_tidptr, (int __user *)child_tidptr); |
415 | } | 409 | } |
416 | 410 | ||
@@ -426,9 +420,10 @@ asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp, | |||
426 | */ | 420 | */ |
427 | asmlinkage int sys_vfork(unsigned long r4, unsigned long r5, | 421 | asmlinkage int sys_vfork(unsigned long r4, unsigned long r5, |
428 | unsigned long r6, unsigned long r7, | 422 | unsigned long r6, unsigned long r7, |
429 | struct pt_regs regs) | 423 | struct pt_regs __regs) |
430 | { | 424 | { |
431 | return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.regs[15], ®s, | 425 | struct pt_regs *regs = RELOC_HIDE(&__regs, 0); |
426 | return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->regs[15], regs, | ||
432 | 0, NULL, NULL); | 427 | 0, NULL, NULL); |
433 | } | 428 | } |
434 | 429 | ||
@@ -437,8 +432,9 @@ asmlinkage int sys_vfork(unsigned long r4, unsigned long r5, | |||
437 | */ | 432 | */ |
438 | asmlinkage int sys_execve(char *ufilename, char **uargv, | 433 | asmlinkage int sys_execve(char *ufilename, char **uargv, |
439 | char **uenvp, unsigned long r7, | 434 | char **uenvp, unsigned long r7, |
440 | struct pt_regs regs) | 435 | struct pt_regs __regs) |
441 | { | 436 | { |
437 | struct pt_regs *regs = RELOC_HIDE(&__regs, 0); | ||
442 | int error; | 438 | int error; |
443 | char *filename; | 439 | char *filename; |
444 | 440 | ||
@@ -450,7 +446,7 @@ asmlinkage int sys_execve(char *ufilename, char **uargv, | |||
450 | error = do_execve(filename, | 446 | error = do_execve(filename, |
451 | (char __user * __user *)uargv, | 447 | (char __user * __user *)uargv, |
452 | (char __user * __user *)uenvp, | 448 | (char __user * __user *)uenvp, |
453 | ®s); | 449 | regs); |
454 | if (error == 0) { | 450 | if (error == 0) { |
455 | task_lock(current); | 451 | task_lock(current); |
456 | current->ptrace &= ~PT_DTRACE; | 452 | current->ptrace &= ~PT_DTRACE; |
@@ -474,15 +470,14 @@ unsigned long get_wchan(struct task_struct *p) | |||
474 | */ | 470 | */ |
475 | pc = thread_saved_pc(p); | 471 | pc = thread_saved_pc(p); |
476 | if (in_sched_functions(pc)) { | 472 | if (in_sched_functions(pc)) { |
477 | schedule_frame = ((unsigned long *)(long)p->thread.sp)[1]; | 473 | schedule_frame = (unsigned long)p->thread.sp; |
478 | return (unsigned long)((unsigned long *)schedule_frame)[1]; | 474 | return ((unsigned long *)schedule_frame)[21]; |
479 | } | 475 | } |
476 | |||
480 | return pc; | 477 | return pc; |
481 | } | 478 | } |
482 | 479 | ||
483 | asmlinkage void break_point_trap(unsigned long r4, unsigned long r5, | 480 | asmlinkage void break_point_trap(void) |
484 | unsigned long r6, unsigned long r7, | ||
485 | struct pt_regs regs) | ||
486 | { | 481 | { |
487 | /* Clear tracing. */ | 482 | /* Clear tracing. */ |
488 | #if defined(CONFIG_CPU_SH4A) | 483 | #if defined(CONFIG_CPU_SH4A) |
@@ -500,8 +495,20 @@ asmlinkage void break_point_trap(unsigned long r4, unsigned long r5, | |||
500 | 495 | ||
501 | asmlinkage void break_point_trap_software(unsigned long r4, unsigned long r5, | 496 | asmlinkage void break_point_trap_software(unsigned long r4, unsigned long r5, |
502 | unsigned long r6, unsigned long r7, | 497 | unsigned long r6, unsigned long r7, |
503 | struct pt_regs regs) | 498 | struct pt_regs __regs) |
504 | { | 499 | { |
505 | regs.pc -= 2; | 500 | struct pt_regs *regs = RELOC_HIDE(&__regs, 0); |
501 | |||
502 | /* Rewind */ | ||
503 | regs->pc -= 2; | ||
504 | |||
505 | #ifdef CONFIG_BUG | ||
506 | if (__kernel_text_address(instruction_pointer(regs))) { | ||
507 | u16 insn = *(u16 *)instruction_pointer(regs); | ||
508 | if (insn == TRAPA_BUG_OPCODE) | ||
509 | handle_BUG(regs); | ||
510 | } | ||
511 | #endif | ||
512 | |||
506 | force_sig(SIGTRAP, current); | 513 | force_sig(SIGTRAP, current); |
507 | } | 514 | } |