summaryrefslogtreecommitdiff
path: root/kernel/time
diff options
context:
space:
mode:
authorThomas Weißschuh <thomas.weissschuh@linutronix.de>2026-03-26 12:42:31 +0100
committerThomas Gleixner <tglx@kernel.org>2026-03-26 15:44:23 +0100
commit1b6c89285d37114d7efe8ab04102a542581cd7da (patch)
tree1254dd6d69b79fe060c6d0369b46967a32d86851 /kernel/time
parent5dc9cf835aba73c882348aa4f99be83b6e45ad9b (diff)
downloadlinux-next-1b6c89285d37114d7efe8ab04102a542581cd7da.tar.gz
linux-next-1b6c89285d37114d7efe8ab04102a542581cd7da.zip
timens: Remove dependency on the vDSO
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@linutronix.de> Signed-off-by: Thomas Gleixner <tglx@kernel.org> Link: https://patch.msgid.link/20260326-vdso-timens-decoupling-v2-2-c82693a7775f@linutronix.de
Diffstat (limited to 'kernel/time')
-rw-r--r--kernel/time/Makefile3
-rw-r--r--kernel/time/namespace.c8
-rw-r--r--kernel/time/namespace_internal.h15
-rw-r--r--kernel/time/namespace_vdso.c14
4 files changed, 35 insertions, 5 deletions
diff --git a/kernel/time/Makefile b/kernel/time/Makefile
index 662bccb3b7f9..eaf290c972f9 100644
--- a/kernel/time/Makefile
+++ b/kernel/time/Makefile
@@ -29,6 +29,7 @@ endif
obj-$(CONFIG_GENERIC_GETTIMEOFDAY) += 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 903f55a2dfb2..42302cc3f3fb 100644
--- a/kernel/time/namespace.c
+++ b/kernel/time/namespace.c
@@ -93,8 +93,8 @@ static struct time_namespace *clone_time_ns(struct user_namespace *user_ns,
if (!ns)
goto fail_dec;
- 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_common_init(ns);
@@ -109,7 +109,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_common_free(ns);
- __free_page(ns->vvar_page);
+ timens_vdso_free_vvar_page(ns);
/* Concurrent nstree traversal depends on a grace period. */
kfree_rcu(ns, ns.ns_rcu);
}
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 0e154f901501..88c075cd16a3 100644
--- a/kernel/time/namespace_vdso.c
+++ b/kernel/time/namespace_vdso.c
@@ -144,3 +144,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);
+}