Branch data Line data Source code
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 : : struct page *vvar_page; 27 : : /* If set prevents changing offsets after any task joined namespace. */ 28 : : bool frozen_offsets; 29 : : } __randomize_layout; 30 : : 31 : : extern struct time_namespace init_time_ns; 32 : : 33 : : #ifdef CONFIG_TIME_NS 34 : : extern int vdso_join_timens(struct task_struct *task, 35 : : struct time_namespace *ns); 36 : : 37 : 78 : static inline struct time_namespace *get_time_ns(struct time_namespace *ns) 38 : : { 39 : 78 : kref_get(&ns->kref); 40 : 78 : return ns; 41 : : } 42 : : 43 : : struct time_namespace *copy_time_ns(unsigned long flags, 44 : : struct user_namespace *user_ns, 45 : : struct time_namespace *old_ns); 46 : : void free_time_ns(struct kref *kref); 47 : : int timens_on_fork(struct nsproxy *nsproxy, struct task_struct *tsk); 48 : : struct vdso_data *arch_get_vdso_data(void *vvar_page); 49 : : 50 : 0 : static inline void put_time_ns(struct time_namespace *ns) 51 : : { 52 : 0 : kref_put(&ns->kref, free_time_ns); 53 : 0 : } 54 : : 55 : : void proc_timens_show_offsets(struct task_struct *p, struct seq_file *m); 56 : : 57 : : struct proc_timens_offset { 58 : : int clockid; 59 : : struct timespec64 val; 60 : : }; 61 : : 62 : : int proc_timens_set_offset(struct file *file, struct task_struct *p, 63 : : struct proc_timens_offset *offsets, int n); 64 : : 65 : 0 : static inline void timens_add_monotonic(struct timespec64 *ts) 66 : : { 67 : 0 : struct timens_offsets *ns_offsets = ¤t->nsproxy->time_ns->offsets; 68 : : 69 : 0 : *ts = timespec64_add(*ts, ns_offsets->monotonic); 70 : 0 : } 71 : : 72 : 104 : static inline void timens_add_boottime(struct timespec64 *ts) 73 : : { 74 : 104 : struct timens_offsets *ns_offsets = ¤t->nsproxy->time_ns->offsets; 75 : : 76 : 104 : *ts = timespec64_add(*ts, ns_offsets->boottime); 77 : 104 : } 78 : : 79 : : ktime_t do_timens_ktime_to_host(clockid_t clockid, ktime_t tim, 80 : : struct timens_offsets *offsets); 81 : : 82 : 1659 : static inline ktime_t timens_ktime_to_host(clockid_t clockid, ktime_t tim) 83 : : { 84 [ - + # # ]: 1659 : struct time_namespace *ns = current->nsproxy->time_ns; 85 : : 86 [ - + # # ]: 1659 : if (likely(ns == &init_time_ns)) 87 : : return tim; 88 : : 89 : 0 : return do_timens_ktime_to_host(clockid, tim, &ns->offsets); 90 : : } 91 : : 92 : : #else 93 : : static inline int vdso_join_timens(struct task_struct *task, 94 : : struct time_namespace *ns) 95 : : { 96 : : return 0; 97 : : } 98 : : 99 : : static inline struct time_namespace *get_time_ns(struct time_namespace *ns) 100 : : { 101 : : return NULL; 102 : : } 103 : : 104 : : static inline void put_time_ns(struct time_namespace *ns) 105 : : { 106 : : } 107 : : 108 : : static inline 109 : : struct time_namespace *copy_time_ns(unsigned long flags, 110 : : struct user_namespace *user_ns, 111 : : struct time_namespace *old_ns) 112 : : { 113 : : if (flags & CLONE_NEWTIME) 114 : : return ERR_PTR(-EINVAL); 115 : : 116 : : return old_ns; 117 : : } 118 : : 119 : : static inline int timens_on_fork(struct nsproxy *nsproxy, 120 : : struct task_struct *tsk) 121 : : { 122 : : return 0; 123 : : } 124 : : 125 : : static inline void timens_add_monotonic(struct timespec64 *ts) { } 126 : : static inline void timens_add_boottime(struct timespec64 *ts) { } 127 : : static inline ktime_t timens_ktime_to_host(clockid_t clockid, ktime_t tim) 128 : : { 129 : : return tim; 130 : : } 131 : : #endif 132 : : 133 : : #endif /* _LINUX_TIMENS_H */