Commit 1b6c8928 authored by Thomas Weißschuh's avatar Thomas Weißschuh Committed by Thomas Gleixner
Browse files

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: default avatarThomas Weißschuh <thomas.weissschuh@linutronix.de>
Signed-off-by: default avatarThomas Gleixner <tglx@kernel.org>
Link: https://patch.msgid.link/20260326-vdso-timens-decoupling-v2-2-c82693a7775f@linutronix.de
parent 5dc9cf83
Loading
Loading
Loading
Loading
+16 −12
Original line number Diff line number Diff line
@@ -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;
@@ -38,7 +40,6 @@ static inline struct time_namespace *to_time_ns(struct ns_common *ns)
	return container_of(ns, struct time_namespace, ns);
}
void __init time_ns_init(void);
extern void timens_commit(struct task_struct *tsk, struct time_namespace *ns);

static inline struct time_namespace *get_time_ns(struct time_namespace *ns)
{
@@ -51,7 +52,6 @@ struct time_namespace *copy_time_ns(u64 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)
{
@@ -115,11 +115,6 @@ static inline void __init time_ns_init(void)
{
}

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;
@@ -146,11 +141,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) { }

@@ -167,4 +157,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 */
+3 −1
Original line number Diff line number Diff line
@@ -1386,12 +1386,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)
+2 −1
Original line number Diff line number Diff line
@@ -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
+4 −4
Original line number Diff line number Diff line
@@ -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);
}
+15 −0
Original line number Diff line number Diff line
@@ -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 */
Loading