[Devel] [PATCH hci-8.1 3/4] ms/timens: Remove dependency on the vDSO
Eva Kurchatova
eva.kurchatova at virtuozzo.com
Fri Oct 9 16:58:36 MSK 2026
Previously, missing time namespace support in the vDSO meant that time
namespaces needed to be disabled globally. This was expressed in a hard
dependency on the generic vDSO library. This also meant that architectures
without any vDSO or only a stub vDSO could not enable time namespaces.
Now that all architectures using a real vDSO are using the generic library,
that dependency is not necessary anymore.
Remove the dependency and let all architectures enable time namespaces.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh at linutronix.de>
Signed-off-by: Thomas Gleixner <tglx at kernel.org>
Link: https://patch.msgid.link/20260326-vdso-timens-decoupling-v2-2-c82693a7775f@linutronix.de
(cherry picked from commit 1b6c89285d37114d7efe8ab04102a542581cd7da)
The User Mode Linux KUnit kernel has no generic vDSO, so it could not
have CONFIG_TIME_NS, which every x86_64 configuration has; a change
under review for VSTOR-146839 named init_time_ns and failed to link
there. With the dependency gone the UML build keeps the option.
https://virtuozzo.atlassian.net/browse/VSTOR-148112
Feature: fix ms/timens
Signed-off-by: Eva Kurchatova <eva.kurchatova at virtuozzo.com>
---
include/linux/time_namespace.h | 29 ++++++++++++++++-------------
init/Kconfig | 4 +++-
kernel/time/Makefile | 3 ++-
kernel/time/namespace.c | 8 ++++----
kernel/time/namespace_internal.h | 15 +++++++++++++++
kernel/time/namespace_vdso.c | 14 ++++++++++++++
6 files changed, 54 insertions(+), 19 deletions(-)
diff --git a/include/linux/time_namespace.h b/include/linux/time_namespace.h
index 63d0051927f1..6c1872e7bb73 100644
--- a/include/linux/time_namespace.h
+++ b/include/linux/time_namespace.h
@@ -25,7 +25,9 @@ struct time_namespace {
struct ucounts *ucounts;
struct ns_common ns;
struct timens_offsets offsets;
+#ifdef CONFIG_TIME_NS_VDSO
struct page *vvar_page;
+#endif
/* If set prevents changing offsets after any task joined namespace. */
bool frozen_offsets;
} __randomize_layout;
@@ -33,8 +35,6 @@ struct time_namespace {
extern struct time_namespace init_time_ns;
#ifdef CONFIG_TIME_NS
-extern void timens_commit(struct task_struct *tsk, struct time_namespace *ns);
-
static inline struct time_namespace *get_time_ns(struct time_namespace *ns)
{
refcount_inc(&ns->ns.count);
@@ -46,7 +46,6 @@ struct time_namespace *copy_time_ns(unsigned long flags,
struct time_namespace *old_ns);
void free_time_ns(struct time_namespace *ns);
void timens_on_fork(struct nsproxy *nsproxy, struct task_struct *tsk);
-struct page *find_timens_vvar_page(struct vm_area_struct *vma);
static inline void put_time_ns(struct time_namespace *ns)
{
@@ -106,11 +105,6 @@ static inline ktime_t timens_ktime_to_host(clockid_t clockid, ktime_t tim)
}
#else
-static inline void timens_commit(struct task_struct *tsk,
- struct time_namespace *ns)
-{
-}
-
static inline struct time_namespace *get_time_ns(struct time_namespace *ns)
{
return NULL;
@@ -137,11 +131,6 @@ static inline void timens_on_fork(struct nsproxy *nsproxy,
return;
}
-static inline struct page *find_timens_vvar_page(struct vm_area_struct *vma)
-{
- return NULL;
-}
-
static inline void timens_add_monotonic(struct timespec64 *ts) { }
static inline void timens_add_boottime(struct timespec64 *ts) { }
@@ -158,4 +147,18 @@ static inline ktime_t timens_ktime_to_host(clockid_t clockid, ktime_t tim)
}
#endif
+#ifdef CONFIG_TIME_NS_VDSO
+extern void timens_commit(struct task_struct *tsk, struct time_namespace *ns);
+struct page *find_timens_vvar_page(struct vm_area_struct *vma);
+#else /* !CONFIG_TIME_NS_VDSO */
+static inline void timens_commit(struct task_struct *tsk, struct time_namespace *ns)
+{
+}
+
+static inline struct page *find_timens_vvar_page(struct vm_area_struct *vma)
+{
+ return NULL;
+}
+#endif /* CONFIG_TIME_NS_VDSO */
+
#endif /* _LINUX_TIMENS_H */
diff --git a/init/Kconfig b/init/Kconfig
index f0ad3790a93a..44b2d4426109 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1306,12 +1306,14 @@ config UTS_NS
config TIME_NS
bool "TIME namespace"
- depends on GENERIC_GETTIMEOFDAY
default y
help
In this namespace boottime and monotonic clocks can be set.
The time will keep going with the same pace.
+config TIME_NS_VDSO
+ def_bool TIME_NS && GENERIC_GETTIMEOFDAY
+
config IPC_NS
bool "IPC namespace"
depends on (SYSVIPC || POSIX_MQUEUE)
diff --git a/kernel/time/Makefile b/kernel/time/Makefile
index 494bd4e41781..dd3ea6997064 100644
--- a/kernel/time/Makefile
+++ b/kernel/time/Makefile
@@ -23,6 +23,7 @@ endif
obj-$(CONFIG_HAVE_GENERIC_VDSO) += vsyscall.o
obj-$(CONFIG_DEBUG_FS) += timekeeping_debug.o
obj-$(CONFIG_TEST_UDELAY) += test_udelay.o
-obj-$(CONFIG_TIME_NS) += namespace.o namespace_vdso.o
+obj-$(CONFIG_TIME_NS) += namespace.o
+obj-$(CONFIG_TIME_NS_VDSO) += namespace_vdso.o
obj-$(CONFIG_TEST_CLOCKSOURCE_WATCHDOG) += clocksource-wdtest.o
obj-$(CONFIG_TIME_KUNIT_TEST) += time_test.o
diff --git a/kernel/time/namespace.c b/kernel/time/namespace.c
index c82dc9a5d1de..cf95f9e0ad94 100644
--- a/kernel/time/namespace.c
+++ b/kernel/time/namespace.c
@@ -94,8 +94,8 @@ static struct time_namespace *clone_time_ns(struct user_namespace *user_ns,
refcount_set(&ns->ns.count, 1);
- ns->vvar_page = alloc_page(GFP_KERNEL_ACCOUNT | __GFP_ZERO);
- if (!ns->vvar_page)
+ err = timens_vdso_alloc_vvar_page(ns);
+ if (err)
goto fail_free;
err = ns_alloc_inum(&ns->ns);
@@ -110,7 +110,7 @@ static struct time_namespace *clone_time_ns(struct user_namespace *user_ns,
return ns;
fail_free_page:
- __free_page(ns->vvar_page);
+ timens_vdso_free_vvar_page(ns);
fail_free:
kfree(ns);
fail_dec:
@@ -146,7 +146,7 @@ void free_time_ns(struct time_namespace *ns)
dec_time_namespaces(ns->ucounts);
put_user_ns(ns->user_ns);
ns_free_inum(&ns->ns);
- __free_page(ns->vvar_page);
+ timens_vdso_free_vvar_page(ns);
kfree(ns);
}
diff --git a/kernel/time/namespace_internal.h b/kernel/time/namespace_internal.h
index e85da11abb4d..b37ba179f43b 100644
--- a/kernel/time/namespace_internal.h
+++ b/kernel/time/namespace_internal.h
@@ -4,10 +4,25 @@
#include <linux/mutex.h>
+struct time_namespace;
+
/*
* Protects possibly multiple offsets writers racing each other
* and tasks entering the namespace.
*/
extern struct mutex timens_offset_lock;
+#ifdef CONFIG_TIME_NS_VDSO
+int timens_vdso_alloc_vvar_page(struct time_namespace *ns);
+void timens_vdso_free_vvar_page(struct time_namespace *ns);
+#else /* !CONFIG_TIME_NS_VDSO */
+static inline int timens_vdso_alloc_vvar_page(struct time_namespace *ns)
+{
+ return 0;
+}
+static inline void timens_vdso_free_vvar_page(struct time_namespace *ns)
+{
+}
+#endif /* CONFIG_TIME_NS_VDSO */
+
#endif /* _TIME_NAMESPACE_INTERNAL_H */
diff --git a/kernel/time/namespace_vdso.c b/kernel/time/namespace_vdso.c
index 558bf5208588..08d69270eb2c 100644
--- a/kernel/time/namespace_vdso.c
+++ b/kernel/time/namespace_vdso.c
@@ -139,3 +139,17 @@ void timens_commit(struct task_struct *tsk, struct time_namespace *ns)
timens_set_vvar_page(tsk, ns);
vdso_join_timens(tsk, ns);
}
+
+int timens_vdso_alloc_vvar_page(struct time_namespace *ns)
+{
+ ns->vvar_page = alloc_page(GFP_KERNEL_ACCOUNT | __GFP_ZERO);
+ if (!ns->vvar_page)
+ return -ENOMEM;
+
+ return 0;
+}
+
+void timens_vdso_free_vvar_page(struct time_namespace *ns)
+{
+ __free_page(ns->vvar_page);
+}
--
2.56.0
More information about the Devel
mailing list