aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Chagin <dchagin@FreeBSD.org>2021-06-07 02:26:48 +0000
committerDmitry Chagin <dchagin@FreeBSD.org>2021-06-07 02:26:48 +0000
commit6501370a7dfb358daf07555136742bc064e68cb7 (patch)
tree469a75814b5ce22e9729ab989d277a588710c98a
parent773d9153c37a709d5c12bc8abe9166e1d044c01b (diff)
downloadsrc-6501370a7dfb358daf07555136742bc064e68cb7.tar.gz
src-6501370a7dfb358daf07555136742bc064e68cb7.zip
linux(4): Implement clock_nanosleep_time64 system call.
MFC after: 2 weeks
-rw-r--r--sys/amd64/linux32/linux32_dummy_machdep.c1
-rw-r--r--sys/amd64/linux32/syscalls.master7
-rw-r--r--sys/compat/linux/linux_time.c109
-rw-r--r--sys/i386/linux/linux_dummy_machdep.c1
-rw-r--r--sys/i386/linux/syscalls.master7
5 files changed, 99 insertions, 26 deletions
diff --git a/sys/amd64/linux32/linux32_dummy_machdep.c b/sys/amd64/linux32/linux32_dummy_machdep.c
index 3f8dfe711dba..041156bd514b 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(clock_nanosleep_time64);
DUMMY(timer_gettime64);
DUMMY(timer_settime64);
DUMMY(timerfd_gettime64);
diff --git a/sys/amd64/linux32/syscalls.master b/sys/amd64/linux32/syscalls.master
index 27034c0216ff..d3a124c6e8c2 100644
--- a/sys/amd64/linux32/syscalls.master
+++ b/sys/amd64/linux32/syscalls.master
@@ -2362,7 +2362,12 @@
);
}
407 AUE_NULL STD {
- int linux_clock_nanosleep_time64(void);
+ int linux_clock_nanosleep_time64(
+ clockid_t which,
+ l_int flags,
+ struct l_timespec64 *rqtp,
+ struct l_timespec64 *rmtp
+ );
}
408 AUE_NULL STD {
int linux_timer_gettime64(void);
diff --git a/sys/compat/linux/linux_time.c b/sys/compat/linux/linux_time.c
index 43db8871a0d8..184de336fd99 100644
--- a/sys/compat/linux/linux_time.c
+++ b/sys/compat/linux/linux_time.c
@@ -107,8 +107,13 @@ LIN_SDT_PROBE_DEFINE1(time, linux_nanosleep, copyin_error, "int");
LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, conversion_error, "int");
LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, copyout_error, "int");
LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, copyin_error, "int");
-LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, unsupported_flags, "int");
-LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, unsupported_clockid, "int");
+LIN_SDT_PROBE_DEFINE1(time, linux_common_clock_nanosleep, unsupported_flags, "int");
+LIN_SDT_PROBE_DEFINE1(time, linux_common_clock_nanosleep, unsupported_clockid, "int");
+#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
+LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep_time64, conversion_error, "int");
+LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep_time64, copyout_error, "int");
+LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep_time64, copyin_error, "int");
+#endif
static int linux_common_clock_gettime(struct thread *, clockid_t,
struct timespec *);
@@ -116,6 +121,8 @@ static int linux_common_clock_settime(struct thread *, clockid_t,
struct timespec *);
static int linux_common_clock_getres(struct thread *, clockid_t,
struct timespec *);
+static int linux_common_clock_nanosleep(struct thread *, clockid_t,
+ l_int, struct timespec *, struct timespec *);
int
native_to_linux_timespec(struct l_timespec *ltp, struct timespec *ntp)
@@ -672,31 +679,41 @@ linux_nanosleep(struct thread *td, struct linux_nanosleep_args *args)
return (error);
}
-int
-linux_clock_nanosleep(struct thread *td, struct linux_clock_nanosleep_args *args)
+static int
+linux_common_clock_nanosleep(struct thread *td, clockid_t which,
+ l_int lflags, struct timespec *rqtp, struct timespec *rmtp)
{
- struct timespec *rmtp;
- struct l_timespec lrqts, lrmts;
- struct timespec rqts, rmts;
- int error, error2, flags;
+ int error, flags;
clockid_t clockid;
- error = linux_to_native_timerflags(&flags, args->flags);
+ error = linux_to_native_timerflags(&flags, lflags);
if (error != 0) {
- LIN_SDT_PROBE1(time, linux_clock_nanosleep, unsupported_flags,
- args->flags);
+ LIN_SDT_PROBE1(time, linux_common_clock_nanosleep,
+ unsupported_flags, lflags);
return (error);
}
- error = linux_to_native_clockid(&clockid, args->which);
+ error = linux_to_native_clockid(&clockid, which);
if (error != 0) {
linux_msg(curthread,
- "unsupported clock_nanosleep clockid %d", args->which);
- LIN_SDT_PROBE1(time, linux_clock_nanosleep, unsupported_clockid,
- args->which);
+ "unsupported clock_nanosleep clockid %d", which);
+ LIN_SDT_PROBE1(time, linux_common_clock_nanosleep,
+ unsupported_clockid, which);
return (error);
}
+ return (kern_clock_nanosleep(td, clockid, flags, rqtp, rmtp));
+}
+
+int
+linux_clock_nanosleep(struct thread *td,
+ struct linux_clock_nanosleep_args *args)
+{
+ struct timespec *rmtp;
+ struct l_timespec lrqts, lrmts;
+ struct timespec rqts, rmts;
+ int error, error2;
+
error = copyin(args->rqtp, &lrqts, sizeof(lrqts));
if (error != 0) {
LIN_SDT_PROBE1(time, linux_clock_nanosleep, copyin_error,
@@ -704,19 +721,21 @@ linux_clock_nanosleep(struct thread *td, struct linux_clock_nanosleep_args *args
return (error);
}
- if (args->rmtp != NULL)
- rmtp = &rmts;
- else
- rmtp = NULL;
-
error = linux_to_native_timespec(&rqts, &lrqts);
if (error != 0) {
LIN_SDT_PROBE1(time, linux_clock_nanosleep, conversion_error,
error);
return (error);
}
- error = kern_clock_nanosleep(td, clockid, flags, &rqts, rmtp);
- if (error == EINTR && (flags & TIMER_ABSTIME) == 0 &&
+
+ if (args->rmtp != NULL)
+ rmtp = &rmts;
+ else
+ rmtp = NULL;
+
+ error = linux_common_clock_nanosleep(td, args->which, args->flags,
+ &rqts, rmtp);
+ if (error == EINTR && (args->flags & LINUX_TIMER_ABSTIME) == 0 &&
args->rmtp != NULL) {
error2 = native_to_linux_timespec(&lrmts, rmtp);
if (error2 != 0)
@@ -728,6 +747,52 @@ linux_clock_nanosleep(struct thread *td, struct linux_clock_nanosleep_args *args
return (error2);
}
}
+ return (error);
+}
+#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
+int
+linux_clock_nanosleep_time64(struct thread *td,
+ struct linux_clock_nanosleep_time64_args *args)
+{
+ struct timespec *rmtp;
+ struct l_timespec64 lrqts, lrmts;
+ struct timespec rqts, rmts;
+ int error, error2;
+
+ error = copyin(args->rqtp, &lrqts, sizeof(lrqts));
+ if (error != 0) {
+ LIN_SDT_PROBE1(time, linux_clock_nanosleep_time64,
+ copyin_error, error);
+ return (error);
+ }
+
+ error = linux_to_native_timespec64(&rqts, &lrqts);
+ if (error != 0) {
+ LIN_SDT_PROBE1(time, linux_clock_nanosleep_time64,
+ conversion_error, error);
+ return (error);
+ }
+
+ if (args->rmtp != NULL)
+ rmtp = &rmts;
+ else
+ rmtp = NULL;
+
+ error = linux_common_clock_nanosleep(td, args->which, args->flags,
+ &rqts, rmtp);
+ if (error == EINTR && (args->flags & LINUX_TIMER_ABSTIME) == 0 &&
+ args->rmtp != NULL) {
+ error2 = native_to_linux_timespec64(&lrmts, rmtp);
+ if (error2 != 0)
+ return (error2);
+ error2 = copyout(&lrmts, args->rmtp, sizeof(lrmts));
+ if (error2 != 0) {
+ LIN_SDT_PROBE1(time, linux_clock_nanosleep_time64,
+ copyout_error, error2);
+ return (error2);
+ }
+ }
return (error);
}
+#endif
diff --git a/sys/i386/linux/linux_dummy_machdep.c b/sys/i386/linux/linux_dummy_machdep.c
index 6e4c9c66edcb..f679e090c7c1 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(clock_nanosleep_time64);
DUMMY(timer_gettime64);
DUMMY(timer_settime64);
DUMMY(timerfd_gettime64);
diff --git a/sys/i386/linux/syscalls.master b/sys/i386/linux/syscalls.master
index 0876a039ea05..7e1ab24e9f75 100644
--- a/sys/i386/linux/syscalls.master
+++ b/sys/i386/linux/syscalls.master
@@ -2380,7 +2380,12 @@
);
}
407 AUE_NULL STD {
- int linux_clock_nanosleep_time64(void);
+ int linux_clock_nanosleep_time64(
+ clockid_t which,
+ l_int flags,
+ struct l_timespec64 *rqtp,
+ struct l_timespec64 *rmtp
+ );
}
408 AUE_NULL STD {
int linux_timer_gettime64(void);