Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 #ifndef _LINUX_TIMENS_H
0003 #define _LINUX_TIMENS_H
0004 
0005 
0006 #include <linux/sched.h>
0007 #include <linux/nsproxy.h>
0008 #include <linux/ns_common.h>
0009 #include <linux/err.h>
0010 
0011 struct user_namespace;
0012 extern struct user_namespace init_user_ns;
0013 
0014 struct timens_offsets {
0015     struct timespec64 monotonic;
0016     struct timespec64 boottime;
0017 };
0018 
0019 struct time_namespace {
0020     struct user_namespace   *user_ns;
0021     struct ucounts      *ucounts;
0022     struct ns_common    ns;
0023     struct timens_offsets   offsets;
0024     struct page     *vvar_page;
0025     /* If set prevents changing offsets after any task joined namespace. */
0026     bool            frozen_offsets;
0027 } __randomize_layout;
0028 
0029 extern struct time_namespace init_time_ns;
0030 
0031 #ifdef CONFIG_TIME_NS
0032 extern int vdso_join_timens(struct task_struct *task,
0033                 struct time_namespace *ns);
0034 extern void timens_commit(struct task_struct *tsk, struct time_namespace *ns);
0035 
0036 static inline struct time_namespace *get_time_ns(struct time_namespace *ns)
0037 {
0038     refcount_inc(&ns->ns.count);
0039     return ns;
0040 }
0041 
0042 struct time_namespace *copy_time_ns(unsigned long flags,
0043                     struct user_namespace *user_ns,
0044                     struct time_namespace *old_ns);
0045 void free_time_ns(struct time_namespace *ns);
0046 void timens_on_fork(struct nsproxy *nsproxy, struct task_struct *tsk);
0047 struct vdso_data *arch_get_vdso_data(void *vvar_page);
0048 
0049 static inline void put_time_ns(struct time_namespace *ns)
0050 {
0051     if (refcount_dec_and_test(&ns->ns.count))
0052         free_time_ns(ns);
0053 }
0054 
0055 void proc_timens_show_offsets(struct task_struct *p, struct seq_file *m);
0056 
0057 struct proc_timens_offset {
0058     int         clockid;
0059     struct timespec64   val;
0060 };
0061 
0062 int proc_timens_set_offset(struct file *file, struct task_struct *p,
0063                struct proc_timens_offset *offsets, int n);
0064 
0065 static inline void timens_add_monotonic(struct timespec64 *ts)
0066 {
0067     struct timens_offsets *ns_offsets = &current->nsproxy->time_ns->offsets;
0068 
0069     *ts = timespec64_add(*ts, ns_offsets->monotonic);
0070 }
0071 
0072 static inline void timens_add_boottime(struct timespec64 *ts)
0073 {
0074     struct timens_offsets *ns_offsets = &current->nsproxy->time_ns->offsets;
0075 
0076     *ts = timespec64_add(*ts, ns_offsets->boottime);
0077 }
0078 
0079 static inline u64 timens_add_boottime_ns(u64 nsec)
0080 {
0081     struct timens_offsets *ns_offsets = &current->nsproxy->time_ns->offsets;
0082 
0083     return nsec + timespec64_to_ns(&ns_offsets->boottime);
0084 }
0085 
0086 static inline void timens_sub_boottime(struct timespec64 *ts)
0087 {
0088     struct timens_offsets *ns_offsets = &current->nsproxy->time_ns->offsets;
0089 
0090     *ts = timespec64_sub(*ts, ns_offsets->boottime);
0091 }
0092 
0093 ktime_t do_timens_ktime_to_host(clockid_t clockid, ktime_t tim,
0094                 struct timens_offsets *offsets);
0095 
0096 static inline ktime_t timens_ktime_to_host(clockid_t clockid, ktime_t tim)
0097 {
0098     struct time_namespace *ns = current->nsproxy->time_ns;
0099 
0100     if (likely(ns == &init_time_ns))
0101         return tim;
0102 
0103     return do_timens_ktime_to_host(clockid, tim, &ns->offsets);
0104 }
0105 
0106 #else
0107 static inline int vdso_join_timens(struct task_struct *task,
0108                    struct time_namespace *ns)
0109 {
0110     return 0;
0111 }
0112 
0113 static inline void timens_commit(struct task_struct *tsk,
0114                  struct time_namespace *ns)
0115 {
0116 }
0117 
0118 static inline struct time_namespace *get_time_ns(struct time_namespace *ns)
0119 {
0120     return NULL;
0121 }
0122 
0123 static inline void put_time_ns(struct time_namespace *ns)
0124 {
0125 }
0126 
0127 static inline
0128 struct time_namespace *copy_time_ns(unsigned long flags,
0129                     struct user_namespace *user_ns,
0130                     struct time_namespace *old_ns)
0131 {
0132     if (flags & CLONE_NEWTIME)
0133         return ERR_PTR(-EINVAL);
0134 
0135     return old_ns;
0136 }
0137 
0138 static inline void timens_on_fork(struct nsproxy *nsproxy,
0139                  struct task_struct *tsk)
0140 {
0141     return;
0142 }
0143 
0144 static inline void timens_add_monotonic(struct timespec64 *ts) { }
0145 static inline void timens_add_boottime(struct timespec64 *ts) { }
0146 
0147 static inline u64 timens_add_boottime_ns(u64 nsec)
0148 {
0149     return nsec;
0150 }
0151 
0152 static inline void timens_sub_boottime(struct timespec64 *ts) { }
0153 
0154 static inline ktime_t timens_ktime_to_host(clockid_t clockid, ktime_t tim)
0155 {
0156     return tim;
0157 }
0158 #endif
0159 
0160 #endif /* _LINUX_TIMENS_H */