git: 1744f14e26c9 - main - linux(4): Implement recvmmsg_time64 syscall.

From: Dmitry Chagin <dchagin_at_FreeBSD.org>
Date: Wed, 04 May 2022 10:08:23 UTC
The branch main has been updated by dchagin:

URL: https://cgit.FreeBSD.org/src/commit/?id=1744f14e26c99af704650922e19e6934aa9a1271

commit 1744f14e26c99af704650922e19e6934aa9a1271
Author:     Dmitry Chagin <dchagin@FreeBSD.org>
AuthorDate: 2022-05-04 10:06:53 +0000
Commit:     Dmitry Chagin <dchagin@FreeBSD.org>
CommitDate: 2022-05-04 10:06:53 +0000

    linux(4): Implement recvmmsg_time64 syscall.
    
    MFC after:              2 weeks
---
 sys/amd64/linux32/linux32_dummy_machdep.c |  1 -
 sys/compat/linux/linux_socket.c           | 85 ++++++++++++++++++++++---------
 sys/i386/linux/linux_dummy_machdep.c      |  1 -
 3 files changed, 61 insertions(+), 26 deletions(-)

diff --git a/sys/amd64/linux32/linux32_dummy_machdep.c b/sys/amd64/linux32/linux32_dummy_machdep.c
index 0cc1cd581c32..a5c61e252f9d 100644
--- a/sys/amd64/linux32/linux32_dummy_machdep.c
+++ b/sys/amd64/linux32/linux32_dummy_machdep.c
@@ -69,7 +69,6 @@ DUMMY(arch_prctl);
 /* Linux 5.0: */
 DUMMY(clock_adjtime64);
 DUMMY(io_pgetevents_time64);
-DUMMY(recvmmsg_time64);
 DUMMY(mq_timedsend_time64);
 DUMMY(mq_timedreceive_time64);
 DUMMY(semtimedop_time64);
diff --git a/sys/compat/linux/linux_socket.c b/sys/compat/linux/linux_socket.c
index d7e17596fde1..93b5cea7ecc3 100644
--- a/sys/compat/linux/linux_socket.c
+++ b/sys/compat/linux/linux_socket.c
@@ -1736,32 +1736,19 @@ linux_recvmsg(struct thread *td, struct linux_recvmsg_args *args)
 	    args->flags, &bsd_msg));
 }
 
-int
-linux_recvmmsg(struct thread *td, struct linux_recvmmsg_args *args)
+static int
+linux_recvmmsg_common(struct thread *td, l_int s, struct l_mmsghdr *msg,
+    l_uint vlen, l_uint flags, struct timespec *tts)
 {
-	struct l_mmsghdr *msg;
 	struct msghdr bsd_msg;
-	struct l_timespec lts;
-	struct timespec ts, tts;
+	struct timespec ts;
 	l_uint retval;
 	int error, datagrams;
 
-	if (args->timeout) {
-		error = copyin(args->timeout, &lts, sizeof(struct l_timespec));
-		if (error != 0)
-			return (error);
-		error = linux_to_native_timespec(&ts, &lts);
-		if (error != 0)
-			return (error);
-		getnanotime(&tts);
-		timespecadd(&tts, &ts, &tts);
-	}
-
-	msg = PTRIN(args->msg);
 	datagrams = 0;
-	while (datagrams < args->vlen) {
-		error = linux_recvmsg_common(td, args->s, &msg->msg_hdr,
-		    args->flags & ~LINUX_MSG_WAITFORONE, &bsd_msg);
+	while (datagrams < vlen) {
+		error = linux_recvmsg_common(td, s, &msg->msg_hdr,
+		    flags & ~LINUX_MSG_WAITFORONE, &bsd_msg);
 		if (error != 0)
 			break;
 
@@ -1775,15 +1762,15 @@ linux_recvmmsg(struct thread *td, struct linux_recvmmsg_args *args)
 		/*
 		 * MSG_WAITFORONE turns on MSG_DONTWAIT after one packet.
 		 */
-		if (args->flags & LINUX_MSG_WAITFORONE)
-			args->flags |= LINUX_MSG_DONTWAIT;
+		if (flags & LINUX_MSG_WAITFORONE)
+			flags |= LINUX_MSG_DONTWAIT;
 
 		/*
 		 * See BUGS section of recvmmsg(2).
 		 */
-		if (args->timeout) {
+		if (tts) {
 			getnanotime(&ts);
-			timespecsub(&ts, &tts, &ts);
+			timespecsub(&ts, tts, &ts);
 			if (!timespecisset(&ts) || ts.tv_sec > 0)
 				break;
 		}
@@ -1796,6 +1783,56 @@ linux_recvmmsg(struct thread *td, struct linux_recvmmsg_args *args)
 	return (error);
 }
 
+int
+linux_recvmmsg(struct thread *td, struct linux_recvmmsg_args *args)
+{
+	struct l_timespec lts;
+	struct timespec ts, tts, *ptts;
+	int error;
+
+	if (args->timeout) {
+		error = copyin(args->timeout, &lts, sizeof(struct l_timespec));
+		if (error != 0)
+			return (error);
+		error = linux_to_native_timespec(&ts, &lts);
+		if (error != 0)
+			return (error);
+		getnanotime(&tts);
+		timespecadd(&tts, &ts, &tts);
+		ptts = &tts;
+	}
+		else ptts = NULL;
+
+	return (linux_recvmmsg_common(td, args->s, PTRIN(args->msg),
+	    args->vlen, args->flags, ptts));
+}
+
+#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
+int
+linux_recvmmsg_time64(struct thread *td, struct linux_recvmmsg_time64_args *args)
+{
+	struct l_timespec64 lts;
+	struct timespec ts, tts, *ptts;
+	int error;
+
+	if (args->timeout) {
+		error = copyin(args->timeout, &lts, sizeof(struct l_timespec));
+		if (error != 0)
+			return (error);
+		error = linux_to_native_timespec64(&ts, &lts);
+		if (error != 0)
+			return (error);
+		getnanotime(&tts);
+		timespecadd(&tts, &ts, &tts);
+		ptts = &tts;
+	}
+		else ptts = NULL;
+
+	return (linux_recvmmsg_common(td, args->s, PTRIN(args->msg),
+	    args->vlen, args->flags, ptts));
+}
+#endif
+
 int
 linux_shutdown(struct thread *td, struct linux_shutdown_args *args)
 {
diff --git a/sys/i386/linux/linux_dummy_machdep.c b/sys/i386/linux/linux_dummy_machdep.c
index 4619fa226a72..dd89444537d0 100644
--- a/sys/i386/linux/linux_dummy_machdep.c
+++ b/sys/i386/linux/linux_dummy_machdep.c
@@ -71,7 +71,6 @@ DUMMY(arch_prctl);
 /* Linux 5.0: */
 DUMMY(clock_adjtime64);
 DUMMY(io_pgetevents_time64);
-DUMMY(recvmmsg_time64);
 DUMMY(mq_timedsend_time64);
 DUMMY(mq_timedreceive_time64);
 DUMMY(semtimedop_time64);