]> git.proxmox.com Git - qemu.git/commitdiff
linux-user: Clean up handling of clone() argument order
authorPeter Maydell <peter.maydell@linaro.org>
Tue, 16 Jul 2013 17:44:57 +0000 (18:44 +0100)
committerRiku Voipio <riku.voipio@linaro.org>
Mon, 22 Jul 2013 18:54:36 +0000 (21:54 +0300)
Linux manages to have three separate orderings of the arguments to
the clone() syscall on different architectures. In the kernel these
are selected via CONFIG_CLONE_BACKWARDS and CONFIG_CLONE_BACKWARDS2.
Clean up our implementation of this to use similar #define names
rather than a TARGET_* ifdef ladder.

This includes behaviour changes fixing bugs on cris, x86-64, m68k,
openrisc and unicore32.  cris had explicit but wrong handling; the
others were just incorrectly using QEMU's default, which happened
to be the equivalent of CONFIG_CLONE_BACKWARDS. (unicore32 appears
to be broken in the mainline kernel in that it tries to use arg3 for
both parent_tidptr and newtls simultaneously -- we don't attempt
to emulate this bug...)

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
linux-user/arm/syscall.h
linux-user/cris/syscall.h
linux-user/i386/syscall.h
linux-user/microblaze/syscall.h
linux-user/mips/syscall.h
linux-user/mips64/syscall.h
linux-user/ppc/syscall.h
linux-user/s390x/syscall.h
linux-user/sparc/syscall.h
linux-user/sparc64/syscall.h
linux-user/syscall.c

index 003d42470172115cd48e9f944fc448fe77d8bc41..73f29314f68677f45d5ca371cf4d58b016a2847c 100644 (file)
@@ -40,3 +40,5 @@ struct target_pt_regs {
 #else
 #define UNAME_MACHINE "armv5tel"
 #endif
+
+#define TARGET_CLONE_BACKWARDS
index 50e50b4f3f242fb504abf111131ceac2218957fa..832ee64bd83efb0fa77b7cf0e0335cb589c64d4f 100644 (file)
@@ -38,4 +38,6 @@ struct target_pt_regs {
         unsigned long eda;
 };
 
+#define TARGET_CLONE_BACKWARDS2
+
 #endif
index 266e2c4c83f22756e51fdd5c2a6cce22c527cff0..12b8c3b672999da280f5f1ac54aeeec136c8df76 100644 (file)
@@ -144,3 +144,5 @@ struct target_vm86plus_struct {
 };
 
 #define UNAME_MACHINE "i686"
+
+#define TARGET_CLONE_BACKWARDS
index c3e5c55b3d4d468962dd9732472f6bc8ee4fd3d0..d550989d5e495485415e824b93f330343b7889fc 100644 (file)
@@ -48,4 +48,6 @@ struct target_pt_regs {
         uint32_t kernel_mode;
 };
 
+#define TARGET_CLONE_BACKWARDS
+
 #endif
index 3deb862cc4f636a96913f5157b25864fa7fadac0..9d437d918bdd128c566cbf26976f8543d1f55cbb 100644 (file)
@@ -225,3 +225,5 @@ struct target_pt_regs {
 #define TARGET_QEMU_ESIGRETURN 255
 
 #define UNAME_MACHINE "mips"
+
+#define TARGET_CLONE_BACKWARDS
index cd707df32f346a3e1de7c6be25774283456eac28..1710f766e26b09d7ee81cef420ce01feb4d0e0f4 100644 (file)
@@ -222,3 +222,5 @@ struct target_pt_regs {
 #define TARGET_QEMU_ESIGRETURN 255
 
 #define UNAME_MACHINE "mips64"
+
+#define TARGET_CLONE_BACKWARDS
index 481047b2dd6d3430cf96c40acf9cd55d96a5c5a8..ba36acbc337b677770a925b9215caf8b808d5e02 100644 (file)
@@ -62,3 +62,5 @@ struct target_revectored_struct {
 #else
 #define UNAME_MACHINE "ppc"
 #endif
+
+#define TARGET_CLONE_BACKWARDS
index e4603b79c3d47f986633d7cc2703ccd141e20d1b..ea8c30484052a9367d504db9359d6926726ddf9c 100644 (file)
@@ -21,3 +21,5 @@ struct target_pt_regs {
 };
 
 #define UNAME_MACHINE "s390x"
+
+#define TARGET_CLONE_BACKWARDS
index 5a9bb7e546983201b106d47d3c74571d21dd9c1b..4cd64bf41dd2d96b02f3324627769b7dc27e029f 100644 (file)
@@ -7,3 +7,10 @@ struct target_pt_regs {
 };
 
 #define UNAME_MACHINE "sun4"
+
+/* SPARC kernels don't define this in their Kconfig, but they have the
+ * same ABI as if they did, implemented by sparc-specific code which fishes
+ * directly in the u_regs() struct for half the parameters in sparc_do_fork()
+ * and copy_thread().
+ */
+#define TARGET_CLONE_BACKWARDS
index 81a816de94a37da75145b57e7a9e626ec285ffc5..e60bf311c02e1d9817f61364f0f9312dbf2f56d1 100644 (file)
@@ -8,3 +8,10 @@ struct target_pt_regs {
 };
 
 #define UNAME_MACHINE "sun4u"
+
+/* SPARC kernels don't define this in their Kconfig, but they have the
+ * same ABI as if they did, implemented by sparc-specific code which fishes
+ * directly in the u_regs() struct for half the parameters in sparc_do_fork()
+ * and copy_thread().
+ */
+#define TARGET_CLONE_BACKWARDS
index 642d0a362072ad73e859ae2cf01d7b64e872e495..b167d7f3aeddf0c979bac698776c7477e2d0d588 100644 (file)
@@ -6956,16 +6956,20 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         ret = get_errno(fsync(arg1));
         break;
     case TARGET_NR_clone:
-#if defined(TARGET_SH4) || defined(TARGET_ALPHA)
-        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4));
-#elif defined(TARGET_CRIS)
-        ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg4, arg5));
-#elif defined(TARGET_MICROBLAZE)
+        /* Linux manages to have three different orderings for its
+         * arguments to clone(); the BACKWARDS and BACKWARDS2 defines
+         * match the kernel's CONFIG_CLONE_* settings.
+         * Microblaze is further special in that it uses a sixth
+         * implicit argument to clone for the TLS pointer.
+         */
+#if defined(TARGET_MICROBLAZE)
         ret = get_errno(do_fork(cpu_env, arg1, arg2, arg4, arg6, arg5));
-#elif defined(TARGET_S390X)
+#elif defined(TARGET_CLONE_BACKWARDS)
+        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5));
+#elif defined(TARGET_CLONE_BACKWARDS2)
         ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg5, arg4));
 #else
-        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5));
+        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4));
 #endif
         break;
 #ifdef __NR_exit_group