summaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/process.c
diff options
context:
space:
mode:
authorLachlan McIlroy <lachlan@redback.melbourne.sgi.com>2008-05-19 15:09:05 +1000
committerLachlan McIlroy <lachlan@redback.melbourne.sgi.com>2008-05-19 15:09:05 +1000
commitc203e45f069af47ca7623e4dcd8c00bfba2722e4 (patch)
tree4563115b6565dcfd97015c1c9366fb3d07cabf19 /arch/sparc64/kernel/process.c
parenta94477da38e0b261a7ecea71f4c95a3bcd5be69c (diff)
parentb8291ad07a7f3b5b990900f0001198ac23ba893e (diff)
downloadblackbird-op-linux-c203e45f069af47ca7623e4dcd8c00bfba2722e4.tar.gz
blackbird-op-linux-c203e45f069af47ca7623e4dcd8c00bfba2722e4.zip
Merge git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6 into for-linus
Diffstat (limited to 'arch/sparc64/kernel/process.c')
-rw-r--r--arch/sparc64/kernel/process.c24
1 files changed, 15 insertions, 9 deletions
diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c
index 056013749157..4129c0449856 100644
--- a/arch/sparc64/kernel/process.c
+++ b/arch/sparc64/kernel/process.c
@@ -503,6 +503,8 @@ asmlinkage long sparc_do_fork(unsigned long clone_flags,
unsigned long stack_size)
{
int __user *parent_tid_ptr, *child_tid_ptr;
+ unsigned long orig_i1 = regs->u_regs[UREG_I1];
+ long ret;
#ifdef CONFIG_COMPAT
if (test_thread_flag(TIF_32BIT)) {
@@ -515,9 +517,19 @@ asmlinkage long sparc_do_fork(unsigned long clone_flags,
child_tid_ptr = (int __user *) regs->u_regs[UREG_I4];
}
- return do_fork(clone_flags, stack_start,
- regs, stack_size,
- parent_tid_ptr, child_tid_ptr);
+ ret = do_fork(clone_flags, stack_start,
+ regs, stack_size,
+ parent_tid_ptr, child_tid_ptr);
+
+ /* If we get an error and potentially restart the system
+ * call, we're screwed because copy_thread() clobbered
+ * the parent's %o1. So detect that case and restore it
+ * here.
+ */
+ if ((unsigned long)ret >= -ERESTART_RESTARTBLOCK)
+ regs->u_regs[UREG_I1] = orig_i1;
+
+ return ret;
}
/* Copy a Sparc thread. The fork() return value conventions
@@ -591,12 +603,6 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
if (clone_flags & CLONE_SETTLS)
t->kregs->u_regs[UREG_G7] = regs->u_regs[UREG_I3];
- /* We do not want to accidently trigger system call restart
- * handling in the new thread. Therefore, clear out the trap
- * type, which will make pt_regs_regs_is_syscall() return false.
- */
- pt_regs_clear_trap_type(t->kregs);
-
return 0;
}
OpenPOWER on IntegriCloud