aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/process.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel/process.c')
-rw-r--r--arch/powerpc/kernel/process.c41
1 files changed, 9 insertions, 32 deletions
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index ba48233500f6..f6d244db9203 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -745,25 +745,24 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
745 /* Copy registers */ 745 /* Copy registers */
746 sp -= sizeof(struct pt_regs); 746 sp -= sizeof(struct pt_regs);
747 childregs = (struct pt_regs *) sp; 747 childregs = (struct pt_regs *) sp;
748 if (!regs) { 748 if (unlikely(p->flags & PF_KTHREAD)) {
749 /* for kernel thread, set `current' and stackptr in new task */ 749 struct thread_info *ti = (void *)task_stack_page(p);
750 memset(childregs, 0, sizeof(struct pt_regs)); 750 memset(childregs, 0, sizeof(struct pt_regs));
751 childregs->gpr[1] = sp + sizeof(struct pt_regs); 751 childregs->gpr[1] = sp + sizeof(struct pt_regs);
752 childregs->gpr[14] = usp; /* function */
752#ifdef CONFIG_PPC64 753#ifdef CONFIG_PPC64
753 childregs->gpr[14] = *(unsigned long *)usp;
754 childregs->gpr[2] = ((unsigned long *)usp)[1],
755 clear_tsk_thread_flag(p, TIF_32BIT); 754 clear_tsk_thread_flag(p, TIF_32BIT);
756#else 755 childregs->softe = 1;
757 childregs->gpr[14] = usp; /* function */
758 childregs->gpr[2] = (unsigned long) p;
759#endif 756#endif
760 childregs->gpr[15] = arg; 757 childregs->gpr[15] = arg;
761 p->thread.regs = NULL; /* no user register state */ 758 p->thread.regs = NULL; /* no user register state */
759 ti->flags |= _TIF_RESTOREALL;
762 f = ret_from_kernel_thread; 760 f = ret_from_kernel_thread;
763 } else { 761 } else {
764 CHECK_FULL_REGS(regs); 762 CHECK_FULL_REGS(regs);
765 *childregs = *regs; 763 *childregs = *regs;
766 childregs->gpr[1] = usp; 764 if (usp)
765 childregs->gpr[1] = usp;
767 p->thread.regs = childregs; 766 p->thread.regs = childregs;
768 childregs->gpr[3] = 0; /* Result from fork() */ 767 childregs->gpr[3] = 0; /* Result from fork() */
769 if (clone_flags & CLONE_SETTLS) { 768 if (clone_flags & CLONE_SETTLS) {
@@ -1027,22 +1026,11 @@ int get_unalign_ctl(struct task_struct *tsk, unsigned long adr)
1027 return put_user(tsk->thread.align_ctl, (unsigned int __user *)adr); 1026 return put_user(tsk->thread.align_ctl, (unsigned int __user *)adr);
1028} 1027}
1029 1028
1030#define TRUNC_PTR(x) ((typeof(x))(((unsigned long)(x)) & 0xffffffff))
1031
1032int sys_clone(unsigned long clone_flags, unsigned long usp, 1029int sys_clone(unsigned long clone_flags, unsigned long usp,
1033 int __user *parent_tidp, void __user *child_threadptr, 1030 int __user *parent_tidp, void __user *child_threadptr,
1034 int __user *child_tidp, int p6, 1031 int __user *child_tidp, int p6,
1035 struct pt_regs *regs) 1032 struct pt_regs *regs)
1036{ 1033{
1037 CHECK_FULL_REGS(regs);
1038 if (usp == 0)
1039 usp = regs->gpr[1]; /* stack pointer for child */
1040#ifdef CONFIG_PPC64
1041 if (is_32bit_task()) {
1042 parent_tidp = TRUNC_PTR(parent_tidp);
1043 child_tidp = TRUNC_PTR(child_tidp);
1044 }
1045#endif
1046 return do_fork(clone_flags, usp, regs, 0, parent_tidp, child_tidp); 1034 return do_fork(clone_flags, usp, regs, 0, parent_tidp, child_tidp);
1047} 1035}
1048 1036
@@ -1050,28 +1038,17 @@ int sys_fork(unsigned long p1, unsigned long p2, unsigned long p3,
1050 unsigned long p4, unsigned long p5, unsigned long p6, 1038 unsigned long p4, unsigned long p5, unsigned long p6,
1051 struct pt_regs *regs) 1039 struct pt_regs *regs)
1052{ 1040{
1053 CHECK_FULL_REGS(regs); 1041 return do_fork(SIGCHLD, 0, regs, 0, NULL, NULL);
1054 return do_fork(SIGCHLD, regs->gpr[1], regs, 0, NULL, NULL);
1055} 1042}
1056 1043
1057int sys_vfork(unsigned long p1, unsigned long p2, unsigned long p3, 1044int sys_vfork(unsigned long p1, unsigned long p2, unsigned long p3,
1058 unsigned long p4, unsigned long p5, unsigned long p6, 1045 unsigned long p4, unsigned long p5, unsigned long p6,
1059 struct pt_regs *regs) 1046 struct pt_regs *regs)
1060{ 1047{
1061 CHECK_FULL_REGS(regs); 1048 return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0,
1062 return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->gpr[1],
1063 regs, 0, NULL, NULL); 1049 regs, 0, NULL, NULL);
1064} 1050}
1065 1051
1066void __ret_from_kernel_execve(struct pt_regs *normal)
1067__noreturn;
1068
1069void ret_from_kernel_execve(struct pt_regs *normal)
1070{
1071 set_thread_flag(TIF_RESTOREALL);
1072 __ret_from_kernel_execve(normal);
1073}
1074
1075static inline int valid_irq_stack(unsigned long sp, struct task_struct *p, 1052static inline int valid_irq_stack(unsigned long sp, struct task_struct *p,
1076 unsigned long nbytes) 1053 unsigned long nbytes)
1077{ 1054{