git: e00aad1042e7 - main - linux(4): Add epoll_pwai2 syscall.

From: Dmitry Chagin <dchagin_at_FreeBSD.org>
Date: Tue, 26 Apr 2022 16:37:21 UTC
The branch main has been updated by dchagin:

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

commit e00aad1042e7163865763b42d8d72137eeb9df63
Author:     Dmitry Chagin <dchagin@FreeBSD.org>
AuthorDate: 2022-04-26 16:35:59 +0000
Commit:     Dmitry Chagin <dchagin@FreeBSD.org>
CommitDate: 2022-04-26 16:35:59 +0000

    linux(4): Add epoll_pwai2 syscall.
    
    MFC after:      2 weeks
---
 sys/compat/linux/linux_dummy.c |  1 -
 sys/compat/linux/linux_event.c | 56 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 56 insertions(+), 1 deletion(-)

diff --git a/sys/compat/linux/linux_dummy.c b/sys/compat/linux/linux_dummy.c
index 57360c0d1a00..6bfeeaf5c298 100644
--- a/sys/compat/linux/linux_dummy.c
+++ b/sys/compat/linux/linux_dummy.c
@@ -140,7 +140,6 @@ DUMMY(close_range);
 DUMMY(openat2);
 DUMMY(pidfd_getfd);
 DUMMY(process_madvise);
-DUMMY(epoll_pwait2);
 DUMMY(mount_setattr);
 /* Linux 4.18: */
 DUMMY(io_pgetevents);
diff --git a/sys/compat/linux/linux_event.c b/sys/compat/linux/linux_event.c
index 52f7c58a4347..08d52cd10fc3 100644
--- a/sys/compat/linux/linux_event.c
+++ b/sys/compat/linux/linux_event.c
@@ -535,6 +535,62 @@ linux_epoll_pwait(struct thread *td, struct linux_epoll_pwait_args *args)
 	    args->maxevents, args->timeout, pmask));
 }
 
+#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
+int
+linux_epoll_pwait2_64(struct thread *td, struct linux_epoll_pwait2_64_args *args)
+{
+	struct timespec ts, *tsa;
+	struct l_timespec64 lts;
+	sigset_t mask, *pmask;
+	int error;
+
+	error = linux_copyin_sigset(args->mask, sizeof(l_sigset_t),
+	    &mask, &pmask);
+	if (error != 0)
+		return (error);
+
+	if (args->timeout) {
+		if ((error = copyin(args->timeout, &lts, sizeof(lts))))
+			return (error);
+		error = linux_to_native_timespec64(&ts, &lts);
+		if (error != 0)
+			return (error);
+		tsa = &ts;
+	} else
+		tsa = NULL;
+
+	return (linux_epoll_wait_ts(td, args->epfd, args->events,
+	    args->maxevents, tsa, pmask));
+}
+#else
+int
+linux_epoll_pwait2(struct thread *td, struct linux_epoll_pwait2_args *args)
+{
+	struct timespec ts, *tsa;
+	struct l_timespec lts;
+	sigset_t mask, *pmask;
+	int error;
+
+	error = linux_copyin_sigset(args->mask, sizeof(l_sigset_t),
+	    &mask, &pmask);
+	if (error != 0)
+		return (error);
+
+	if (args->timeout) {
+		if ((error = copyin(args->timeout, &lts, sizeof(lts))))
+			return (error);
+		error = linux_to_native_timespec(&ts, &lts);
+		if (error != 0)
+			return (error);
+		tsa = &ts;
+	} else
+		tsa = NULL;
+
+	return (linux_epoll_wait_ts(td, args->epfd, args->events,
+	    args->maxevents, tsa, pmask));
+}
+#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
+
 static int
 epoll_register_kevent(struct thread *td, struct file *epfp, int fd, int filter,
     unsigned int flags)