mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-04 00:03:54 -06:00
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>
This commit is contained in:
parent
45eafb4d32
commit
5457dc9e37
9 changed files with 39 additions and 21 deletions
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue