Commit 89dd8eec authored by Andrei Vagin's avatar Andrei Vagin Committed by Thomas Gleixner

time: Add do_timens_ktime_to_host() helper

The helper subtracts namespace's clock offset from the given time
and ensures that the result is within [0, KTIME_MAX].
Co-developed-by: default avatarDmitry Safonov <dima@arista.com>
Signed-off-by: default avatarAndrei Vagin <avagin@gmail.com>
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-13-dima@arista.com
parent 5a590f35
...@@ -59,6 +59,19 @@ static inline void timens_add_boottime(struct timespec64 *ts) ...@@ -59,6 +59,19 @@ static inline void timens_add_boottime(struct timespec64 *ts)
*ts = timespec64_add(*ts, ns_offsets->boottime); *ts = timespec64_add(*ts, ns_offsets->boottime);
} }
ktime_t do_timens_ktime_to_host(clockid_t clockid, ktime_t tim,
struct timens_offsets *offsets);
static inline ktime_t timens_ktime_to_host(clockid_t clockid, ktime_t tim)
{
struct time_namespace *ns = current->nsproxy->time_ns;
if (likely(ns == &init_time_ns))
return tim;
return do_timens_ktime_to_host(clockid, tim, &ns->offsets);
}
#else #else
static inline struct time_namespace *get_time_ns(struct time_namespace *ns) static inline struct time_namespace *get_time_ns(struct time_namespace *ns)
{ {
...@@ -88,6 +101,10 @@ static inline int timens_on_fork(struct nsproxy *nsproxy, ...@@ -88,6 +101,10 @@ static inline int timens_on_fork(struct nsproxy *nsproxy,
static inline void timens_add_monotonic(struct timespec64 *ts) { } static inline void timens_add_monotonic(struct timespec64 *ts) { }
static inline void timens_add_boottime(struct timespec64 *ts) { } static inline void timens_add_boottime(struct timespec64 *ts) { }
static inline ktime_t timens_ktime_to_host(clockid_t clockid, ktime_t tim)
{
return tim;
}
#endif #endif
#endif /* _LINUX_TIMENS_H */ #endif /* _LINUX_TIMENS_H */
...@@ -16,6 +16,42 @@ ...@@ -16,6 +16,42 @@
#include <linux/err.h> #include <linux/err.h>
#include <linux/mm.h> #include <linux/mm.h>
ktime_t do_timens_ktime_to_host(clockid_t clockid, ktime_t tim,
struct timens_offsets *ns_offsets)
{
ktime_t offset;
switch (clockid) {
case CLOCK_MONOTONIC:
offset = timespec64_to_ktime(ns_offsets->monotonic);
break;
case CLOCK_BOOTTIME:
case CLOCK_BOOTTIME_ALARM:
offset = timespec64_to_ktime(ns_offsets->boottime);
break;
default:
return tim;
}
/*
* Check that @tim value is in [offset, KTIME_MAX + offset]
* and subtract offset.
*/
if (tim < offset) {
/*
* User can specify @tim *absolute* value - if it's lesser than
* the time namespace's offset - it's already expired.
*/
tim = 0;
} else {
tim = ktime_sub(tim, offset);
if (unlikely(tim > KTIME_MAX))
tim = KTIME_MAX;
}
return tim;
}
static struct ucounts *inc_time_namespaces(struct user_namespace *ns) static struct ucounts *inc_time_namespaces(struct user_namespace *ns)
{ {
return inc_ucount(ns, current_euid(), UCOUNT_TIME_NAMESPACES); return inc_ucount(ns, current_euid(), UCOUNT_TIME_NAMESPACES);
......
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