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>
11 struct user_namespace
;
12 extern struct user_namespace init_user_ns
;
14 struct timens_offsets
{
15 struct timespec64 monotonic
;
16 struct timespec64 boottime
;
19 struct time_namespace
{
20 struct user_namespace
*user_ns
;
21 struct ucounts
*ucounts
;
23 struct timens_offsets offsets
;
24 struct page
*vvar_page
;
25 /* If set prevents changing offsets after any task joined namespace. */
29 extern struct time_namespace init_time_ns
;
32 extern int vdso_join_timens(struct task_struct
*task
,
33 struct time_namespace
*ns
);
34 extern void timens_commit(struct task_struct
*tsk
, struct time_namespace
*ns
);
36 static inline struct time_namespace
*get_time_ns(struct time_namespace
*ns
)
38 refcount_inc(&ns
->ns
.count
);
42 struct time_namespace
*copy_time_ns(unsigned long flags
,
43 struct user_namespace
*user_ns
,
44 struct time_namespace
*old_ns
);
45 void free_time_ns(struct time_namespace
*ns
);
46 void timens_on_fork(struct nsproxy
*nsproxy
, struct task_struct
*tsk
);
47 struct vdso_data
*arch_get_vdso_data(void *vvar_page
);
49 static inline void put_time_ns(struct time_namespace
*ns
)
51 if (refcount_dec_and_test(&ns
->ns
.count
))
55 void proc_timens_show_offsets(struct task_struct
*p
, struct seq_file
*m
);
57 struct proc_timens_offset
{
59 struct timespec64 val
;
62 int proc_timens_set_offset(struct file
*file
, struct task_struct
*p
,
63 struct proc_timens_offset
*offsets
, int n
);
65 static inline void timens_add_monotonic(struct timespec64
*ts
)
67 struct timens_offsets
*ns_offsets
= ¤t
->nsproxy
->time_ns
->offsets
;
69 *ts
= timespec64_add(*ts
, ns_offsets
->monotonic
);
72 static inline void timens_add_boottime(struct timespec64
*ts
)
74 struct timens_offsets
*ns_offsets
= ¤t
->nsproxy
->time_ns
->offsets
;
76 *ts
= timespec64_add(*ts
, ns_offsets
->boottime
);
79 static inline u64
timens_add_boottime_ns(u64 nsec
)
81 struct timens_offsets
*ns_offsets
= ¤t
->nsproxy
->time_ns
->offsets
;
83 return nsec
+ timespec64_to_ns(&ns_offsets
->boottime
);
86 static inline void timens_sub_boottime(struct timespec64
*ts
)
88 struct timens_offsets
*ns_offsets
= ¤t
->nsproxy
->time_ns
->offsets
;
90 *ts
= timespec64_sub(*ts
, ns_offsets
->boottime
);
93 ktime_t
do_timens_ktime_to_host(clockid_t clockid
, ktime_t tim
,
94 struct timens_offsets
*offsets
);
96 static inline ktime_t
timens_ktime_to_host(clockid_t clockid
, ktime_t tim
)
98 struct time_namespace
*ns
= current
->nsproxy
->time_ns
;
100 if (likely(ns
== &init_time_ns
))
103 return do_timens_ktime_to_host(clockid
, tim
, &ns
->offsets
);
107 static inline int vdso_join_timens(struct task_struct
*task
,
108 struct time_namespace
*ns
)
113 static inline void timens_commit(struct task_struct
*tsk
,
114 struct time_namespace
*ns
)
118 static inline struct time_namespace
*get_time_ns(struct time_namespace
*ns
)
123 static inline void put_time_ns(struct time_namespace
*ns
)
128 struct time_namespace
*copy_time_ns(unsigned long flags
,
129 struct user_namespace
*user_ns
,
130 struct time_namespace
*old_ns
)
132 if (flags
& CLONE_NEWTIME
)
133 return ERR_PTR(-EINVAL
);
138 static inline void timens_on_fork(struct nsproxy
*nsproxy
,
139 struct task_struct
*tsk
)
144 static inline void timens_add_monotonic(struct timespec64
*ts
) { }
145 static inline void timens_add_boottime(struct timespec64
*ts
) { }
147 static inline u64
timens_add_boottime_ns(u64 nsec
)
152 static inline void timens_sub_boottime(struct timespec64
*ts
) { }
154 static inline ktime_t
timens_ktime_to_host(clockid_t clockid
, ktime_t tim
)
160 #endif /* _LINUX_TIMENS_H */