]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] CLONE_SETTLS, CLONE_SETTID, 2.5.31-BK
authorIngo Molnar <mingo@elte.hu>
Tue, 13 Aug 2002 07:36:16 +0000 (00:36 -0700)
committerLinus Torvalds <torvalds@home.transmeta.com>
Tue, 13 Aug 2002 07:36:16 +0000 (00:36 -0700)
This adds two new clone() flags:

    CLONE_SETTLS => if present then the third clone() syscall parameter
                    is the new TLS.

    CLONE_SETTID => if present then the child TID is written to the
                    address specified by the fourth clone() parameter.

the new parameters are handled in a safe way, clone() returns -EFAULT or
-EINVAL if there's some problem with them.

arch/i386/kernel/process.c
include/linux/sched.h

index b5c74b80769d0e10d3f6120b3db408afac4ae055..fdcd260eba588fe8c434b5a58a0771718db5f412 100644 (file)
@@ -579,6 +579,35 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
        unlazy_fpu(tsk);
        struct_cpy(&p->thread.i387, &tsk->thread.i387);
 
+       /*
+        * Set a new TLS for the child thread?
+        */
+       if (clone_flags & CLONE_SETTLS) {
+               struct desc_struct *desc;
+               struct user_desc info;
+               int idx;
+
+               if (copy_from_user(&info, (void *)childregs->esi, sizeof(info)))
+                       return -EFAULT;
+               if (LDT_empty(&info))
+                       return -EINVAL;
+
+               idx = info.entry_number;
+               if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
+                       return -EINVAL;
+
+               desc = p->thread.tls_array + idx - GDT_ENTRY_TLS_MIN;
+               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;
+
        if (unlikely(NULL != tsk->thread.ts_io_bitmap)) {
                p->thread.ts_io_bitmap = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL);
                if (!p->thread.ts_io_bitmap)
index 7adc9c6278b70ba0002123272bb2cf51f5a59e10..d44342a05d5bc6779e5d4d12e6a156bee4dc010a 100644 (file)
@@ -45,6 +45,8 @@ struct exec_domain;
 #define CLONE_THREAD   0x00010000      /* Same thread group? */
 #define CLONE_NEWNS    0x00020000      /* New namespace group? */
 #define CLONE_SYSVSEM  0x00040000      /* share system V SEM_UNDO semantics */
+#define CLONE_SETTLS   0x00080000      /* create a new TLS for the child */
+#define CLONE_SETTID   0x00100000      /* write the TID back to userspace */
 
 #define CLONE_SIGNAL   (CLONE_SIGHAND | CLONE_THREAD)