--- zzzz-none-000/linux-3.10.107/arch/h8300/kernel/process.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/arch/h8300/kernel/process.c 2021-02-04 17:41:59.000000000 +0000 @@ -52,46 +52,46 @@ /* * The idle loop on an H8/300.. */ -#if !defined(CONFIG_H8300H_SIM) && !defined(CONFIG_H8S_SIM) void arch_cpu_idle(void) { local_irq_enable(); - /* XXX: race here! What if need_resched() gets set now? */ __asm__("sleep"); } -#endif -void machine_restart(char * __unused) +void machine_restart(char *__unused) { local_irq_disable(); - __asm__("jmp @@0"); + __asm__("jmp @@0"); } void machine_halt(void) { local_irq_disable(); __asm__("sleep"); - for (;;); + for (;;) + ; } void machine_power_off(void) { local_irq_disable(); __asm__("sleep"); - for (;;); + for (;;) + ; } -void show_regs(struct pt_regs * regs) +void show_regs(struct pt_regs *regs) { show_regs_print_info(KERN_DEFAULT); - printk("\nPC: %08lx Status: %02x", + pr_notice("\n"); + pr_notice("PC: %08lx Status: %02x\n", regs->pc, regs->ccr); - printk("\nORIG_ER0: %08lx ER0: %08lx ER1: %08lx", + pr_notice("ORIG_ER0: %08lx ER0: %08lx ER1: %08lx\n", regs->orig_er0, regs->er0, regs->er1); - printk("\nER2: %08lx ER3: %08lx ER4: %08lx ER5: %08lx", + pr_notice("ER2: %08lx ER3: %08lx ER4: %08lx ER5: %08lx\n", regs->er2, regs->er3, regs->er4, regs->er5); - printk("\nER6' %08lx ",regs->er6); + pr_notice("ER6' %08lx ", regs->er6); if (user_mode(regs)) printk("USP: %08lx\n", rdusp()); else @@ -103,10 +103,10 @@ } int copy_thread(unsigned long clone_flags, - unsigned long usp, unsigned long topstk, - struct task_struct * p) + unsigned long usp, unsigned long topstk, + struct task_struct *p) { - struct pt_regs * childregs; + struct pt_regs *childregs; childregs = (struct pt_regs *) (THREAD_SIZE + task_stack_page(p)) - 1; @@ -115,12 +115,12 @@ childregs->retpc = (unsigned long) ret_from_kernel_thread; childregs->er4 = topstk; /* arg */ childregs->er5 = usp; /* fn */ - p->thread.ksp = (unsigned long)childregs; + } else { + *childregs = *current_pt_regs(); + childregs->er0 = 0; + childregs->retpc = (unsigned long) ret_from_fork; + p->thread.usp = usp ?: rdusp(); } - *childregs = *current_pt_regs(); - childregs->retpc = (unsigned long) ret_from_fork; - childregs->er0 = 0; - p->thread.usp = usp ?: rdusp(); p->thread.ksp = (unsigned long)childregs; return 0; @@ -136,6 +136,7 @@ unsigned long fp, pc; unsigned long stack_page; int count = 0; + if (!p || p == current || p->state == TASK_RUNNING) return 0; @@ -152,3 +153,19 @@ } while (count++ < 16); return 0; } + +/* generic sys_clone is not enough registers */ +asmlinkage int sys_clone(unsigned long __user *args) +{ + unsigned long clone_flags; + unsigned long newsp; + uintptr_t parent_tidptr; + uintptr_t child_tidptr; + + get_user(clone_flags, &args[0]); + get_user(newsp, &args[1]); + get_user(parent_tidptr, &args[2]); + get_user(child_tidptr, &args[3]); + return do_fork(clone_flags, newsp, 0, + (int __user *)parent_tidptr, (int __user *)child_tidptr); +}