summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurent Vivier <laurent@vivier.eu>2016-07-08 01:17:27 +0200
committerRiku Voipio <riku.voipio@linaro.org>2016-09-22 07:24:21 +0300
commit5457dc9e37fe0a29989bd64306c63941074864ce (patch)
tree500f40acbc2b3e2e4401a037447d93904856c522
parent45eafb4d32ced9ff1dcb3800c89f8beaf47b61cc (diff)
downloadqemu-5457dc9e37fe0a29989bd64306c63941074864ce.tar.gz
linux-user: fix TARGET_NR_select
TARGET_NR_select can have three different implementations: 1- to always return -ENOSYS microblaze, ppc, ppc64 -> TARGET_WANT_NI_OLD_SELECT 2- to take parameters from a structure pointed by arg1 (kernel sys_old_select) i386, arm, m68k -> TARGET_WANT_OLD_SYS_SELECT 3- to take parameters from arg[1-5] (kernel sys_select) x86_64, alpha, s390x, cris, sparc, sparc64 Some (new) architectures don't define NR_select, 4- but only NR__newselect with sys_select: mips, mips64, sh 5- don't define NR__newselect, and use pselect6 syscall: aarch64, openrisc, tilegx, unicore32 Reported-by: Timothy Pearson <tpearson@raptorengineering.com> Reported-by: Allan Wirth <awirth@akamai.com> Suggested-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Laurent Vivier <laurent@vivier.eu> Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
-rw-r--r--linux-user/arm/target_syscall.h1
-rw-r--r--linux-user/i386/target_syscall.h1
-rw-r--r--linux-user/m68k/target_syscall.h2
-rw-r--r--linux-user/microblaze/target_syscall.h2
-rw-r--r--linux-user/openrisc/syscall_nr.h2
-rw-r--r--linux-user/ppc/target_syscall.h1
-rw-r--r--linux-user/sh4/syscall_nr.h2
-rw-r--r--linux-user/syscall.c48
-rw-r--r--linux-user/tilegx/syscall_nr.h1
9 files changed, 39 insertions, 21 deletions
diff --git a/linux-user/arm/target_syscall.h b/linux-user/arm/target_syscall.h
index 0879b4d4a8..94e2a42cb2 100644
--- a/linux-user/arm/target_syscall.h
+++ b/linux-user/arm/target_syscall.h
@@ -32,6 +32,7 @@ struct target_pt_regs {
#define TARGET_MINSIGSTKSZ 2048
#define TARGET_MLOCKALL_MCL_CURRENT 1
#define TARGET_MLOCKALL_MCL_FUTURE 2
+#define TARGET_WANT_OLD_SYS_SELECT
#define TARGET_FORCE_SHMLBA
diff --git a/linux-user/i386/target_syscall.h b/linux-user/i386/target_syscall.h
index b4e895fd9c..2854758134 100644
--- a/linux-user/i386/target_syscall.h
+++ b/linux-user/i386/target_syscall.h
@@ -153,5 +153,6 @@ struct target_vm86plus_struct {
#define TARGET_MINSIGSTKSZ 2048
#define TARGET_MLOCKALL_MCL_CURRENT 1
#define TARGET_MLOCKALL_MCL_FUTURE 2
+#define TARGET_WANT_OLD_SYS_SELECT
#endif /* I386_TARGET_SYSCALL_H */
diff --git a/linux-user/m68k/target_syscall.h b/linux-user/m68k/target_syscall.h
index db2be4f101..632ee4fcf8 100644
--- a/linux-user/m68k/target_syscall.h
+++ b/linux-user/m68k/target_syscall.h
@@ -24,6 +24,8 @@ struct target_pt_regs {
#define TARGET_MLOCKALL_MCL_CURRENT 1
#define TARGET_MLOCKALL_MCL_FUTURE 2
+#define TARGET_WANT_OLD_SYS_SELECT
+
void do_m68k_simcall(CPUM68KState *, int);
#endif /* M68K_TARGET_SYSCALL_H */
diff --git a/linux-user/microblaze/target_syscall.h b/linux-user/microblaze/target_syscall.h
index 0b6980c899..4141cbaa5e 100644
--- a/linux-user/microblaze/target_syscall.h
+++ b/linux-user/microblaze/target_syscall.h
@@ -53,4 +53,6 @@ struct target_pt_regs {
#define TARGET_MLOCKALL_MCL_CURRENT 1
#define TARGET_MLOCKALL_MCL_FUTURE 2
+#define TARGET_WANT_NI_OLD_SELECT
+
#endif
diff --git a/linux-user/openrisc/syscall_nr.h b/linux-user/openrisc/syscall_nr.h
index 6b1c7d265e..04059d020c 100644
--- a/linux-user/openrisc/syscall_nr.h
+++ b/linux-user/openrisc/syscall_nr.h
@@ -459,8 +459,6 @@
#define TARGET_NR_getdents 1065
#define __ARCH_WANT_SYS_GETDENTS
#define TARGET_NR_futimesat 1066
-#define TARGET_NR_select 1067
-#define __ARCH_WANT_SYS_SELECT
#define TARGET_NR_poll 1068
#define TARGET_NR_epoll_wait 1069
#define TARGET_NR_ustat 1070
diff --git a/linux-user/ppc/target_syscall.h b/linux-user/ppc/target_syscall.h
index a8662f4856..afc0570410 100644
--- a/linux-user/ppc/target_syscall.h
+++ b/linux-user/ppc/target_syscall.h
@@ -74,5 +74,6 @@ struct target_revectored_struct {
#define TARGET_MINSIGSTKSZ 2048
#define TARGET_MLOCKALL_MCL_CURRENT 0x2000
#define TARGET_MLOCKALL_MCL_FUTURE 0x4000
+#define TARGET_WANT_NI_OLD_SELECT
#endif /* PPC_TARGET_SYSCALL_H */
diff --git a/linux-user/sh4/syscall_nr.h b/linux-user/sh4/syscall_nr.h
index 50099846d2..e99f73589d 100644
--- a/linux-user/sh4/syscall_nr.h
+++ b/linux-user/sh4/syscall_nr.h
@@ -84,7 +84,7 @@
#define TARGET_NR_settimeofday 79
#define TARGET_NR_getgroups 80
#define TARGET_NR_setgroups 81
-#define TARGET_NR_select 82
+ /* 82 was sys_oldselect */
#define TARGET_NR_symlink 83
#define TARGET_NR_oldlstat 84
#define TARGET_NR_readlink 85
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index d7e4d9ff2f..7aa2c1d720 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -1444,6 +1444,29 @@ static abi_long do_select(int n,
return ret;
}
+
+#if defined(TARGET_WANT_OLD_SYS_SELECT)
+static abi_long do_old_select(abi_ulong arg1)
+{
+ struct target_sel_arg_struct *sel;
+ abi_ulong inp, outp, exp, tvp;
+ long nsel;
+
+ if (!lock_user_struct(VERIFY_READ, sel, arg1, 1)) {
+ return -TARGET_EFAULT;
+ }
+
+ nsel = tswapal(sel->n);
+ inp = tswapal(sel->inp);
+ outp = tswapal(sel->outp);
+ exp = tswapal(sel->exp);
+ tvp = tswapal(sel->tvp);
+
+ unlock_user_struct(sel, arg1, 0);
+
+ return do_select(nsel, inp, outp, exp, tvp);
+}
+#endif
#endif
static abi_long do_pipe2(int host_pipe[], int flags)
@@ -8668,24 +8691,15 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
break;
#if defined(TARGET_NR_select)
case TARGET_NR_select:
-#if defined(TARGET_S390X) || defined(TARGET_ALPHA)
- ret = do_select(arg1, arg2, arg3, arg4, arg5);
+#if defined(TARGET_WANT_NI_OLD_SELECT)
+ /* some architectures used to have old_select here
+ * but now ENOSYS it.
+ */
+ ret = -TARGET_ENOSYS;
+#elif defined(TARGET_WANT_OLD_SYS_SELECT)
+ ret = do_old_select(arg1);
#else
- {
- struct target_sel_arg_struct *sel;
- abi_ulong inp, outp, exp, tvp;
- long nsel;
-
- if (!lock_user_struct(VERIFY_READ, sel, arg1, 1))
- goto efault;
- nsel = tswapal(sel->n);
- inp = tswapal(sel->inp);
- outp = tswapal(sel->outp);
- exp = tswapal(sel->exp);
- tvp = tswapal(sel->tvp);
- unlock_user_struct(sel, arg1, 0);
- ret = do_select(nsel, inp, outp, exp, tvp);
- }
+ ret = do_select(arg1, arg2, arg3, arg4, arg5);
#endif
break;
#endif
diff --git a/linux-user/tilegx/syscall_nr.h b/linux-user/tilegx/syscall_nr.h
index 8e30cd1ae9..c104b94230 100644
--- a/linux-user/tilegx/syscall_nr.h
+++ b/linux-user/tilegx/syscall_nr.h
@@ -311,7 +311,6 @@
#define TARGET_NR_creat 1064
#define TARGET_NR_getdents 1065
#define TARGET_NR_futimesat 1066
-#define TARGET_NR_select 1067
#define TARGET_NR_poll 1068
#define TARGET_NR_epoll_wait 1069
#define TARGET_NR_ustat 1070