aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/time/posix-cpu-timers.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2017-06-07 09:42:31 +0100
committerThomas Gleixner <tglx@linutronix.de>2017-06-14 00:00:42 +0200
commitedbeda46322fbcb15af2d2d0f2daffb0cd349a5a (patch)
treea4aa5436d4e5dcce6f4d041d13c521e1660331b7 /kernel/time/posix-cpu-timers.c
parentposix-timers: Store rmtp into restart_block in sys_clock_nanosleep() (diff)
downloadlinux-dev-edbeda46322fbcb15af2d2d0f2daffb0cd349a5a.tar.xz
linux-dev-edbeda46322fbcb15af2d2d0f2daffb0cd349a5a.zip
time/posix-timers: Move the compat copyouts to the nanosleep implementations
Turn restart_block.nanosleep.{rmtp,compat_rmtp} into a tagged union (kind = 1 -> native, kind = 2 -> compat, kind = 0 -> nothing) and make the places doing actual copyout handle compat as well as native (that will become a helper in the next commit). Result: compat wrappers, messing with reassignments, etc. are gone. [ tglx: Folded in a variant of Peter Zijlstras enum patch ] Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: John Stultz <john.stultz@linaro.org> Cc: Peter Zijlstra <peterz@infradead.org> Link: http://lkml.kernel.org/r/20170607084241.28657-6-viro@ZenIV.linux.org.uk
Diffstat (limited to 'kernel/time/posix-cpu-timers.c')
-rw-r--r--kernel/time/posix-cpu-timers.c20
1 files changed, 14 insertions, 6 deletions
diff --git a/kernel/time/posix-cpu-timers.c b/kernel/time/posix-cpu-timers.c
index ec6258c9cde5..1563ca22cf1f 100644
--- a/kernel/time/posix-cpu-timers.c
+++ b/kernel/time/posix-cpu-timers.c
@@ -12,6 +12,7 @@
#include <trace/events/timer.h>
#include <linux/tick.h>
#include <linux/workqueue.h>
+#include <linux/compat.h>
#include "posix-timers.h"
@@ -1243,10 +1244,9 @@ static int do_cpu_nanosleep(const clockid_t which_clock, int flags,
timer.it_process = current;
if (!error) {
static struct itimerspec64 zero_it;
- struct restart_block *restart = &current->restart_block;
- struct timespec __user *rmtp;
+ struct restart_block *restart;
- memset(&it, 0, sizeof it);
+ memset(&it, 0, sizeof(it));
it.it_value = *rqtp;
spin_lock_irq(&timer.it_lock);
@@ -1311,12 +1311,20 @@ static int do_cpu_nanosleep(const clockid_t which_clock, int flags,
/*
* Report back to the user the time still remaining.
*/
- rmtp = restart->nanosleep.rmtp;
- if (rmtp) {
+ restart = &current->restart_block;
+ if (restart->nanosleep.type != TT_NONE) {
struct timespec ts;
ts = timespec64_to_timespec(it.it_value);
- if (copy_to_user(rmtp, &ts, sizeof(*rmtp)))
+#ifdef CONFIG_COMPAT
+ if (restart->nanosleep.type == TT_COMPAT) {
+ if (compat_put_timespec(&ts,
+ restart->nanosleep.compat_rmtp))
+ return -EFAULT;
+ } else
+#endif
+ if (copy_to_user(restart->nanosleep.rmtp, &ts,
+ sizeof(ts)))
return -EFAULT;
}
restart->nanosleep.expires = timespec64_to_ns(rqtp);