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/kref.h> 8 #include <linux/nsproxy.h> 9 #include <linux/ns_common.h> 10 #include <linux/err.h> 11 12 struct user_namespace; 13 extern struct user_namespace init_user_ns; 14 15 struct timens_offsets { 16 struct timespec64 monotonic; 17 struct timespec64 boottime; 18 }; 19 20 struct time_namespace { 21 struct kref kref; 22 struct user_namespace *user_ns; 23 struct ucounts *ucounts; 24 struct ns_common ns; 25 struct timens_offsets offsets; 26 } __randomize_layout; 27 28 extern struct time_namespace init_time_ns; 29 30 #ifdef CONFIG_TIME_NS 31 static inline struct time_namespace *get_time_ns(struct time_namespace *ns) 32 { 33 kref_get(&ns->kref); 34 return ns; 35 } 36 37 struct time_namespace *copy_time_ns(unsigned long flags, 38 struct user_namespace *user_ns, 39 struct time_namespace *old_ns); 40 void free_time_ns(struct kref *kref); 41 int timens_on_fork(struct nsproxy *nsproxy, struct task_struct *tsk); 42 43 static inline void put_time_ns(struct time_namespace *ns) 44 { 45 kref_put(&ns->kref, free_time_ns); 46 } 47 48 static inline void timens_add_monotonic(struct timespec64 *ts) 49 { 50 struct timens_offsets *ns_offsets = ¤t->nsproxy->time_ns->offsets; 51 52 *ts = timespec64_add(*ts, ns_offsets->monotonic); 53 } 54 55 static inline void timens_add_boottime(struct timespec64 *ts) 56 { 57 struct timens_offsets *ns_offsets = ¤t->nsproxy->time_ns->offsets; 58 59 *ts = timespec64_add(*ts, ns_offsets->boottime); 60 } 61 62 ktime_t do_timens_ktime_to_host(clockid_t clockid, ktime_t tim, 63 struct timens_offsets *offsets); 64 65 static inline ktime_t timens_ktime_to_host(clockid_t clockid, ktime_t tim) 66 { 67 struct time_namespace *ns = current->nsproxy->time_ns; 68 69 if (likely(ns == &init_time_ns)) 70 return tim; 71 72 return do_timens_ktime_to_host(clockid, tim, &ns->offsets); 73 } 74 75 #else 76 static inline struct time_namespace *get_time_ns(struct time_namespace *ns) 77 { 78 return NULL; 79 } 80 81 static inline void put_time_ns(struct time_namespace *ns) 82 { 83 } 84 85 static inline 86 struct time_namespace *copy_time_ns(unsigned long flags, 87 struct user_namespace *user_ns, 88 struct time_namespace *old_ns) 89 { 90 if (flags & CLONE_NEWTIME) 91 return ERR_PTR(-EINVAL); 92 93 return old_ns; 94 } 95 96 static inline int timens_on_fork(struct nsproxy *nsproxy, 97 struct task_struct *tsk) 98 { 99 return 0; 100 } 101 102 static inline void timens_add_monotonic(struct timespec64 *ts) { } 103 static inline void timens_add_boottime(struct timespec64 *ts) { } 104 static inline ktime_t timens_ktime_to_host(clockid_t clockid, ktime_t tim) 105 { 106 return tim; 107 } 108 #endif 109 110 #endif /* _LINUX_TIMENS_H */ 111