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