linux/include/linux/time_namespace.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2#ifndef _LINUX_TIMENS_H
   3#define _LINUX_TIMENS_H
   4
   5
   6#include <linux/sched.h>
   7#include <linux/nsproxy.h>
   8#include <linux/ns_common.h>
   9#include <linux/err.h>
  10
  11struct user_namespace;
  12extern struct user_namespace init_user_ns;
  13
  14struct timens_offsets {
  15        struct timespec64 monotonic;
  16        struct timespec64 boottime;
  17};
  18
  19struct time_namespace {
  20        struct user_namespace   *user_ns;
  21        struct ucounts          *ucounts;
  22        struct ns_common        ns;
  23        struct timens_offsets   offsets;
  24        struct page             *vvar_page;
  25        /* If set prevents changing offsets after any task joined namespace. */
  26        bool                    frozen_offsets;
  27} __randomize_layout;
  28
  29extern struct time_namespace init_time_ns;
  30
  31#ifdef CONFIG_TIME_NS
  32extern int vdso_join_timens(struct task_struct *task,
  33                            struct time_namespace *ns);
  34extern void timens_commit(struct task_struct *tsk, struct time_namespace *ns);
  35
  36static inline struct time_namespace *get_time_ns(struct time_namespace *ns)
  37{
  38        refcount_inc(&ns->ns.count);
  39        return ns;
  40}
  41
  42struct time_namespace *copy_time_ns(unsigned long flags,
  43                                    struct user_namespace *user_ns,
  44                                    struct time_namespace *old_ns);
  45void free_time_ns(struct time_namespace *ns);
  46void timens_on_fork(struct nsproxy *nsproxy, struct task_struct *tsk);
  47struct vdso_data *arch_get_vdso_data(void *vvar_page);
  48
  49static inline void put_time_ns(struct time_namespace *ns)
  50{
  51        if (refcount_dec_and_test(&ns->ns.count))
  52                free_time_ns(ns);
  53}
  54
  55void proc_timens_show_offsets(struct task_struct *p, struct seq_file *m);
  56
  57struct proc_timens_offset {
  58        int                     clockid;
  59        struct timespec64       val;
  60};
  61
  62int proc_timens_set_offset(struct file *file, struct task_struct *p,
  63                           struct proc_timens_offset *offsets, int n);
  64
  65static inline void timens_add_monotonic(struct timespec64 *ts)
  66{
  67        struct timens_offsets *ns_offsets = &current->nsproxy->time_ns->offsets;
  68
  69        *ts = timespec64_add(*ts, ns_offsets->monotonic);
  70}
  71
  72static inline void timens_add_boottime(struct timespec64 *ts)
  73{
  74        struct timens_offsets *ns_offsets = &current->nsproxy->time_ns->offsets;
  75
  76        *ts = timespec64_add(*ts, ns_offsets->boottime);
  77}
  78
  79static inline u64 timens_add_boottime_ns(u64 nsec)
  80{
  81        struct timens_offsets *ns_offsets = &current->nsproxy->time_ns->offsets;
  82
  83        return nsec + timespec64_to_ns(&ns_offsets->boottime);
  84}
  85
  86static inline void timens_sub_boottime(struct timespec64 *ts)
  87{
  88        struct timens_offsets *ns_offsets = &current->nsproxy->time_ns->offsets;
  89
  90        *ts = timespec64_sub(*ts, ns_offsets->boottime);
  91}
  92
  93ktime_t do_timens_ktime_to_host(clockid_t clockid, ktime_t tim,
  94                                struct timens_offsets *offsets);
  95
  96static inline ktime_t timens_ktime_to_host(clockid_t clockid, ktime_t tim)
  97{
  98        struct time_namespace *ns = current->nsproxy->time_ns;
  99
 100        if (likely(ns == &init_time_ns))
 101                return tim;
 102
 103        return do_timens_ktime_to_host(clockid, tim, &ns->offsets);
 104}
 105
 106#else
 107static inline int vdso_join_timens(struct task_struct *task,
 108                                   struct time_namespace *ns)
 109{
 110        return 0;
 111}
 112
 113static inline void timens_commit(struct task_struct *tsk,
 114                                 struct time_namespace *ns)
 115{
 116}
 117
 118static inline struct time_namespace *get_time_ns(struct time_namespace *ns)
 119{
 120        return NULL;
 121}
 122
 123static inline void put_time_ns(struct time_namespace *ns)
 124{
 125}
 126
 127static inline
 128struct time_namespace *copy_time_ns(unsigned long flags,
 129                                    struct user_namespace *user_ns,
 130                                    struct time_namespace *old_ns)
 131{
 132        if (flags & CLONE_NEWTIME)
 133                return ERR_PTR(-EINVAL);
 134
 135        return old_ns;
 136}
 137
 138static inline void timens_on_fork(struct nsproxy *nsproxy,
 139                                 struct task_struct *tsk)
 140{
 141        return;
 142}
 143
 144static inline void timens_add_monotonic(struct timespec64 *ts) { }
 145static inline void timens_add_boottime(struct timespec64 *ts) { }
 146
 147static inline u64 timens_add_boottime_ns(u64 nsec)
 148{
 149        return nsec;
 150}
 151
 152static inline void timens_sub_boottime(struct timespec64 *ts) { }
 153
 154static inline ktime_t timens_ktime_to_host(clockid_t clockid, ktime_t tim)
 155{
 156        return tim;
 157}
 158#endif
 159
 160#endif /* _LINUX_TIMENS_H */
 161