From ec00b51a6c3e6c515c52e6e4564d915ee1f19022 Mon Sep 17 00:00:00 2001 From: Dillon Amburgey Date: Wed, 2 Jan 2013 21:06:35 -0500 Subject: [PATCH 01/11] linux-user: Add Alpha socket constants Without these, some networking programs will not work Signed-off-by: Dillon Amburgey Reviewed-by: Richard Henderson Signed-off-by: Riku Voipio --- linux-user/socket.h | 69 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/linux-user/socket.h b/linux-user/socket.h index 93d47823d8..339cae5a16 100644 --- a/linux-user/socket.h +++ b/linux-user/socket.h @@ -87,6 +87,75 @@ #define TARGET_SOCK_MAX (SOCK_PACKET + 1) +#elif defined(TARGET_ALPHA) + + /* For setsockopt(2) */ + #define TARGET_SOL_SOCKET 0xffff + + #define TARGET_SO_DEBUG 0x0001 + #define TARGET_SO_REUSEADDR 0x0004 + #define TARGET_SO_KEEPALIVE 0x0008 + #define TARGET_SO_DONTROUTE 0x0010 + #define TARGET_SO_BROADCAST 0x0020 + #define TARGET_SO_LINGER 0x0080 + #define TARGET_SO_OOBINLINE 0x0100 + /* To add :#define TARGET_SO_REUSEPORT 0x0200 */ + + #define TARGET_SO_TYPE 0x1008 + #define TARGET_SO_ERROR 0x1007 + #define TARGET_SO_SNDBUF 0x1001 + #define TARGET_SO_RCVBUF 0x1002 + #define TARGET_SO_SNDBUFFORCE 0x100a + #define TARGET_SO_RCVBUFFORCE 0x100b + #define TARGET_SO_RCVLOWAT 0x1010 + #define TARGET_SO_SNDLOWAT 0x1011 + #define TARGET_SO_RCVTIMEO 0x1012 + #define TARGET_SO_SNDTIMEO 0x1013 + #define TARGET_SO_ACCEPTCONN 0x1014 + #define TARGET_SO_PROTOCOL 0x1028 + #define TARGET_SO_DOMAIN 0x1029 + + /* linux-specific, might as well be the same as on i386 */ + #define TARGET_SO_NO_CHECK 11 + #define TARGET_SO_PRIORITY 12 + #define TARGET_SO_BSDCOMPAT 14 + + #define TARGET_SO_PASSCRED 17 + #define TARGET_SO_PEERCRED 18 + #define TARGET_SO_BINDTODEVICE 25 + + /* Socket filtering */ + #define TARGET_SO_ATTACH_FILTER 26 + #define TARGET_SO_DETACH_FILTER 27 + + #define TARGET_SO_PEERNAME 28 + #define TARGET_SO_TIMESTAMP 29 + #define TARGET_SCM_TIMESTAMP TARGET_SO_TIMESTAMP + + #define TARGET_SO_PEERSEC 30 + #define TARGET_SO_PASSSEC 34 + #define TARGET_SO_TIMESTAMPNS 35 + #define TARGET_SCM_TIMESTAMPNS TARGET_SO_TIMESTAMPNS + + /* Security levels - as per NRL IPv6 - don't actually do anything */ + #define TARGET_SO_SECURITY_AUTHENTICATION 19 + #define TARGET_SO_SECURITY_ENCRYPTION_TRANSPORT 20 + #define TARGET_SO_SECURITY_ENCRYPTION_NETWORK 21 + + #define TARGET_SO_MARK 36 + + #define TARGET_SO_TIMESTAMPING 37 + #define TARGET_SCM_TIMESTAMPING TARGET_SO_TIMESTAMPING + + #define TARGET_SO_RXQ_OVFL 40 + + #define TARGET_SO_WIFI_STATUS 41 + #define TARGET_SCM_WIFI_STATUS TARGET_SO_WIFI_STATUS + #define TARGET_SO_PEEK_OFF 42 + + /* Instruct lower device to use last 4-bytes of skb data as FCS */ + #define TARGET_SO_NOFCS 43 + #else /* For setsockopt(2) */ From d95ec14fd20ff69881ab26e7ebd1dab4eb851d97 Mon Sep 17 00:00:00 2001 From: Laurent Vivier Date: Mon, 31 Dec 2012 21:00:11 +0100 Subject: [PATCH 02/11] linux-user: improve print_fcntl() Signed-off-by: Laurent Vivier Signed-off-by: Riku Voipio --- linux-user/strace.c | 97 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 79 insertions(+), 18 deletions(-) diff --git a/linux-user/strace.c b/linux-user/strace.c index 4e91a6eb9c..9a181460ec 100644 --- a/linux-user/strace.c +++ b/linux-user/strace.c @@ -462,18 +462,6 @@ UNUSED static struct flags mmap_flags[] = { FLAG_END, }; -UNUSED static struct flags fcntl_flags[] = { - FLAG_TARGET(F_DUPFD), - FLAG_TARGET(F_GETFD), - FLAG_TARGET(F_SETFD), - FLAG_TARGET(F_GETFL), - FLAG_TARGET(F_SETFL), - FLAG_TARGET(F_GETLK), - FLAG_TARGET(F_SETLK), - FLAG_TARGET(F_SETLKW), - FLAG_END, -}; - UNUSED static struct flags clone_flags[] = { FLAG_GENERIC(CLONE_VM), FLAG_GENERIC(CLONE_FS), @@ -867,12 +855,85 @@ print_fcntl(const struct syscallname *name, { print_syscall_prologue(name); print_raw_param("%d", arg0, 0); - print_flags(fcntl_flags, arg1, 0); - /* - * TODO: check flags and print following argument only - * when needed. - */ - print_pointer(arg2, 1); + switch(arg1) { + case TARGET_F_DUPFD: + gemu_log("F_DUPFD,"); + print_raw_param(TARGET_ABI_FMT_ld, arg2, 1); + break; + case TARGET_F_GETFD: + gemu_log("F_GETFD"); + break; + case TARGET_F_SETFD: + gemu_log("F_SETFD,"); + print_raw_param(TARGET_ABI_FMT_ld, arg2, 1); + break; + case TARGET_F_GETFL: + gemu_log("F_GETFL"); + break; + case TARGET_F_SETFL: + gemu_log("F_SETFL,"); + print_open_flags(arg2, 1); + break; + case TARGET_F_GETLK: + gemu_log("F_GETLK,"); + print_pointer(arg2, 1); + break; + case TARGET_F_SETLK: + gemu_log("F_SETLK,"); + print_pointer(arg2, 1); + break; + case TARGET_F_SETLKW: + gemu_log("F_SETLKW,"); + print_pointer(arg2, 1); + break; + case TARGET_F_GETOWN: + gemu_log("F_GETOWN"); + break; + case TARGET_F_SETOWN: + gemu_log("F_SETOWN,"); + print_raw_param(TARGET_ABI_FMT_ld, arg2, 0); + break; + case TARGET_F_GETSIG: + gemu_log("F_GETSIG"); + break; + case TARGET_F_SETSIG: + gemu_log("F_SETSIG,"); + print_raw_param(TARGET_ABI_FMT_ld, arg2, 0); + break; +#if TARGET_ABI_BITS == 32 + case TARGET_F_GETLK64: + gemu_log("F_GETLK64,"); + print_pointer(arg2, 1); + break; + case TARGET_F_SETLK64: + gemu_log("F_SETLK64,"); + print_pointer(arg2, 1); + break; + case TARGET_F_SETLKW64: + gemu_log("F_SETLKW64,"); + print_pointer(arg2, 1); + break; +#endif + case TARGET_F_SETLEASE: + gemu_log("F_SETLEASE,"); + print_raw_param(TARGET_ABI_FMT_ld, arg2, 0); + break; + case TARGET_F_GETLEASE: + gemu_log("F_GETLEASE"); + break; + case TARGET_F_DUPFD_CLOEXEC: + gemu_log("F_DUPFD_CLOEXEC,"); + print_raw_param(TARGET_ABI_FMT_ld, arg2, 1); + break; + case TARGET_F_NOTIFY: + gemu_log("F_NOTIFY,"); + print_raw_param(TARGET_ABI_FMT_ld, arg2, 0); + break; + default: + print_raw_param(TARGET_ABI_FMT_ld, arg1, 0); + print_pointer(arg2, 1); + break; + } print_syscall_epilogue(name); } #define print_fcntl64 print_fcntl From cce246e0a21577bb2372ab3a7d6789371e087de9 Mon Sep 17 00:00:00 2001 From: John Rigby Date: Sat, 23 Feb 2013 16:14:07 -0700 Subject: [PATCH 03/11] linux-user/syscall.c: handle FUTEX_WAIT_BITSET in do_futex Upstream libc has recently changed to start using FUTEX_WAIT_BITSET instead of FUTEX_WAIT and this is causing do_futex to return -TARGET_ENOSYS. Pass bitset in val3 to sys_futex which will be ignored by kernel for the FUTEX_WAIT case. Signed-off-by: John Rigby Signed-off-by: Riku Voipio --- linux-user/syscall.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 19630eaf20..c7fcfc02c6 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -4922,6 +4922,7 @@ static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout, #endif switch (base_op) { case FUTEX_WAIT: + case FUTEX_WAIT_BITSET: if (timeout) { pts = &ts; target_to_host_timespec(pts, timeout); @@ -4929,7 +4930,7 @@ static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout, pts = NULL; } return get_errno(sys_futex(g2h(uaddr), op, tswap32(val), - pts, NULL, 0)); + pts, NULL, val3)); case FUTEX_WAKE: return get_errno(sys_futex(g2h(uaddr), op, val, NULL, NULL, 0)); case FUTEX_FD: From bfb669f39f2ecd854992924ced20b00163509043 Mon Sep 17 00:00:00 2001 From: John Rigby Date: Sat, 23 Feb 2013 16:14:08 -0700 Subject: [PATCH 04/11] linux-user: fix futex strace of FUTEX_CLOCK_REALTIME Handle same as existing FUTEX_PRIVATE_FLAG. Signed-off-by: John Rigby Signed-off-by: Riku Voipio --- linux-user/strace.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/linux-user/strace.c b/linux-user/strace.c index 9a181460ec..0fbae3c2f6 100644 --- a/linux-user/strace.c +++ b/linux-user/strace.c @@ -1497,6 +1497,12 @@ if( cmd == val ) { \ gemu_log("FUTEX_PRIVATE_FLAG|"); cmd &= ~FUTEX_PRIVATE_FLAG; } +#endif +#ifdef FUTEX_CLOCK_REALTIME + if (cmd & FUTEX_CLOCK_REALTIME) { + gemu_log("FUTEX_CLOCK_REALTIME|"); + cmd &= ~FUTEX_CLOCK_REALTIME; + } #endif print_op(FUTEX_WAIT) print_op(FUTEX_WAKE) From f2b79ce9dc65753c6833921dd5ef6fa59632851f Mon Sep 17 00:00:00 2001 From: Dillon Amburgey Date: Sat, 2 Feb 2013 18:04:48 -0500 Subject: [PATCH 05/11] linux-user: Support setgroups syscall with no groups Signed-off-by: Dillon Amburgey Reviewed-by: Peter Maydell Signed-off-by: Riku Voipio --- linux-user/syscall.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index c7fcfc02c6..1729446840 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -7680,18 +7680,20 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, { int gidsetsize = arg1; target_id *target_grouplist; - gid_t *grouplist; + gid_t *grouplist = NULL; int i; - - grouplist = alloca(gidsetsize * sizeof(gid_t)); - target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 2, 1); - if (!target_grouplist) { - ret = -TARGET_EFAULT; - goto fail; + if (gidsetsize) { + grouplist = alloca(gidsetsize * sizeof(gid_t)); + target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 2, 1); + if (!target_grouplist) { + ret = -TARGET_EFAULT; + goto fail; + } + for (i = 0; i < gidsetsize; i++) { + grouplist[i] = low2highgid(tswapid(target_grouplist[i])); + } + unlock_user(target_grouplist, arg2, 0); } - for(i = 0;i < gidsetsize; i++) - grouplist[i] = low2highgid(tswapid(target_grouplist[i])); - unlock_user(target_grouplist, arg2, 0); ret = get_errno(setgroups(gidsetsize, grouplist)); } break; From 0d95fda86b0d69fc4010f6bb37aa4fd38f1addff Mon Sep 17 00:00:00 2001 From: Dillon Amburgey Date: Thu, 3 Jan 2013 22:10:26 -0500 Subject: [PATCH 06/11] linux-user: Add more sparc syscall numbers Signed-off-by: Dillon Amburgey Signed-off-by: Riku Voipio --- linux-user/sparc/syscall_nr.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/linux-user/sparc/syscall_nr.h b/linux-user/sparc/syscall_nr.h index 061711cc03..534e6e9963 100644 --- a/linux-user/sparc/syscall_nr.h +++ b/linux-user/sparc/syscall_nr.h @@ -200,6 +200,8 @@ #define TARGET_NR__newselect 230 /* Linux Specific */ #define TARGET_NR_time 231 /* Linux Specific */ #define TARGET_NR_stime 233 /* Linux Specific */ +#define TARGET_NR_statfs64 234 /* Linux Specific */ +#define TARGET_NR_fstatfs64 235 /* Linux Specific */ #define TARGET_NR__llseek 236 /* Linux Specific */ #define TARGET_NR_mlock 237 #define TARGET_NR_munlock 238 From 63ec54d7b319824df8b60cfe25afdfb607ce3905 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Thu, 14 Feb 2013 08:46:43 +0000 Subject: [PATCH 07/11] linux-user: Fix layout of usage table to account for option text The linux-user usage message attempts to line up the columns in its table by calculating the maximum width of any item in them. However for the 'Argument' column it was only accounting for the length of the option switch (eg "-d"), not the additional example text (eg "item[,...]"). This currently has no adverse effects because the widest item in the column happens to be the argumentless "-singlestep" option, but improving the "-d" option help to read "-d item[,...]" exceeds that limit. Fix this by correctly calculating maxarglen as the width of the first column text including a possible option argument, and adjusting its uses to match. Signed-off-by: Peter Maydell Signed-off-by: Riku Voipio --- linux-user/main.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/linux-user/main.c b/linux-user/main.c index d8b0cd65fa..4e92a0b4c5 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -3406,27 +3406,35 @@ static void usage(void) "Options and associated environment variables:\n" "\n"); - maxarglen = maxenvlen = 0; + /* Calculate column widths. We must always have at least enough space + * for the column header. + */ + maxarglen = strlen("Argument"); + maxenvlen = strlen("Env-variable"); for (arginfo = arg_table; arginfo->handle_opt != NULL; arginfo++) { + int arglen = strlen(arginfo->argv); + if (arginfo->has_arg) { + arglen += strlen(arginfo->example) + 1; + } if (strlen(arginfo->env) > maxenvlen) { maxenvlen = strlen(arginfo->env); } - if (strlen(arginfo->argv) > maxarglen) { - maxarglen = strlen(arginfo->argv); + if (arglen > maxarglen) { + maxarglen = arglen; } } - printf("%-*s%-*sDescription\n", maxarglen+3, "Argument", - maxenvlen+1, "Env-variable"); + printf("%-*s %-*s Description\n", maxarglen+1, "Argument", + maxenvlen, "Env-variable"); for (arginfo = arg_table; arginfo->handle_opt != NULL; arginfo++) { if (arginfo->has_arg) { printf("-%s %-*s %-*s %s\n", arginfo->argv, - (int)(maxarglen-strlen(arginfo->argv)), arginfo->example, - maxenvlen, arginfo->env, arginfo->help); + (int)(maxarglen - strlen(arginfo->argv) - 1), + arginfo->example, maxenvlen, arginfo->env, arginfo->help); } else { - printf("-%-*s %-*s %s\n", maxarglen+1, arginfo->argv, + printf("-%-*s %-*s %s\n", maxarglen, arginfo->argv, maxenvlen, arginfo->env, arginfo->help); } From dfae8e00f8ddeedcda24bd28f71d4fd2a9f988b8 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 8 Feb 2013 07:58:41 +0000 Subject: [PATCH 08/11] linux-user: make bogus negative iovec lengths fail EINVAL If the guest passes us a bogus negative length for an iovec, fail EINVAL rather than proceeding blindly forward. This fixes some of the error cases tests for readv and writev in the LTP. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Signed-off-by: Riku Voipio --- linux-user/syscall.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 1729446840..bab9ab58a0 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -1776,7 +1776,7 @@ static struct iovec *lock_iovec(int type, abi_ulong target_addr, errno = 0; return NULL; } - if (count > IOV_MAX) { + if (count < 0 || count > IOV_MAX) { errno = EINVAL; return NULL; } From a8fd1aba8584cbe68583907ce766fd8ecfe81f4b Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 8 Feb 2013 07:31:55 +0000 Subject: [PATCH 09/11] linux-user: Implement sendfile and sendfile64 Implement the sendfile and sendfile64 syscalls. This implementation passes all the LTP test cases for these syscalls. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Signed-off-by: Riku Voipio --- configure | 17 ++++++++++++++ linux-user/syscall.c | 53 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/configure b/configure index 84317c6826..a416e23597 100755 --- a/configure +++ b/configure @@ -2760,6 +2760,20 @@ if compile_prog "" "" ; then epoll_pwait=yes fi +# check for sendfile support +sendfile=no +cat > $TMPC << EOF +#include + +int main(void) +{ + return sendfile(0, 0, 0, 0); +} +EOF +if compile_prog "" "" ; then + sendfile=yes +fi + # Check if tools are available to build documentation. if test "$docs" != "no" ; then if has makeinfo && has pod2man; then @@ -3628,6 +3642,9 @@ fi if test "$epoll_pwait" = "yes" ; then echo "CONFIG_EPOLL_PWAIT=y" >> $config_host_mak fi +if test "$sendfile" = "yes" ; then + echo "CONFIG_SENDFILE=y" >> $config_host_mak +fi if test "$inotify" = "yes" ; then echo "CONFIG_INOTIFY=y" >> $config_host_mak fi diff --git a/linux-user/syscall.c b/linux-user/syscall.c index bab9ab58a0..77281f1b48 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -78,6 +78,9 @@ int __clone2(int (*fn)(void *), void *child_stack_base, #ifdef CONFIG_ATTR #include "qemu/xattr.h" #endif +#ifdef CONFIG_SENDFILE +#include +#endif #define termios host_termios #define winsize host_winsize @@ -7531,8 +7534,58 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #else goto unimplemented; #endif + +#ifdef CONFIG_SENDFILE case TARGET_NR_sendfile: + { + off_t *offp = NULL; + off_t off; + if (arg3) { + ret = get_user_sal(off, arg3); + if (is_error(ret)) { + break; + } + offp = &off; + } + ret = get_errno(sendfile(arg1, arg2, offp, arg4)); + if (!is_error(ret) && arg3) { + abi_long ret2 = put_user_sal(off, arg3); + if (is_error(ret2)) { + ret = ret2; + } + } + break; + } +#ifdef TARGET_NR_sendfile64 + case TARGET_NR_sendfile64: + { + off_t *offp = NULL; + off_t off; + if (arg3) { + ret = get_user_s64(off, arg3); + if (is_error(ret)) { + break; + } + offp = &off; + } + ret = get_errno(sendfile(arg1, arg2, offp, arg4)); + if (!is_error(ret) && arg3) { + abi_long ret2 = put_user_s64(off, arg3); + if (is_error(ret2)) { + ret = ret2; + } + } + break; + } +#endif +#else + case TARGET_NR_sendfile: +#ifdef TARGET_NR_sendfile64: + case TARGET_NR_sendfile64: +#endif goto unimplemented; +#endif + #ifdef TARGET_NR_getpmsg case TARGET_NR_getpmsg: goto unimplemented; From a94b4987e243d9afebf56a098afeddae133276b5 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 8 Feb 2013 04:35:04 +0000 Subject: [PATCH 10/11] linux-user: Implement accept4 Implement the accept4 syscall (which is identical to accept but has an additional flags argument). Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Signed-off-by: Riku Voipio --- linux-user/syscall.c | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 77281f1b48..6182a272ec 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -2004,16 +2004,30 @@ out2: return ret; } -/* do_accept() Must return target values and target errnos. */ -static abi_long do_accept(int fd, abi_ulong target_addr, - abi_ulong target_addrlen_addr) +/* If we don't have a system accept4() then just call accept. + * The callsites to do_accept4() will ensure that they don't + * pass a non-zero flags argument in this config. + */ +#ifndef CONFIG_ACCEPT4 +static inline int accept4(int sockfd, struct sockaddr *addr, + socklen_t *addrlen, int flags) +{ + assert(flags == 0); + return accept(sockfd, addr, addrlen); +} +#endif + +/* do_accept4() Must return target values and target errnos. */ +static abi_long do_accept4(int fd, abi_ulong target_addr, + abi_ulong target_addrlen_addr, int flags) { socklen_t addrlen; void *addr; abi_long ret; - if (target_addr == 0) - return get_errno(accept(fd, NULL, NULL)); + if (target_addr == 0) { + return get_errno(accept4(fd, NULL, NULL, flags)); + } /* linux returns EINVAL if addrlen pointer is invalid */ if (get_user_u32(addrlen, target_addrlen_addr)) @@ -2028,7 +2042,7 @@ static abi_long do_accept(int fd, abi_ulong target_addr, addr = alloca(addrlen); - ret = get_errno(accept(fd, addr, &addrlen)); + ret = get_errno(accept4(fd, addr, &addrlen, flags)); if (!is_error(ret)) { host_to_target_sockaddr(target_addr, addr, addrlen); if (put_user_u32(addrlen, target_addrlen_addr)) @@ -2254,7 +2268,7 @@ static abi_long do_socketcall(int num, abi_ulong vptr) || get_user_ual(target_addrlen, vptr + 2 * n)) return -TARGET_EFAULT; - ret = do_accept(sockfd, target_addr, target_addrlen); + ret = do_accept4(sockfd, target_addr, target_addrlen, 0); } break; case SOCKOP_getsockname: @@ -6677,7 +6691,16 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #endif #ifdef TARGET_NR_accept case TARGET_NR_accept: - ret = do_accept(arg1, arg2, arg3); + ret = do_accept4(arg1, arg2, arg3, 0); + break; +#endif +#ifdef TARGET_NR_accept4 + case TARGET_NR_accept4: +#ifdef CONFIG_ACCEPT4 + ret = do_accept4(arg1, arg2, arg3, arg4); +#else + goto unimplemented; +#endif break; #endif #ifdef TARGET_NR_bind From e9a970a8316f9f86a6c800a9a90175bd593f862c Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 8 Feb 2013 04:34:54 +0000 Subject: [PATCH 11/11] linux-user/syscall.c: Don't warn about unimplemented get_robust_list The nature of the kernel ABI for the get_robust_list and set_robust_list syscalls means we cannot implement them in QEMU. Make get_robust_list silently return ENOSYS rather than using the default "print message and then fail ENOSYS" code path, in the same way we already do for set_robust_list, and add a comment documenting why we do this. This silences warnings which were being produced for emulating even trivial programs like 'ls' in x86-64-on-x86-64. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Signed-off-by: Riku Voipio --- linux-user/syscall.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 6182a272ec..ee82a2da4e 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -8631,7 +8631,20 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #ifdef TARGET_NR_set_robust_list case TARGET_NR_set_robust_list: - goto unimplemented_nowarn; + case TARGET_NR_get_robust_list: + /* The ABI for supporting robust futexes has userspace pass + * the kernel a pointer to a linked list which is updated by + * userspace after the syscall; the list is walked by the kernel + * when the thread exits. Since the linked list in QEMU guest + * memory isn't a valid linked list for the host and we have + * no way to reliably intercept the thread-death event, we can't + * support these. Silently return ENOSYS so that guest userspace + * falls back to a non-robust futex implementation (which should + * be OK except in the corner case of the guest crashing while + * holding a mutex that is shared with another process via + * shared memory). + */ + goto unimplemented_nowarn; #endif #if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)