aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/time/posix-cpu-timers.c
diff options
context:
space:
mode:
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);