[PATCH 3/8] kernel: compat: Move clock and timer compat syscalls
From: Deepa Dinamani
Date: Mon Jun 19 2017 - 02:45:52 EST
Move the compat syscall handling to the files that
handle the native syscalls.
The move helps for code reusability by helping same
functions be used in both compat and native syscall
handling paths.
In this series, this servers as a preparatory patch to
eliminate the use of set_fs()/get_fs() in the compat
syscall path.
Note that the clock compat syscalls have to be moved
twice, once into each file: posix_timers.c and posix-stubs.c.
Signed-off-by: Deepa Dinamani <deepa.kernel@xxxxxxxxx>
---
kernel/compat.c | 91 ---------------------------------------------
kernel/time/posix-stubs.c | 55 +++++++++++++++++++++++++++
kernel/time/posix-timers.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 147 insertions(+), 91 deletions(-)
diff --git a/kernel/compat.c b/kernel/compat.c
index 89d10cf47e9c..d6559c0c69b0 100644
--- a/kernel/compat.c
+++ b/kernel/compat.c
@@ -675,80 +675,6 @@ COMPAT_SYSCALL_DEFINE3(timer_create, clockid_t, which_clock,
return sys_timer_create(which_clock, event, created_timer_id);
}
-COMPAT_SYSCALL_DEFINE4(timer_settime, timer_t, timer_id, int, flags,
- struct compat_itimerspec __user *, new,
- struct compat_itimerspec __user *, old)
-{
- long err;
- mm_segment_t oldfs;
- struct itimerspec newts, oldts;
-
- if (!new)
- return -EINVAL;
- if (get_compat_itimerspec(&newts, new))
- return -EFAULT;
- oldfs = get_fs();
- set_fs(KERNEL_DS);
- err = sys_timer_settime(timer_id, flags,
- (struct itimerspec __user *) &newts,
- (struct itimerspec __user *) &oldts);
- set_fs(oldfs);
- if (!err && old && put_compat_itimerspec(old, &oldts))
- return -EFAULT;
- return err;
-}
-
-COMPAT_SYSCALL_DEFINE2(timer_gettime, timer_t, timer_id,
- struct compat_itimerspec __user *, setting)
-{
- long err;
- mm_segment_t oldfs;
- struct itimerspec ts;
-
- oldfs = get_fs();
- set_fs(KERNEL_DS);
- err = sys_timer_gettime(timer_id,
- (struct itimerspec __user *) &ts);
- set_fs(oldfs);
- if (!err && put_compat_itimerspec(setting, &ts))
- return -EFAULT;
- return err;
-}
-
-COMPAT_SYSCALL_DEFINE2(clock_settime, clockid_t, which_clock,
- struct compat_timespec __user *, tp)
-{
- long err;
- mm_segment_t oldfs;
- struct timespec ts;
-
- if (compat_get_timespec(&ts, tp))
- return -EFAULT;
- oldfs = get_fs();
- set_fs(KERNEL_DS);
- err = sys_clock_settime(which_clock,
- (struct timespec __user *) &ts);
- set_fs(oldfs);
- return err;
-}
-
-COMPAT_SYSCALL_DEFINE2(clock_gettime, clockid_t, which_clock,
- struct compat_timespec __user *, tp)
-{
- long err;
- mm_segment_t oldfs;
- struct timespec ts;
-
- oldfs = get_fs();
- set_fs(KERNEL_DS);
- err = sys_clock_gettime(which_clock,
- (struct timespec __user *) &ts);
- set_fs(oldfs);
- if (!err && compat_put_timespec(&ts, tp))
- return -EFAULT;
- return err;
-}
-
COMPAT_SYSCALL_DEFINE2(clock_adjtime, clockid_t, which_clock,
struct compat_timex __user *, utp)
{
@@ -772,23 +698,6 @@ COMPAT_SYSCALL_DEFINE2(clock_adjtime, clockid_t, which_clock,
return ret;
}
-COMPAT_SYSCALL_DEFINE2(clock_getres, clockid_t, which_clock,
- struct compat_timespec __user *, tp)
-{
- long err;
- mm_segment_t oldfs;
- struct timespec ts;
-
- oldfs = get_fs();
- set_fs(KERNEL_DS);
- err = sys_clock_getres(which_clock,
- (struct timespec __user *) &ts);
- set_fs(oldfs);
- if (!err && tp && compat_put_timespec(&ts, tp))
- return -EFAULT;
- return err;
-}
-
/*
* We currently only need the following fields from the sigevent
* structure: sigev_value, sigev_signo, sig_notify and (sometimes
diff --git a/kernel/time/posix-stubs.c b/kernel/time/posix-stubs.c
index 3031a28921ba..cd1b9a2e2618 100644
--- a/kernel/time/posix-stubs.c
+++ b/kernel/time/posix-stubs.c
@@ -125,6 +125,61 @@ SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags,
}
#ifdef CONFIG_COMPAT
+#define COMPAT_SYS_NI(name) SYSCALL_ALIAS(compat_sys_##name, sys_ni_posix_timers)
+COMPAT_SYS_NI(timer_gettime);
+COMPAT_SYS_NI(timer_settime);
+
+COMPAT_SYSCALL_DEFINE2(clock_settime, clockid_t, which_clock,
+ struct compat_timespec __user *, tp)
+{
+ long err;
+ mm_segment_t oldfs;
+ struct timespec ts;
+
+ if (compat_get_timespec(&ts, tp))
+ return -EFAULT;
+ oldfs = get_fs();
+ set_fs(KERNEL_DS);
+ err = sys_clock_settime(which_clock,
+ (struct timespec __user *) &ts);
+ set_fs(oldfs);
+ return err;
+}
+
+COMPAT_SYSCALL_DEFINE2(clock_gettime, clockid_t, which_clock,
+ struct compat_timespec __user *, tp)
+{
+ long err;
+ mm_segment_t oldfs;
+ struct timespec ts;
+
+ oldfs = get_fs();
+ set_fs(KERNEL_DS);
+ err = sys_clock_gettime(which_clock,
+ (struct timespec __user *) &ts);
+ set_fs(oldfs);
+ if (!err && compat_put_timespec(&ts, tp))
+ return -EFAULT;
+ return err;
+}
+
+COMPAT_SYSCALL_DEFINE2(clock_getres, clockid_t, which_clock,
+ struct compat_timespec __user *, tp)
+{
+ long err;
+ mm_segment_t oldfs;
+ struct timespec ts;
+
+ oldfs = get_fs();
+ set_fs(KERNEL_DS);
+ err = sys_clock_getres(which_clock,
+ (struct timespec __user *) &ts);
+ set_fs(oldfs);
+ if (!err && tp && compat_put_timespec(&ts, tp))
+ return -EFAULT;
+ return err;
+}
+
long clock_nanosleep_restart(struct restart_block *restart_block)
{
return hrtimer_nanosleep_restart(restart_block);
diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c
index cf32adccd062..009a9145d64d 100644
--- a/kernel/time/posix-timers.c
+++ b/kernel/time/posix-timers.c
@@ -1233,4 +1233,96 @@ COMPAT_SYSCALL_DEFINE4(clock_nanosleep, clockid_t, which_clock, int, flags,
}
return err;
}
+
+COMPAT_SYSCALL_DEFINE4(timer_settime, timer_t, timer_id, int, flags,
+ struct compat_itimerspec __user *, new,
+ struct compat_itimerspec __user *, old)
+{
+ long err;
+ mm_segment_t oldfs;
+ struct itimerspec newts, oldts;
+
+ if (!new)
+ return -EINVAL;
+ if (get_compat_itimerspec(&newts, new))
+ return -EFAULT;
+ oldfs = get_fs();
+ set_fs(KERNEL_DS);
+ err = sys_timer_settime(timer_id, flags,
+ (struct itimerspec __user *) &newts,
+ (struct itimerspec __user *) &oldts);
+ set_fs(oldfs);
+ if (!err && old && put_compat_itimerspec(old, &oldts))
+ return -EFAULT;
+ return err;
+}
+
+COMPAT_SYSCALL_DEFINE2(timer_gettime, timer_t, timer_id,
+ struct compat_itimerspec __user *, setting)
+{
+ long err;
+ mm_segment_t oldfs;
+ struct itimerspec ts;
+
+ oldfs = get_fs();
+ set_fs(KERNEL_DS);
+ err = sys_timer_gettime(timer_id,
+ (struct itimerspec __user *) &ts);
+ set_fs(oldfs);
+ if (!err && put_compat_itimerspec(setting, &ts))
+ return -EFAULT;
+ return err;
+}
+
+COMPAT_SYSCALL_DEFINE2(clock_settime, clockid_t, which_clock,
+ struct compat_timespec __user *, tp)
+{
+ long err;
+ mm_segment_t oldfs;
+ struct timespec ts;
+
+ if (compat_get_timespec(&ts, tp))
+ return -EFAULT;
+ oldfs = get_fs();
+ set_fs(KERNEL_DS);
+ err = sys_clock_settime(which_clock,
+ (struct timespec __user *) &ts);
+ set_fs(oldfs);
+ return err;
+}
+
+COMPAT_SYSCALL_DEFINE2(clock_gettime, clockid_t, which_clock,
+ struct compat_timespec __user *, tp)
+{
+ long err;
+ mm_segment_t oldfs;
+ struct timespec ts;
+
+ oldfs = get_fs();
+ set_fs(KERNEL_DS);
+ err = sys_clock_gettime(which_clock,
+ (struct timespec __user *) &ts);
+ set_fs(oldfs);
+ if (!err && compat_put_timespec(&ts, tp))
+ return -EFAULT;
+ return err;
+}
+
+COMPAT_SYSCALL_DEFINE2(clock_getres, clockid_t, which_clock,
+ struct compat_timespec __user *, tp)
+{
+ long err;
+ mm_segment_t oldfs;
+ struct timespec ts;
+
+ oldfs = get_fs();
+ set_fs(KERNEL_DS);
+ err = sys_clock_getres(which_clock,
+ (struct timespec __user *) &ts);
+ set_fs(oldfs);
+ if (!err && tp && compat_put_timespec(&ts, tp))
+ return -EFAULT;
+ return err;
+}
+
#endif
--
2.11.0