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