regs.eflags = 0x286;
/* Ok, create the new process.. */
- p = do_fork(flags | CLONE_VM, 0, ®s, 0);
+ p = do_fork(flags | CLONE_VM, 0, ®s, 0, NULL);
return IS_ERR(p) ? PTR_ERR(p) : p->pid;
}
IO_BITMAP_BYTES);
}
- /*
- * The common fastpath:
- */
- if (!(clone_flags & (CLONE_SETTLS | CLONE_SETTID | CLONE_CLEARTID)))
- return 0;
/*
* Set a new TLS for the child thread?
*/
desc->a = LDT_entry_a(&info);
desc->b = LDT_entry_b(&info);
}
-
- /*
- * Notify the child of the TID?
- */
- if (clone_flags & CLONE_SETTID)
- if (put_user(p->pid, (pid_t *)childregs->edx))
- return -EFAULT;
-
- /*
- * Does the userspace VM want the TID cleared on mm_release()?
- */
- if (clone_flags & CLONE_CLEARTID)
- p->user_tid = (int *) childregs->edx;
return 0;
}
{
struct task_struct *p;
- p = do_fork(SIGCHLD, regs.esp, ®s, 0);
+ p = do_fork(SIGCHLD, regs.esp, ®s, 0, NULL);
return IS_ERR(p) ? PTR_ERR(p) : p->pid;
}
struct task_struct *p;
unsigned long clone_flags;
unsigned long newsp;
+ int *user_tid;
clone_flags = regs.ebx;
newsp = regs.ecx;
+ user_tid = (int *)regs.edx;
if (!newsp)
newsp = regs.esp;
- p = do_fork(clone_flags & ~CLONE_IDLETASK, newsp, ®s, 0);
+ p = do_fork(clone_flags & ~CLONE_IDLETASK, newsp, ®s, 0, user_tid);
return IS_ERR(p) ? PTR_ERR(p) : p->pid;
}
{
struct task_struct *p;
- p = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.esp, ®s, 0);
+ p = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.esp, ®s, 0, NULL);
return IS_ERR(p) ? PTR_ERR(p) : p->pid;
}
* don't care about the eip and regs settings since
* we'll never reschedule the forked task.
*/
- return do_fork(CLONE_VM|CLONE_IDLETASK, 0, ®s, 0);
+ return do_fork(CLONE_VM|CLONE_IDLETASK, 0, ®s, 0, NULL);
}
/* which physical APIC ID maps to which logical CPU number */
extern task_t *child_reaper;
extern int do_execve(char *, char **, char **, struct pt_regs *);
-extern struct task_struct *do_fork(unsigned long, unsigned long, struct pt_regs *, unsigned long);
+extern struct task_struct *do_fork(unsigned long, unsigned long, struct pt_regs *, unsigned long, int *);
extern void FASTCALL(add_wait_queue(wait_queue_head_t *q, wait_queue_t * wait));
extern void FASTCALL(add_wait_queue_exclusive(wait_queue_head_t *q, wait_queue_t * wait));
static struct task_struct *copy_process(unsigned long clone_flags,
unsigned long stack_start,
struct pt_regs *regs,
- unsigned long stack_size)
+ unsigned long stack_size,
+ int *user_tid)
{
int retval;
struct task_struct *p = NULL;
retval = copy_thread(0, clone_flags, stack_start, stack_size, p, regs);
if (retval)
goto bad_fork_cleanup_namespace;
-
+ /*
+ * Notify the child of the TID?
+ */
+ retval = -EFAULT;
+ if (clone_flags & CLONE_SETTID)
+ if (put_user(p->pid, user_tid))
+ goto bad_fork_cleanup_namespace;
+
+ /*
+ * Does the userspace VM want the TID cleared on mm_release()?
+ */
+ if (clone_flags & CLONE_CLEARTID)
+ p->user_tid = user_tid;
+
/* Our parent execution domain becomes current domain
These must match for thread signalling to apply */
struct task_struct *do_fork(unsigned long clone_flags,
unsigned long stack_start,
struct pt_regs *regs,
- unsigned long stack_size)
+ unsigned long stack_size,
+ int *user_tid)
{
struct task_struct *p;
- p = copy_process(clone_flags, stack_start, regs, stack_size);
+ p = copy_process(clone_flags, stack_start, regs, stack_size, user_tid);
if (!IS_ERR(p)) {
struct completion vfork;