]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
raw_syscalls: lxc_raw_clone() 2940/head
authorChristian Brauner <christian.brauner@ubuntu.com>
Tue, 16 Apr 2019 21:32:03 +0000 (23:32 +0200)
committerChristian Brauner <christian.brauner@ubuntu.com>
Tue, 16 Apr 2019 21:35:26 +0000 (23:35 +0200)
Account for different trap number on 32bit SPARC.

Link: https://bugs.gentoo.org/656368
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
src/lxc/raw_syscalls.c

index 4ac51ac253eb63ddd0240b00497c3802c66a95da..a4db3069196c193397cd0ed2d46b5526190426c5 100644 (file)
@@ -47,7 +47,7 @@ pid_t lxc_raw_clone(unsigned long flags)
        /* On s390/s390x and cris the order of the first and second arguments
         * of the system call is reversed.
         */
-       return (int)syscall(__NR_clone, NULL, flags | SIGCHLD);
+       return syscall(__NR_clone, NULL, flags | SIGCHLD);
 #elif defined(__sparc__) && defined(__arch64__)
        {
                /*
@@ -55,28 +55,38 @@ pid_t lxc_raw_clone(unsigned long flags)
                 * boolean flag whether this is the child or the parent in %o1.
                 * Inline assembly is needed to get the flag returned in %o1.
                 */
-               int in_child;
-               int child_pid;
-               asm volatile("mov %2, %%g1\n\t"
-                            "mov %3, %%o0\n\t"
-                            "mov 0 , %%o1\n\t"
-                            "t 0x6d\n\t"
-                            "mov %%o1, %0\n\t"
-                            "mov %%o0, %1"
-                            : "=r"(in_child), "=r"(child_pid)
-                            : "i"(__NR_clone), "r"(flags | SIGCHLD)
-                            : "%o1", "%o0", "%g1");
+               int child_pid, in_child, ret;
+
+                asm volatile("mov %3, %%g1\n\t"
+                             "mov %4, %%o0\n\t"
+                             "mov 0 , %%o1\n\t"
+#if defined(__arch64__)
+                             "t 0x6d\n\t"
+#else
+                             "t 0x10\n\t"
+#endif
+                             "addx %%g0, 0, %2\n\t"
+                             "mov %%o1, %0\n\t"
+                             "mov %%o0, %1" :
+                             "=r"(in_child), "=r"(child_pid), "=r"(ret) :
+                             "i"(__NR_clone), "r"(flags | SIGCHLD) :
+                             "%o1", "%o0", "%g1", "cc" );
+
+               if (ret) {
+                       errno = child_pid;
+                       return -1;
+               }
 
                if (in_child)
                        return 0;
-               else
-                       return child_pid;
+
+               return child_pid;
        }
 #elif defined(__ia64__)
        /* On ia64 the stack and stack size are passed as separate arguments. */
-       return (int)syscall(__NR_clone, flags | SIGCHLD, NULL, prctl_arg(0));
+       return syscall(__NR_clone, flags | SIGCHLD, NULL, prctl_arg(0));
 #else
-       return (int)syscall(__NR_clone, flags | SIGCHLD, NULL);
+       return syscall(__NR_clone, flags | SIGCHLD, NULL);
 #endif
 }