0001
0002 #ifndef _LINUX_TIMENS_H
0003 #define _LINUX_TIMENS_H
0004
0005
0006 #include <linux/sched.h>
0007 #include <linux/nsproxy.h>
0008 #include <linux/ns_common.h>
0009 #include <linux/err.h>
0010
0011 struct user_namespace;
0012 extern struct user_namespace init_user_ns;
0013
0014 struct timens_offsets {
0015 struct timespec64 monotonic;
0016 struct timespec64 boottime;
0017 };
0018
0019 struct time_namespace {
0020 struct user_namespace *user_ns;
0021 struct ucounts *ucounts;
0022 struct ns_common ns;
0023 struct timens_offsets offsets;
0024 struct page *vvar_page;
0025
0026 bool frozen_offsets;
0027 } __randomize_layout;
0028
0029 extern struct time_namespace init_time_ns;
0030
0031 #ifdef CONFIG_TIME_NS
0032 extern int vdso_join_timens(struct task_struct *task,
0033 struct time_namespace *ns);
0034 extern void timens_commit(struct task_struct *tsk, struct time_namespace *ns);
0035
0036 static inline struct time_namespace *get_time_ns(struct time_namespace *ns)
0037 {
0038 refcount_inc(&ns->ns.count);
0039 return ns;
0040 }
0041
0042 struct time_namespace *copy_time_ns(unsigned long flags,
0043 struct user_namespace *user_ns,
0044 struct time_namespace *old_ns);
0045 void free_time_ns(struct time_namespace *ns);
0046 void timens_on_fork(struct nsproxy *nsproxy, struct task_struct *tsk);
0047 struct vdso_data *arch_get_vdso_data(void *vvar_page);
0048
0049 static inline void put_time_ns(struct time_namespace *ns)
0050 {
0051 if (refcount_dec_and_test(&ns->ns.count))
0052 free_time_ns(ns);
0053 }
0054
0055 void proc_timens_show_offsets(struct task_struct *p, struct seq_file *m);
0056
0057 struct proc_timens_offset {
0058 int clockid;
0059 struct timespec64 val;
0060 };
0061
0062 int proc_timens_set_offset(struct file *file, struct task_struct *p,
0063 struct proc_timens_offset *offsets, int n);
0064
0065 static inline void timens_add_monotonic(struct timespec64 *ts)
0066 {
0067 struct timens_offsets *ns_offsets = ¤t->nsproxy->time_ns->offsets;
0068
0069 *ts = timespec64_add(*ts, ns_offsets->monotonic);
0070 }
0071
0072 static inline void timens_add_boottime(struct timespec64 *ts)
0073 {
0074 struct timens_offsets *ns_offsets = ¤t->nsproxy->time_ns->offsets;
0075
0076 *ts = timespec64_add(*ts, ns_offsets->boottime);
0077 }
0078
0079 static inline u64 timens_add_boottime_ns(u64 nsec)
0080 {
0081 struct timens_offsets *ns_offsets = ¤t->nsproxy->time_ns->offsets;
0082
0083 return nsec + timespec64_to_ns(&ns_offsets->boottime);
0084 }
0085
0086 static inline void timens_sub_boottime(struct timespec64 *ts)
0087 {
0088 struct timens_offsets *ns_offsets = ¤t->nsproxy->time_ns->offsets;
0089
0090 *ts = timespec64_sub(*ts, ns_offsets->boottime);
0091 }
0092
0093 ktime_t do_timens_ktime_to_host(clockid_t clockid, ktime_t tim,
0094 struct timens_offsets *offsets);
0095
0096 static inline ktime_t timens_ktime_to_host(clockid_t clockid, ktime_t tim)
0097 {
0098 struct time_namespace *ns = current->nsproxy->time_ns;
0099
0100 if (likely(ns == &init_time_ns))
0101 return tim;
0102
0103 return do_timens_ktime_to_host(clockid, tim, &ns->offsets);
0104 }
0105
0106 #else
0107 static inline int vdso_join_timens(struct task_struct *task,
0108 struct time_namespace *ns)
0109 {
0110 return 0;
0111 }
0112
0113 static inline void timens_commit(struct task_struct *tsk,
0114 struct time_namespace *ns)
0115 {
0116 }
0117
0118 static inline struct time_namespace *get_time_ns(struct time_namespace *ns)
0119 {
0120 return NULL;
0121 }
0122
0123 static inline void put_time_ns(struct time_namespace *ns)
0124 {
0125 }
0126
0127 static inline
0128 struct time_namespace *copy_time_ns(unsigned long flags,
0129 struct user_namespace *user_ns,
0130 struct time_namespace *old_ns)
0131 {
0132 if (flags & CLONE_NEWTIME)
0133 return ERR_PTR(-EINVAL);
0134
0135 return old_ns;
0136 }
0137
0138 static inline void timens_on_fork(struct nsproxy *nsproxy,
0139 struct task_struct *tsk)
0140 {
0141 return;
0142 }
0143
0144 static inline void timens_add_monotonic(struct timespec64 *ts) { }
0145 static inline void timens_add_boottime(struct timespec64 *ts) { }
0146
0147 static inline u64 timens_add_boottime_ns(u64 nsec)
0148 {
0149 return nsec;
0150 }
0151
0152 static inline void timens_sub_boottime(struct timespec64 *ts) { }
0153
0154 static inline ktime_t timens_ktime_to_host(clockid_t clockid, ktime_t tim)
0155 {
0156 return tim;
0157 }
0158 #endif
0159
0160 #endif