summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorDmitry Safonov <dima@arista.com>2019-11-12 01:27:15 +0000
committerThomas Gleixner <tglx@linutronix.de>2020-01-14 12:20:59 +0100
commit70ddf65184ec1e8989322f35193e4fde7377f0cc (patch)
tree57c0c780122cece61b02950fe7c2ee6abd5457f1 /kernel
parente6b28ec65b6d433624a2c290073bc356c4fce914 (diff)
downloadlinux-70ddf65184ec1e8989322f35193e4fde7377f0cc.tar.bz2
x86/vdso: Zap vvar pages when switching to a time namespace
The VVAR page layout depends on whether a task belongs to the root or non-root time namespace. Whenever a task changes its namespace, the VVAR page tables are cleared and then they will be re-faulted with a corresponding layout. Co-developed-by: Andrei Vagin <avagin@gmail.com> Signed-off-by: Andrei Vagin <avagin@gmail.com> Signed-off-by: Dmitry Safonov <dima@arista.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Link: https://lore.kernel.org/r/20191112012724.250792-27-dima@arista.com
Diffstat (limited to 'kernel')
-rw-r--r--kernel/time/namespace.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/kernel/time/namespace.c b/kernel/time/namespace.c
index d705c15d0273..0732964803b9 100644
--- a/kernel/time/namespace.c
+++ b/kernel/time/namespace.c
@@ -281,6 +281,7 @@ static void timens_put(struct ns_common *ns)
static int timens_install(struct nsproxy *nsproxy, struct ns_common *new)
{
struct time_namespace *ns = to_time_ns(new);
+ int err;
if (!current_is_single_threaded())
return -EUSERS;
@@ -291,6 +292,10 @@ static int timens_install(struct nsproxy *nsproxy, struct ns_common *new)
timens_set_vvar_page(current, ns);
+ err = vdso_join_timens(current, ns);
+ if (err)
+ return err;
+
get_time_ns(ns);
put_time_ns(nsproxy->time_ns);
nsproxy->time_ns = ns;
@@ -305,6 +310,7 @@ int timens_on_fork(struct nsproxy *nsproxy, struct task_struct *tsk)
{
struct ns_common *nsc = &nsproxy->time_ns_for_children->ns;
struct time_namespace *ns = to_time_ns(nsc);
+ int err;
/* create_new_namespaces() already incremented the ref counter */
if (nsproxy->time_ns == nsproxy->time_ns_for_children)
@@ -312,6 +318,10 @@ int timens_on_fork(struct nsproxy *nsproxy, struct task_struct *tsk)
timens_set_vvar_page(tsk, ns);
+ err = vdso_join_timens(tsk, ns);
+ if (err)
+ return err;
+
get_time_ns(ns);
put_time_ns(nsproxy->time_ns);
nsproxy->time_ns = ns;