git: a1fd2911ddb0 - main - linux(4): Implement timer_settime64 syscall.

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

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

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

    linux(4): Implement timer_settime64 syscall.
    
    MFC after:              2 weeks
---
 sys/amd64/linux32/linux32_dummy_machdep.c |  1 -
 sys/compat/linux/linux_timer.c            | 44 +++++++++++++++++++++++++++----
 sys/i386/linux/linux_dummy_machdep.c      |  1 -
 3 files changed, 39 insertions(+), 7 deletions(-)

diff --git a/sys/amd64/linux32/linux32_dummy_machdep.c b/sys/amd64/linux32/linux32_dummy_machdep.c
index d6e4d89d573a..7dbc3352b07d 100644
--- a/sys/amd64/linux32/linux32_dummy_machdep.c
+++ b/sys/amd64/linux32/linux32_dummy_machdep.c
@@ -68,7 +68,6 @@ DUMMY(mq_getsetattr);
 DUMMY(arch_prctl);
 /* Linux 5.0: */
 DUMMY(clock_adjtime64);
-DUMMY(timer_settime64);
 DUMMY(timerfd_gettime64);
 DUMMY(timerfd_settime64);
 DUMMY(io_pgetevents_time64);
diff --git a/sys/compat/linux/linux_timer.c b/sys/compat/linux/linux_timer.c
index 83c099fbc800..3e844704f132 100644
--- a/sys/compat/linux/linux_timer.c
+++ b/sys/compat/linux/linux_timer.c
@@ -123,20 +123,54 @@ linux_timer_settime(struct thread *td, struct linux_timer_settime_args *uap)
 {
 	struct l_itimerspec l_val, l_oval;
 	struct itimerspec val, oval, *ovalp;
-	int error;
+	int flags, error;
+
+	error = copyin(uap->new, &l_val, sizeof(l_val));
+	if (error != 0)
+		return (error);
+	error = linux_to_native_itimerspec(&val, &l_val);
+	if (error != 0)
+		return (error);
+	ovalp = uap->old != NULL ? &oval : NULL;
+	error = linux_to_native_timerflags(&flags, uap->flags);
+	if (error != 0)
+		return (error);
+	error = kern_ktimer_settime(td, uap->timerid, flags, &val, ovalp);
+	if (error == 0 && uap->old != NULL) {
+		error = native_to_linux_itimerspec(&l_val, &val);
+		if (error == 0)
+			error = copyout(&l_oval, uap->old, sizeof(l_oval));
+	}
+	return (error);
+}
+
+#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
+int
+linux_timer_settime64(struct thread *td, struct linux_timer_settime64_args *uap)
+{
+	struct l_itimerspec64 l_val, l_oval;
+	struct itimerspec val, oval, *ovalp;
+	int flags, error;
 
 	error = copyin(uap->new, &l_val, sizeof(l_val));
 	if (error != 0)
 		return (error);
-	ITS_CP(l_val, val);
+	error = linux_to_native_itimerspec64(&val, &l_val);
+	if (error != 0)
+		return (error);
 	ovalp = uap->old != NULL ? &oval : NULL;
-	error = kern_ktimer_settime(td, uap->timerid, uap->flags, &val, ovalp);
+	error = linux_to_native_timerflags(&flags, uap->flags);
+	if (error != 0)
+		return (error);
+	error = kern_ktimer_settime(td, uap->timerid, flags, &val, ovalp);
 	if (error == 0 && uap->old != NULL) {
-		ITS_CP(oval, l_oval);
-		error = copyout(&l_oval, uap->old, sizeof(l_oval));
+		error = native_to_linux_itimerspec64(&l_val, &val);
+		if (error == 0)
+			error = copyout(&l_oval, uap->old, sizeof(l_oval));
 	}
 	return (error);
 }
+#endif
 
 int
 linux_timer_gettime(struct thread *td, struct linux_timer_gettime_args *uap)
diff --git a/sys/i386/linux/linux_dummy_machdep.c b/sys/i386/linux/linux_dummy_machdep.c
index 57edba56004f..f4280da8df16 100644
--- a/sys/i386/linux/linux_dummy_machdep.c
+++ b/sys/i386/linux/linux_dummy_machdep.c
@@ -70,7 +70,6 @@ DUMMY(vm86old);
 DUMMY(arch_prctl);
 /* Linux 5.0: */
 DUMMY(clock_adjtime64);
-DUMMY(timer_settime64);
 DUMMY(timerfd_gettime64);
 DUMMY(timerfd_settime64);
 DUMMY(io_pgetevents_time64);