Commit 1f9b37bf authored by Andrei Vagin's avatar Andrei Vagin Committed by Thomas Gleixner

posix-timers: Make clock_nanosleep() time namespace aware

clock_nanosleep() accepts absolute values of expiration time, if the
TIMER_ABSTIME flag is set. This value is in the tasks time namespace,
which has to be converted to the host time namespace.
Co-developed-by: default avatarDmitry Safonov <dima@arista.com>
Signed-off-by: default avatarAndrei Vagin <avagin@openvz.org>
Signed-off-by: default avatarDmitry Safonov <dima@arista.com>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/20191112012724.250792-18-dima@arista.com
parent ea2d1f7f
...@@ -129,6 +129,7 @@ SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags, ...@@ -129,6 +129,7 @@ SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags,
struct __kernel_timespec __user *, rmtp) struct __kernel_timespec __user *, rmtp)
{ {
struct timespec64 t; struct timespec64 t;
ktime_t texp;
switch (which_clock) { switch (which_clock) {
case CLOCK_REALTIME: case CLOCK_REALTIME:
...@@ -147,7 +148,10 @@ SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags, ...@@ -147,7 +148,10 @@ SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags,
rmtp = NULL; rmtp = NULL;
current->restart_block.nanosleep.type = rmtp ? TT_NATIVE : TT_NONE; current->restart_block.nanosleep.type = rmtp ? TT_NATIVE : TT_NONE;
current->restart_block.nanosleep.rmtp = rmtp; current->restart_block.nanosleep.rmtp = rmtp;
return hrtimer_nanosleep(timespec64_to_ktime(t), flags & TIMER_ABSTIME ? texp = timespec64_to_ktime(t);
if (flags & TIMER_ABSTIME)
texp = timens_ktime_to_host(which_clock, texp);
return hrtimer_nanosleep(texp, flags & TIMER_ABSTIME ?
HRTIMER_MODE_ABS : HRTIMER_MODE_REL, HRTIMER_MODE_ABS : HRTIMER_MODE_REL,
which_clock); which_clock);
} }
...@@ -218,6 +222,7 @@ SYSCALL_DEFINE4(clock_nanosleep_time32, clockid_t, which_clock, int, flags, ...@@ -218,6 +222,7 @@ SYSCALL_DEFINE4(clock_nanosleep_time32, clockid_t, which_clock, int, flags,
struct old_timespec32 __user *, rmtp) struct old_timespec32 __user *, rmtp)
{ {
struct timespec64 t; struct timespec64 t;
ktime_t texp;
switch (which_clock) { switch (which_clock) {
case CLOCK_REALTIME: case CLOCK_REALTIME:
...@@ -236,7 +241,10 @@ SYSCALL_DEFINE4(clock_nanosleep_time32, clockid_t, which_clock, int, flags, ...@@ -236,7 +241,10 @@ SYSCALL_DEFINE4(clock_nanosleep_time32, clockid_t, which_clock, int, flags,
rmtp = NULL; rmtp = NULL;
current->restart_block.nanosleep.type = rmtp ? TT_COMPAT : TT_NONE; current->restart_block.nanosleep.type = rmtp ? TT_COMPAT : TT_NONE;
current->restart_block.nanosleep.compat_rmtp = rmtp; current->restart_block.nanosleep.compat_rmtp = rmtp;
return hrtimer_nanosleep(timespec64_to_ktime(t), flags & TIMER_ABSTIME ? texp = timespec64_to_ktime(t);
if (flags & TIMER_ABSTIME)
texp = timens_ktime_to_host(which_clock, texp);
return hrtimer_nanosleep(texp, flags & TIMER_ABSTIME ?
HRTIMER_MODE_ABS : HRTIMER_MODE_REL, HRTIMER_MODE_ABS : HRTIMER_MODE_REL,
which_clock); which_clock);
} }
......
...@@ -1228,6 +1228,19 @@ static int common_nsleep(const clockid_t which_clock, int flags, ...@@ -1228,6 +1228,19 @@ static int common_nsleep(const clockid_t which_clock, int flags,
which_clock); which_clock);
} }
static int common_nsleep_timens(const clockid_t which_clock, int flags,
const struct timespec64 *rqtp)
{
ktime_t texp = timespec64_to_ktime(*rqtp);
if (flags & TIMER_ABSTIME)
texp = timens_ktime_to_host(which_clock, texp);
return hrtimer_nanosleep(texp, flags & TIMER_ABSTIME ?
HRTIMER_MODE_ABS : HRTIMER_MODE_REL,
which_clock);
}
SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags, SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags,
const struct __kernel_timespec __user *, rqtp, const struct __kernel_timespec __user *, rqtp,
struct __kernel_timespec __user *, rmtp) struct __kernel_timespec __user *, rmtp)
...@@ -1305,7 +1318,7 @@ static const struct k_clock clock_monotonic = { ...@@ -1305,7 +1318,7 @@ static const struct k_clock clock_monotonic = {
.clock_getres = posix_get_hrtimer_res, .clock_getres = posix_get_hrtimer_res,
.clock_get_timespec = posix_get_monotonic_timespec, .clock_get_timespec = posix_get_monotonic_timespec,
.clock_get_ktime = posix_get_monotonic_ktime, .clock_get_ktime = posix_get_monotonic_ktime,
.nsleep = common_nsleep, .nsleep = common_nsleep_timens,
.timer_create = common_timer_create, .timer_create = common_timer_create,
.timer_set = common_timer_set, .timer_set = common_timer_set,
.timer_get = common_timer_get, .timer_get = common_timer_get,
...@@ -1354,7 +1367,7 @@ static const struct k_clock clock_boottime = { ...@@ -1354,7 +1367,7 @@ static const struct k_clock clock_boottime = {
.clock_getres = posix_get_hrtimer_res, .clock_getres = posix_get_hrtimer_res,
.clock_get_ktime = posix_get_boottime_ktime, .clock_get_ktime = posix_get_boottime_ktime,
.clock_get_timespec = posix_get_boottime_timespec, .clock_get_timespec = posix_get_boottime_timespec,
.nsleep = common_nsleep, .nsleep = common_nsleep_timens,
.timer_create = common_timer_create, .timer_create = common_timer_create,
.timer_set = common_timer_set, .timer_set = common_timer_set,
.timer_get = common_timer_get, .timer_get = common_timer_get,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment