Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 10 Jun 2021 12:04:51 GMT
From:      Dmitry Chagin <dchagin@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: f6d075ecd769 - main - linux(4): Implement pselect6_time64 system call.
Message-ID:  <202106101204.15AC4pLP033439@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by dchagin:

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

commit f6d075ecd76925cbe56ea528a59bd74e4dd9451e
Author:     Dmitry Chagin <dchagin@FreeBSD.org>
AuthorDate: 2021-06-10 12:03:30 +0000
Commit:     Dmitry Chagin <dchagin@FreeBSD.org>
CommitDate: 2021-06-10 12:03:30 +0000

    linux(4): Implement pselect6_time64 system call.
    
    MFC after:      2 weeks
---
 sys/amd64/linux32/linux32_dummy_machdep.c |  1 -
 sys/amd64/linux32/syscalls.master         |  9 ++-
 sys/compat/linux/linux_misc.c             | 96 ++++++++++++++++++++++++-------
 sys/i386/linux/linux_dummy_machdep.c      |  1 -
 sys/i386/linux/syscalls.master            |  9 ++-
 5 files changed, 92 insertions(+), 24 deletions(-)

diff --git a/sys/amd64/linux32/linux32_dummy_machdep.c b/sys/amd64/linux32/linux32_dummy_machdep.c
index 837496641311..81e0ed51ae31 100644
--- a/sys/amd64/linux32/linux32_dummy_machdep.c
+++ b/sys/amd64/linux32/linux32_dummy_machdep.c
@@ -72,7 +72,6 @@ DUMMY(timer_gettime64);
 DUMMY(timer_settime64);
 DUMMY(timerfd_gettime64);
 DUMMY(timerfd_settime64);
-DUMMY(pselect6_time64);
 DUMMY(ppoll_time64);
 DUMMY(io_pgetevents_time64);
 DUMMY(recvmmsg_time64);
diff --git a/sys/amd64/linux32/syscalls.master b/sys/amd64/linux32/syscalls.master
index 92c1c0e53cdc..ef89e331b429 100644
--- a/sys/amd64/linux32/syscalls.master
+++ b/sys/amd64/linux32/syscalls.master
@@ -2390,7 +2390,14 @@
 		);
 	}
 413	AUE_NULL	STD {
-		int linux_pselect6_time64(void);
+		int linux_pselect6_time64(
+		    l_int nfds,
+		    l_fd_set *readfds,
+		    l_fd_set *writefds,
+		    l_fd_set *exceptfds,
+		    struct l_timespec64 *tsp,
+		    l_uintptr_t *sig
+		);
 	}
 414	AUE_NULL	STD {
 		int linux_ppoll_time64(void);
diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c
index bfa7bb659d5f..78dc37d9a19f 100644
--- a/sys/compat/linux/linux_misc.c
+++ b/sys/compat/linux/linux_misc.c
@@ -138,6 +138,9 @@ static int	linux_utimensat_lts64_to_ts(struct l_timespec64 *,
 #endif
 static int	linux_common_utimensat(struct thread *, int,
 			const char *, struct timespec *, int);
+static int	linux_common_pselect6(struct thread *, l_int,
+			l_fd_set *, l_fd_set *, l_fd_set *,
+			struct timespec *, l_uintptr_t *);
 
 int
 linux_sysinfo(struct thread *td, struct linux_sysinfo_args *args)
@@ -2347,19 +2350,50 @@ linux_prlimit64(struct thread *td, struct linux_prlimit64_args *args)
 
 int
 linux_pselect6(struct thread *td, struct linux_pselect6_args *args)
+{
+	struct l_timespec lts;
+	struct timespec ts, *tsp;
+	int error;
+
+	if (args->tsp != NULL) {
+		error = copyin(args->tsp, &lts, sizeof(lts));
+		if (error != 0)
+			return (error);
+		error = linux_to_native_timespec(&ts, &lts);
+		if (error != 0)
+			return (error);
+		tsp = &ts;
+	} else
+		tsp = NULL;
+
+	error = linux_common_pselect6(td, args->nfds, args->readfds,
+	    args->writefds, args->exceptfds, tsp, args->sig);
+	if (error != 0)
+		return (error);
+
+	if (args->tsp != NULL) {
+		error = native_to_linux_timespec(&lts, tsp);
+		if (error == 0)
+			error = copyout(&lts, args->tsp, sizeof(lts));
+	}
+	return (error);
+}
+
+static int
+linux_common_pselect6(struct thread *td, l_int nfds, l_fd_set *readfds,
+    l_fd_set *writefds, l_fd_set *exceptfds, struct timespec *tsp,
+    l_uintptr_t *sig)
 {
 	struct timeval utv, tv0, tv1, *tvp;
 	struct l_pselect6arg lpse6;
-	struct l_timespec lts;
-	struct timespec uts;
 	l_sigset_t l_ss;
 	sigset_t *ssp;
 	sigset_t ss;
 	int error;
 
 	ssp = NULL;
-	if (args->sig != NULL) {
-		error = copyin(args->sig, &lpse6, sizeof(lpse6));
+	if (sig != NULL) {
+		error = copyin(sig, &lpse6, sizeof(lpse6));
 		if (error != 0)
 			return (error);
 		if (lpse6.ss_len != sizeof(l_ss))
@@ -2372,21 +2406,15 @@ linux_pselect6(struct thread *td, struct linux_pselect6_args *args)
 			linux_to_bsd_sigset(&l_ss, &ss);
 			ssp = &ss;
 		}
-	}
+	} else
+		ssp = NULL;
 
 	/*
 	 * Currently glibc changes nanosecond number to microsecond.
 	 * This mean losing precision but for now it is hardly seen.
 	 */
-	if (args->tsp != NULL) {
-		error = copyin(args->tsp, &lts, sizeof(lts));
-		if (error != 0)
-			return (error);
-		error = linux_to_native_timespec(&uts, &lts);
-		if (error != 0)
-			return (error);
-
-		TIMESPEC_TO_TIMEVAL(&utv, &uts);
+	if (tsp != NULL) {
+		TIMESPEC_TO_TIMEVAL(&utv, tsp);
 		if (itimerfix(&utv))
 			return (EINVAL);
 
@@ -2395,10 +2423,10 @@ linux_pselect6(struct thread *td, struct linux_pselect6_args *args)
 	} else
 		tvp = NULL;
 
-	error = kern_pselect(td, args->nfds, args->readfds, args->writefds,
-	    args->exceptfds, tvp, ssp, LINUX_NFDBITS);
+	error = kern_pselect(td, nfds, readfds, writefds,
+	    exceptfds, tvp, ssp, LINUX_NFDBITS);
 
-	if (error == 0 && args->tsp != NULL) {
+	if (error == 0 && tsp != NULL) {
 		if (td->td_retval[0] != 0) {
 			/*
 			 * Compute how much time was left of the timeout,
@@ -2414,16 +2442,44 @@ linux_pselect6(struct thread *td, struct linux_pselect6_args *args)
 				timevalclear(&utv);
 		} else
 			timevalclear(&utv);
+		TIMEVAL_TO_TIMESPEC(&utv, tsp);
+	}
+	return (error);
+}
 
-		TIMEVAL_TO_TIMESPEC(&utv, &uts);
+#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
+int
+linux_pselect6_time64(struct thread *td,
+    struct linux_pselect6_time64_args *args)
+{
+	struct l_timespec64 lts;
+	struct timespec ts, *tsp;
+	int error;
 
-		error = native_to_linux_timespec(&lts, &uts);
+	if (args->tsp != NULL) {
+		error = copyin(args->tsp, &lts, sizeof(lts));
+		if (error != 0)
+			return (error);
+		error = linux_to_native_timespec64(&ts, &lts);
+		if (error != 0)
+			return (error);
+		tsp = &ts;
+	} else
+		tsp = NULL;
+
+	error = linux_common_pselect6(td, args->nfds, args->readfds,
+	    args->writefds, args->exceptfds, tsp, args->sig);
+	if (error != 0)
+		return (error);
+
+	if (args->tsp != NULL) {
+		error = native_to_linux_timespec64(&lts, tsp);
 		if (error == 0)
 			error = copyout(&lts, args->tsp, sizeof(lts));
 	}
-
 	return (error);
 }
+#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
 
 int
 linux_ppoll(struct thread *td, struct linux_ppoll_args *args)
diff --git a/sys/i386/linux/linux_dummy_machdep.c b/sys/i386/linux/linux_dummy_machdep.c
index a349fab5b637..67c70afa15b3 100644
--- a/sys/i386/linux/linux_dummy_machdep.c
+++ b/sys/i386/linux/linux_dummy_machdep.c
@@ -74,7 +74,6 @@ DUMMY(timer_gettime64);
 DUMMY(timer_settime64);
 DUMMY(timerfd_gettime64);
 DUMMY(timerfd_settime64);
-DUMMY(pselect6_time64);
 DUMMY(ppoll_time64);
 DUMMY(io_pgetevents_time64);
 DUMMY(recvmmsg_time64);
diff --git a/sys/i386/linux/syscalls.master b/sys/i386/linux/syscalls.master
index c42d9af0058d..056ac42eaad7 100644
--- a/sys/i386/linux/syscalls.master
+++ b/sys/i386/linux/syscalls.master
@@ -2408,7 +2408,14 @@
 		);
 	}
 413	AUE_NULL	STD {
-		int linux_pselect6_time64(void);
+		int linux_pselect6_time64(
+		    l_int nfds,
+		    l_fd_set *readfds,
+		    l_fd_set *writefds,
+		    l_fd_set *exceptfds,
+		    struct l_timespec64 *tsp,
+		    l_uintptr_t *sig
+		);
 	}
 414	AUE_NULL	STD {
 		int linux_ppoll_time64(void);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202106101204.15AC4pLP033439>