|
@@ -1082,8 +1082,66 @@ SYSCALL_DEFINE2(clock_adjtime, const clockid_t, which_clock,
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
+SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock,
|
|
|
+ struct timespec __user *, tp)
|
|
|
+{
|
|
|
+ const struct k_clock *kc = clockid_to_kclock(which_clock);
|
|
|
+ struct timespec64 rtn_tp64;
|
|
|
+ struct timespec rtn_tp;
|
|
|
+ int error;
|
|
|
+
|
|
|
+ if (!kc)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ error = kc->clock_getres(which_clock, &rtn_tp64);
|
|
|
+ rtn_tp = timespec64_to_timespec(rtn_tp64);
|
|
|
+
|
|
|
+ if (!error && tp && copy_to_user(tp, &rtn_tp, sizeof (rtn_tp)))
|
|
|
+ error = -EFAULT;
|
|
|
+
|
|
|
+ return error;
|
|
|
+}
|
|
|
+
|
|
|
#ifdef CONFIG_COMPAT
|
|
|
|
|
|
+COMPAT_SYSCALL_DEFINE2(clock_settime, clockid_t, which_clock,
|
|
|
+ struct compat_timespec __user *, tp)
|
|
|
+{
|
|
|
+ const struct k_clock *kc = clockid_to_kclock(which_clock);
|
|
|
+ struct timespec64 new_tp64;
|
|
|
+ struct timespec new_tp;
|
|
|
+
|
|
|
+ if (!kc || !kc->clock_set)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ if (compat_get_timespec(&new_tp, tp))
|
|
|
+ return -EFAULT;
|
|
|
+
|
|
|
+ new_tp64 = timespec_to_timespec64(new_tp);
|
|
|
+
|
|
|
+ return kc->clock_set(which_clock, &new_tp64);
|
|
|
+}
|
|
|
+
|
|
|
+COMPAT_SYSCALL_DEFINE2(clock_gettime, clockid_t, which_clock,
|
|
|
+ struct compat_timespec __user *, tp)
|
|
|
+{
|
|
|
+ const struct k_clock *kc = clockid_to_kclock(which_clock);
|
|
|
+ struct timespec64 kernel_tp64;
|
|
|
+ struct timespec kernel_tp;
|
|
|
+ int error;
|
|
|
+
|
|
|
+ if (!kc)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ error = kc->clock_get(which_clock, &kernel_tp64);
|
|
|
+ kernel_tp = timespec64_to_timespec(kernel_tp64);
|
|
|
+
|
|
|
+ if (!error && compat_put_timespec(&kernel_tp, tp))
|
|
|
+ error = -EFAULT;
|
|
|
+
|
|
|
+ return error;
|
|
|
+}
|
|
|
+
|
|
|
COMPAT_SYSCALL_DEFINE2(clock_adjtime, clockid_t, which_clock,
|
|
|
struct compat_timex __user *, utp)
|
|
|
{
|
|
@@ -1107,10 +1165,9 @@ COMPAT_SYSCALL_DEFINE2(clock_adjtime, clockid_t, which_clock,
|
|
|
|
|
|
return err;
|
|
|
}
|
|
|
-#endif
|
|
|
|
|
|
-SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock,
|
|
|
- struct timespec __user *, tp)
|
|
|
+COMPAT_SYSCALL_DEFINE2(clock_getres, clockid_t, which_clock,
|
|
|
+ struct compat_timespec __user *, tp)
|
|
|
{
|
|
|
const struct k_clock *kc = clockid_to_kclock(which_clock);
|
|
|
struct timespec64 rtn_tp64;
|
|
@@ -1123,11 +1180,12 @@ SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock,
|
|
|
error = kc->clock_getres(which_clock, &rtn_tp64);
|
|
|
rtn_tp = timespec64_to_timespec(rtn_tp64);
|
|
|
|
|
|
- if (!error && tp && copy_to_user(tp, &rtn_tp, sizeof (rtn_tp)))
|
|
|
+ if (!error && tp && compat_put_timespec(&rtn_tp, tp))
|
|
|
error = -EFAULT;
|
|
|
|
|
|
return error;
|
|
|
}
|
|
|
+#endif
|
|
|
|
|
|
/*
|
|
|
* nanosleep for monotonic and realtime clocks
|