1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef _LINUX_TIMENS_H
3 #define _LINUX_TIMENS_H
6 #include <linux/sched.h>
7 #include <linux/nsproxy.h>
8 #include <linux/ns_common.h>
10 #include <linux/time64.h>
12 struct user_namespace
;
13 extern struct user_namespace init_user_ns
;
15 struct vm_area_struct
;
17 struct timens_offsets
{
18 struct timespec64 monotonic
;
19 struct timespec64 boottime
;
22 struct time_namespace
{
23 struct user_namespace
*user_ns
;
24 struct ucounts
*ucounts
;
26 struct timens_offsets offsets
;
27 struct page
*vvar_page
;
28 /* If set prevents changing offsets after any task joined namespace. */
32 extern struct time_namespace init_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
);
39 static inline struct time_namespace
*get_time_ns(struct time_namespace
*ns
)
41 refcount_inc(&ns
->ns
.count
);
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
);
52 static inline void put_time_ns(struct time_namespace
*ns
)
54 if (refcount_dec_and_test(&ns
->ns
.count
))
58 void proc_timens_show_offsets(struct task_struct
*p
, struct seq_file
*m
);
60 struct proc_timens_offset
{
62 struct timespec64 val
;
65 int proc_timens_set_offset(struct file
*file
, struct task_struct
*p
,
66 struct proc_timens_offset
*offsets
, int n
);
68 static inline void timens_add_monotonic(struct timespec64
*ts
)
70 struct timens_offsets
*ns_offsets
= ¤t
->nsproxy
->time_ns
->offsets
;
72 *ts
= timespec64_add(*ts
, ns_offsets
->monotonic
);
75 static inline void timens_add_boottime(struct timespec64
*ts
)
77 struct timens_offsets
*ns_offsets
= ¤t
->nsproxy
->time_ns
->offsets
;
79 *ts
= timespec64_add(*ts
, ns_offsets
->boottime
);
82 static inline u64
timens_add_boottime_ns(u64 nsec
)
84 struct timens_offsets
*ns_offsets
= ¤t
->nsproxy
->time_ns
->offsets
;
86 return nsec
+ timespec64_to_ns(&ns_offsets
->boottime
);
89 static inline void timens_sub_boottime(struct timespec64
*ts
)
91 struct timens_offsets
*ns_offsets
= ¤t
->nsproxy
->time_ns
->offsets
;
93 *ts
= timespec64_sub(*ts
, ns_offsets
->boottime
);
96 ktime_t
do_timens_ktime_to_host(clockid_t clockid
, ktime_t tim
,
97 struct timens_offsets
*offsets
);
99 static inline ktime_t
timens_ktime_to_host(clockid_t clockid
, ktime_t tim
)
101 struct time_namespace
*ns
= current
->nsproxy
->time_ns
;
103 if (likely(ns
== &init_time_ns
))
106 return do_timens_ktime_to_host(clockid
, tim
, &ns
->offsets
);
110 static inline int vdso_join_timens(struct task_struct
*task
,
111 struct time_namespace
*ns
)
116 static inline void timens_commit(struct task_struct
*tsk
,
117 struct time_namespace
*ns
)
121 static inline struct time_namespace
*get_time_ns(struct time_namespace
*ns
)
126 static inline void put_time_ns(struct time_namespace
*ns
)
131 struct time_namespace
*copy_time_ns(unsigned long flags
,
132 struct user_namespace
*user_ns
,
133 struct time_namespace
*old_ns
)
135 if (flags
& CLONE_NEWTIME
)
136 return ERR_PTR(-EINVAL
);
141 static inline void timens_on_fork(struct nsproxy
*nsproxy
,
142 struct task_struct
*tsk
)
147 static inline struct page
*find_timens_vvar_page(struct vm_area_struct
*vma
)
152 static inline void timens_add_monotonic(struct timespec64
*ts
) { }
153 static inline void timens_add_boottime(struct timespec64
*ts
) { }
155 static inline u64
timens_add_boottime_ns(u64 nsec
)
160 static inline void timens_sub_boottime(struct timespec64
*ts
) { }
162 static inline ktime_t
timens_ktime_to_host(clockid_t clockid
, ktime_t tim
)
168 struct vdso_data
*arch_get_vdso_data(void *vvar_page
);
170 #endif /* _LINUX_TIMENS_H */