struct stub_data {
        unsigned long offset;
        int fd;
-       long err;
+       long parent_err, child_err;
 };
 
 #endif
 
 void __attribute__ ((__section__ (".__syscall_stub")))
 stub_clone_handler(void)
 {
-       struct stub_data *data = (struct stub_data *) STUB_DATA;
+       int stack;
+       struct stub_data *data = (void *) ((unsigned long)&stack & ~(UM_KERN_PAGE_SIZE - 1));
        long err;
 
        err = stub_syscall2(__NR_clone, CLONE_PARENT | CLONE_FILES | SIGCHLD,
-                           STUB_DATA + UM_KERN_PAGE_SIZE / 2 - sizeof(void *));
-       if (err != 0)
-               goto out;
+                           (unsigned long)data + UM_KERN_PAGE_SIZE / 2 - sizeof(void *));
+       if (err) {
+               data->parent_err = err;
+               goto done;
+       }
 
        err = stub_syscall4(__NR_ptrace, PTRACE_TRACEME, 0, 0, 0);
-       if (err)
-               goto out;
+       if (err) {
+               data->child_err = err;
+               goto done;
+       }
 
        remap_stack(data->fd, data->offset);
        goto done;
 
- out:
-       /*
-        * save current result.
-        * Parent: pid;
-        * child: retcode of mmap already saved and it jumps around this
-        * assignment
-        */
-       data->err = err;
  done:
        trap_myself();
 }
 
         * and child's mmap2 calls
         */
        *data = ((struct stub_data) {
-                       .offset = MMAP_OFFSET(new_offset),
-                       .fd     = new_fd
+               .offset = MMAP_OFFSET(new_offset),
+               .fd     = new_fd,
+               .parent_err = -ESRCH,
+               .child_err = 0,
+       });
+
+       *child_data = ((struct stub_data) {
+               .child_err = -ESRCH,
        });
 
        err = ptrace_setregs(pid, thread_regs);
                return err;
        }
 
-       /* set a well known return code for detection of child write failure */
-       child_data->err = 12345678;
-
        /*
         * Wait, until parent has finished its work: read child's pid from
         * parent's stack, and check, if bad result.
 
        wait_stub_done(pid);
 
-       pid = data->err;
+       pid = data->parent_err;
        if (pid < 0) {
                printk(UM_KERN_ERR "copy_context_skas0 - stub-parent reports "
                       "error %d\n", -pid);
         * child's stack and check it.
         */
        wait_stub_done(pid);
-       if (child_data->err != STUB_DATA) {
-               printk(UM_KERN_ERR "copy_context_skas0 - stub-child reports "
-                      "error %ld\n", child_data->err);
-               err = child_data->err;
+       if (child_data->child_err != STUB_DATA) {
+               printk(UM_KERN_ERR "copy_context_skas0 - stub-child %d reports "
+                      "error %ld\n", pid, data->child_err);
+               err = data->child_err;
                goto out_kill;
        }
 
 
                            "d" (PROT_READ | PROT_WRITE),
                            "S" (MAP_FIXED | MAP_SHARED), "D" (fd),
                            "a" (offset),
-                           "i" (&((struct stub_data *) STUB_DATA)->err)
+                           "i" (&((struct stub_data *) STUB_DATA)->child_err)
                          : "memory");
 }
 
 
                            "d" (PROT_READ | PROT_WRITE),
                             "g" (MAP_FIXED | MAP_SHARED), "g" (fd),
                            "g" (offset),
-                           "i" (&((struct stub_data *) STUB_DATA)->err)
+                           "i" (&((struct stub_data *) STUB_DATA)->child_err)
                          : __syscall_clobber, "r10", "r8", "r9" );
 }