Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Dmitry Safonov <dima@arista.com>
Signed-off-by: Andrei Vagin <avagin@openvz.org>
Signed-off-by: Dmitry Safonov <dima@arista.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/20191112012724.250792-18-dima@arista.com


authored by

Andrei Vagin and committed by
Thomas Gleixner
1f9b37bf ea2d1f7f

+25 -4
+10 -2
kernel/time/posix-stubs.c
··· 129 129 struct __kernel_timespec __user *, rmtp) 130 130 { 131 131 struct timespec64 t; 132 + ktime_t texp; 132 133 133 134 switch (which_clock) { 134 135 case CLOCK_REALTIME: ··· 148 147 rmtp = NULL; 149 148 current->restart_block.nanosleep.type = rmtp ? TT_NATIVE : TT_NONE; 150 149 current->restart_block.nanosleep.rmtp = rmtp; 151 - return hrtimer_nanosleep(timespec64_to_ktime(t), flags & TIMER_ABSTIME ? 150 + texp = timespec64_to_ktime(t); 151 + if (flags & TIMER_ABSTIME) 152 + texp = timens_ktime_to_host(which_clock, texp); 153 + return hrtimer_nanosleep(texp, flags & TIMER_ABSTIME ? 152 154 HRTIMER_MODE_ABS : HRTIMER_MODE_REL, 153 155 which_clock); 154 156 } ··· 222 218 struct old_timespec32 __user *, rmtp) 223 219 { 224 220 struct timespec64 t; 221 + ktime_t texp; 225 222 226 223 switch (which_clock) { 227 224 case CLOCK_REALTIME: ··· 241 236 rmtp = NULL; 242 237 current->restart_block.nanosleep.type = rmtp ? TT_COMPAT : TT_NONE; 243 238 current->restart_block.nanosleep.compat_rmtp = rmtp; 244 - return hrtimer_nanosleep(timespec64_to_ktime(t), flags & TIMER_ABSTIME ? 239 + texp = timespec64_to_ktime(t); 240 + if (flags & TIMER_ABSTIME) 241 + texp = timens_ktime_to_host(which_clock, texp); 242 + return hrtimer_nanosleep(texp, flags & TIMER_ABSTIME ? 245 243 HRTIMER_MODE_ABS : HRTIMER_MODE_REL, 246 244 which_clock); 247 245 }
+15 -2
kernel/time/posix-timers.c
··· 1228 1228 which_clock); 1229 1229 } 1230 1230 1231 + static int common_nsleep_timens(const clockid_t which_clock, int flags, 1232 + const struct timespec64 *rqtp) 1233 + { 1234 + ktime_t texp = timespec64_to_ktime(*rqtp); 1235 + 1236 + if (flags & TIMER_ABSTIME) 1237 + texp = timens_ktime_to_host(which_clock, texp); 1238 + 1239 + return hrtimer_nanosleep(texp, flags & TIMER_ABSTIME ? 1240 + HRTIMER_MODE_ABS : HRTIMER_MODE_REL, 1241 + which_clock); 1242 + } 1243 + 1231 1244 SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags, 1232 1245 const struct __kernel_timespec __user *, rqtp, 1233 1246 struct __kernel_timespec __user *, rmtp) ··· 1318 1305 .clock_getres = posix_get_hrtimer_res, 1319 1306 .clock_get_timespec = posix_get_monotonic_timespec, 1320 1307 .clock_get_ktime = posix_get_monotonic_ktime, 1321 - .nsleep = common_nsleep, 1308 + .nsleep = common_nsleep_timens, 1322 1309 .timer_create = common_timer_create, 1323 1310 .timer_set = common_timer_set, 1324 1311 .timer_get = common_timer_get, ··· 1367 1354 .clock_getres = posix_get_hrtimer_res, 1368 1355 .clock_get_ktime = posix_get_boottime_ktime, 1369 1356 .clock_get_timespec = posix_get_boottime_timespec, 1370 - .nsleep = common_nsleep, 1357 + .nsleep = common_nsleep_timens, 1371 1358 .timer_create = common_timer_create, 1372 1359 .timer_set = common_timer_set, 1373 1360 .timer_get = common_timer_get,