time_namespace.h 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. #ifndef _LINUX_TIMENS_H
  3. #define _LINUX_TIMENS_H
  4. #include <linux/sched.h>
  5. #include <linux/kref.h>
  6. #include <linux/nsproxy.h>
  7. #include <linux/ns_common.h>
  8. #include <linux/err.h>
  9. struct user_namespace;
  10. extern struct user_namespace init_user_ns;
  11. struct timens_offsets {
  12. struct timespec64 monotonic;
  13. struct timespec64 boottime;
  14. };
  15. struct time_namespace {
  16. struct kref kref;
  17. struct user_namespace *user_ns;
  18. struct ucounts *ucounts;
  19. struct ns_common ns;
  20. struct timens_offsets offsets;
  21. struct page *vvar_page;
  22. /* If set prevents changing offsets after any task joined namespace. */
  23. bool frozen_offsets;
  24. } __randomize_layout;
  25. extern struct time_namespace init_time_ns;
  26. #ifdef CONFIG_TIME_NS
  27. extern int vdso_join_timens(struct task_struct *task,
  28. struct time_namespace *ns);
  29. extern void timens_commit(struct task_struct *tsk, struct time_namespace *ns);
  30. static inline struct time_namespace *get_time_ns(struct time_namespace *ns)
  31. {
  32. kref_get(&ns->kref);
  33. return ns;
  34. }
  35. struct time_namespace *copy_time_ns(unsigned long flags,
  36. struct user_namespace *user_ns,
  37. struct time_namespace *old_ns);
  38. void free_time_ns(struct kref *kref);
  39. int timens_on_fork(struct nsproxy *nsproxy, struct task_struct *tsk);
  40. struct vdso_data *arch_get_vdso_data(void *vvar_page);
  41. static inline void put_time_ns(struct time_namespace *ns)
  42. {
  43. kref_put(&ns->kref, free_time_ns);
  44. }
  45. void proc_timens_show_offsets(struct task_struct *p, struct seq_file *m);
  46. struct proc_timens_offset {
  47. int clockid;
  48. struct timespec64 val;
  49. };
  50. int proc_timens_set_offset(struct file *file, struct task_struct *p,
  51. struct proc_timens_offset *offsets, int n);
  52. static inline void timens_add_monotonic(struct timespec64 *ts)
  53. {
  54. struct timens_offsets *ns_offsets = &current->nsproxy->time_ns->offsets;
  55. *ts = timespec64_add(*ts, ns_offsets->monotonic);
  56. }
  57. static inline void timens_add_boottime(struct timespec64 *ts)
  58. {
  59. struct timens_offsets *ns_offsets = &current->nsproxy->time_ns->offsets;
  60. *ts = timespec64_add(*ts, ns_offsets->boottime);
  61. }
  62. ktime_t do_timens_ktime_to_host(clockid_t clockid, ktime_t tim,
  63. struct timens_offsets *offsets);
  64. static inline ktime_t timens_ktime_to_host(clockid_t clockid, ktime_t tim)
  65. {
  66. struct time_namespace *ns = current->nsproxy->time_ns;
  67. if (likely(ns == &init_time_ns))
  68. return tim;
  69. return do_timens_ktime_to_host(clockid, tim, &ns->offsets);
  70. }
  71. #else
  72. static inline int vdso_join_timens(struct task_struct *task,
  73. struct time_namespace *ns)
  74. {
  75. return 0;
  76. }
  77. static inline void timens_commit(struct task_struct *tsk,
  78. struct time_namespace *ns)
  79. {
  80. }
  81. static inline struct time_namespace *get_time_ns(struct time_namespace *ns)
  82. {
  83. return NULL;
  84. }
  85. static inline void put_time_ns(struct time_namespace *ns)
  86. {
  87. }
  88. static inline
  89. struct time_namespace *copy_time_ns(unsigned long flags,
  90. struct user_namespace *user_ns,
  91. struct time_namespace *old_ns)
  92. {
  93. if (flags & CLONE_NEWTIME)
  94. return ERR_PTR(-EINVAL);
  95. return old_ns;
  96. }
  97. static inline int timens_on_fork(struct nsproxy *nsproxy,
  98. struct task_struct *tsk)
  99. {
  100. return 0;
  101. }
  102. static inline void timens_add_monotonic(struct timespec64 *ts) { }
  103. static inline void timens_add_boottime(struct timespec64 *ts) { }
  104. static inline ktime_t timens_ktime_to_host(clockid_t clockid, ktime_t tim)
  105. {
  106. return tim;
  107. }
  108. #endif
  109. #endif /* _LINUX_TIMENS_H */