This patch introduces functionality for syscall: *recvmmsg_time64
This syscall is a 2038 safe variant for syscall: int recvmmsg(int sockfd, struct mmsghdr *msgvec, unsigned int vlen, int flags, struct timespec *timeout) --receive multiple messages on a socket-- man page: https://man7.org/linux/man-pages/man2/recvmmsg.2.html Implementation notes: Function 'do_sendrecvmmsg()' in 'syscall.c' was changed with the addition of a new argument 'time64' which represents a flag by which the function knows what kind of 'struct timespec' converting function to call ('target_to_host_timespec() or 'target_to_host_timespec64()'). It is 0 in case of 'TARGET_NR_recvmmsg' and 1 in case of 'TARGET_NR_recvmmsg_time64'. In 'do_socketcall()', the 'TARGET_ABI_BITS' was checked to know what value for 'time64' argument to pass (0 if 'TARGET_ABI_BITS == 32' and 1 otherwise). Signed-off-by: Filip Bozuta <filip.boz...@syrmia.com> --- linux-user/syscall.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 420d7e7334..ed9c2cb7ab 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -3217,7 +3217,7 @@ static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg, static abi_long do_sendrecvmmsg(int fd, abi_ulong target_msgvec_addr, unsigned int vlen, unsigned int flags, - abi_long timeout, int send) + abi_long timeout, int time64, int send) { struct mmsghdr *host_msgvec; struct target_mmsghdr *target_msgvec; @@ -3277,7 +3277,10 @@ static abi_long do_sendrecvmmsg(int fd, abi_ulong target_msgvec_addr, ret = get_errno(safe_sendmmsg(fd, host_msgvec, i, flags)); } else { if (timeout) { - if (target_to_host_timespec(&ts, timeout)) { + if (!time64 && target_to_host_timespec(&ts, timeout)) { + return -TARGET_EFAULT; + } + if (time64 && target_to_host_timespec64(&ts, timeout)) { return -TARGET_EFAULT; } ret = get_errno(safe_recvmmsg(fd, host_msgvec, i, flags, &ts)); @@ -3619,10 +3622,14 @@ static abi_long do_socketcall(int num, abi_ulong vptr) return do_sendrecvmsg(a[0], a[1], a[2], 0); case TARGET_SYS_ACCEPT4: /* sockfd, addr, addrlen, flags */ return do_accept4(a[0], a[1], a[2], a[3]); - case TARGET_SYS_RECVMMSG: /* sockfd, msgvec, vlen, timeout, flags */ - return do_sendrecvmmsg(a[0], a[1], a[2], a[3], a[4], 0); + case TARGET_SYS_RECVMMSG: /* sockfd, msgvec, vlen, flags, timeout, */ +#if TARGET_ABI_BITS == 32 + return do_sendrecvmmsg(a[0], a[1], a[2], a[3], a[4], 0, 0); +#else + return do_sendrecvmmsg(a[0], a[1], a[2], a[3], a[4], 1, 0); +#endif case TARGET_SYS_SENDMMSG: /* sockfd, msgvec, vlen, flags */ - return do_sendrecvmmsg(a[0], a[1], a[2], a[3], 0, 1); + return do_sendrecvmmsg(a[0], a[1], a[2], a[3], 0, 0, 1); default: qemu_log_mask(LOG_UNIMP, "Unsupported socketcall: %d\n", num); return -TARGET_EINVAL; @@ -9426,11 +9433,15 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, #endif #ifdef TARGET_NR_sendmmsg case TARGET_NR_sendmmsg: - return do_sendrecvmmsg(arg1, arg2, arg3, arg4, 0, 1); + return do_sendrecvmmsg(arg1, arg2, arg3, arg4, 0, 0, 1); #endif #ifdef TARGET_NR_recvmmsg case TARGET_NR_recvmmsg: - return do_sendrecvmmsg(arg1, arg2, arg3, arg4, arg5, 0); + return do_sendrecvmmsg(arg1, arg2, arg3, arg4, arg5, 0, 0); +#endif +#ifdef TARGET_NR_recvmmsg_time64 + case TARGET_NR_recvmmsg_time64: + return do_sendrecvmmsg(arg1, arg2, arg3, arg4, arg5, 1, 0); #endif #ifdef TARGET_NR_sendto case TARGET_NR_sendto: -- 2.25.1