git: 2eae70753e44 - stable/13 - linux(4): Implement rt_sigtimedwait_time64 system call.

From: Dmitry Chagin <dchagin_at_FreeBSD.org>
Date: Fri, 17 Jun 2022 19:31:51 UTC
The branch stable/13 has been updated by dchagin:

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

commit 2eae70753e443a2b801a3bb9202b2e662dac9df1
Author:     Dmitry Chagin <dchagin@FreeBSD.org>
AuthorDate: 2021-06-10 11:51:30 +0000
Commit:     Dmitry Chagin <dchagin@FreeBSD.org>
CommitDate: 2022-06-17 19:30:15 +0000

    linux(4): Implement rt_sigtimedwait_time64 system call.
    
    It still does not work as intended, awaits D30675.
    
    MFC after:      2 weeks
    
    (cherry picked from commit db4a1f331b73eb821d5d9c3cbb478ad50223f023)
---
 sys/amd64/linux32/linux32_dummy_machdep.c |  1 -
 sys/amd64/linux32/syscalls.master         |  7 +++-
 sys/compat/linux/linux_signal.c           | 70 +++++++++++++++++++++++--------
 sys/i386/linux/linux_dummy_machdep.c      |  1 -
 sys/i386/linux/syscalls.master            |  7 +++-
 5 files changed, 64 insertions(+), 22 deletions(-)

diff --git a/sys/amd64/linux32/linux32_dummy_machdep.c b/sys/amd64/linux32/linux32_dummy_machdep.c
index bfb4ff71e0b1..837496641311 100644
--- a/sys/amd64/linux32/linux32_dummy_machdep.c
+++ b/sys/amd64/linux32/linux32_dummy_machdep.c
@@ -79,5 +79,4 @@ DUMMY(recvmmsg_time64);
 DUMMY(mq_timedsend_time64);
 DUMMY(mq_timedreceive_time64);
 DUMMY(semtimedop_time64);
-DUMMY(rt_sigtimedwait_time64);
 DUMMY(sched_rr_get_interval_time64);
diff --git a/sys/amd64/linux32/syscalls.master b/sys/amd64/linux32/syscalls.master
index bf2778bb91fd..92c1c0e53cdc 100644
--- a/sys/amd64/linux32/syscalls.master
+++ b/sys/amd64/linux32/syscalls.master
@@ -2412,7 +2412,12 @@
 		int linux_semtimedop_time64(void);
 	}
 421	AUE_NULL	STD {
-		int linux_rt_sigtimedwait_time64(void);
+		int linux_rt_sigtimedwait_time64(
+		    l_sigset_t *mask,
+		    l_siginfo_t *ptr,
+		    struct l_timespec64 *timeout,
+		    l_size_t sigsetsize
+		);
 	}
 422	AUE_NULL	STD {
 		int linux_sys_futex_time64(
diff --git a/sys/compat/linux/linux_signal.c b/sys/compat/linux/linux_signal.c
index 8c41d724c0b9..610bd7916689 100644
--- a/sys/compat/linux/linux_signal.c
+++ b/sys/compat/linux/linux_signal.c
@@ -60,6 +60,9 @@ __FBSDID("$FreeBSD$");
 static int	linux_do_tkill(struct thread *td, struct thread *tdt,
 		    ksiginfo_t *ksi);
 static void	sicode_to_lsicode(int si_code, int *lsi_code);
+static int	linux_common_rt_sigtimedwait(struct thread *,
+		    l_sigset_t *, struct timespec *, l_siginfo_t *,
+		    l_size_t);
 
 static void
 linux_to_bsd_sigaction(l_sigaction_t *lsa, struct sigaction *bsa)
@@ -391,29 +394,14 @@ linux_rt_sigpending(struct thread *td, struct linux_rt_sigpending_args *args)
 	return (copyout(&lset, args->set, args->sigsetsize));
 }
 
-/*
- * MPSAFE
- */
 int
 linux_rt_sigtimedwait(struct thread *td,
 	struct linux_rt_sigtimedwait_args *args)
 {
-	int error, sig;
 	struct timespec ts, *tsa;
 	struct l_timespec lts;
-	l_sigset_t lset;
-	sigset_t bset;
-	l_siginfo_t lsi;
-	ksiginfo_t ksi;
-
-	if (args->sigsetsize != sizeof(l_sigset_t))
-		return (EINVAL);
-
-	if ((error = copyin(args->mask, &lset, sizeof(lset))))
-		return (error);
-	linux_to_bsd_sigset(&lset, &bset);
+	int error;
 
-	tsa = NULL;
 	if (args->timeout) {
 		if ((error = copyin(args->timeout, &lts, sizeof(lts))))
 			return (error);
@@ -424,16 +412,38 @@ linux_rt_sigtimedwait(struct thread *td,
 	} else
 		tsa = NULL;
 
+	return (linux_common_rt_sigtimedwait(td, args->mask, tsa,
+	    args->ptr, args->sigsetsize));
+}
+
+static int
+linux_common_rt_sigtimedwait(struct thread *td, l_sigset_t *mask,
+    struct timespec *tsa, l_siginfo_t *ptr, l_size_t sigsetsize)
+{
+	int error, sig;
+	l_sigset_t lset;
+	sigset_t bset;
+	l_siginfo_t lsi;
+	ksiginfo_t ksi;
+
+	if (sigsetsize != sizeof(l_sigset_t))
+		return (EINVAL);
+
+	if ((error = copyin(mask, &lset, sizeof(lset))))
+		return (error);
+	linux_to_bsd_sigset(&lset, &bset);
+
+	ksiginfo_init(&ksi);
 	error = kern_sigtimedwait(td, bset, &ksi, tsa);
 	if (error)
 		return (error);
 
 	sig = bsd_to_linux_signal(ksi.ksi_signo);
 
-	if (args->ptr) {
+	if (ptr) {
 		memset(&lsi, 0, sizeof(lsi));
 		siginfo_to_lsiginfo(&ksi.ksi_info, &lsi, sig);
-		error = copyout(&lsi, args->ptr, sizeof(lsi));
+		error = copyout(&lsi, ptr, sizeof(lsi));
 	}
 	if (error == 0)
 		td->td_retval[0] = sig;
@@ -441,6 +451,30 @@ linux_rt_sigtimedwait(struct thread *td,
 	return (error);
 }
 
+#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
+int
+linux_rt_sigtimedwait_time64(struct thread *td,
+	struct linux_rt_sigtimedwait_time64_args *args)
+{
+	struct timespec ts, *tsa;
+	struct l_timespec64 lts;
+	int 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_common_rt_sigtimedwait(td, args->mask, tsa,
+	    args->ptr, args->sigsetsize));
+}
+#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
+
 int
 linux_kill(struct thread *td, struct linux_kill_args *args)
 {
diff --git a/sys/i386/linux/linux_dummy_machdep.c b/sys/i386/linux/linux_dummy_machdep.c
index 78503b9453ee..a349fab5b637 100644
--- a/sys/i386/linux/linux_dummy_machdep.c
+++ b/sys/i386/linux/linux_dummy_machdep.c
@@ -81,5 +81,4 @@ DUMMY(recvmmsg_time64);
 DUMMY(mq_timedsend_time64);
 DUMMY(mq_timedreceive_time64);
 DUMMY(semtimedop_time64);
-DUMMY(rt_sigtimedwait_time64);
 DUMMY(sched_rr_get_interval_time64);
diff --git a/sys/i386/linux/syscalls.master b/sys/i386/linux/syscalls.master
index d78f000530e3..c42d9af0058d 100644
--- a/sys/i386/linux/syscalls.master
+++ b/sys/i386/linux/syscalls.master
@@ -2430,7 +2430,12 @@
 		int linux_semtimedop_time64(void);
 	}
 421	AUE_NULL	STD {
-		int linux_rt_sigtimedwait_time64(void);
+		int linux_rt_sigtimedwait_time64(
+		    l_sigset_t *mask,
+		    l_siginfo_t *ptr,
+		    struct l_timespec64 *timeout,
+		    l_size_t sigsetsize
+		);
 	}
 422	AUE_NULL	STD {
 		int linux_sys_futex_time64(