[CRIU] [PATCHv1 19/26] restore: add arch_prctl mapping compatible vDSO
Dmitry Safonov
dsafonov at virtuozzo.com
Thu Jun 16 03:53:36 PDT 2016
Map here instead of park before unmap.
TODO: need to check that mapped size is smaller than x86_64 vDSO.
Cc: Cyrill Gorcunov <gorcunov at openvz.org>
Signed-off-by: Dmitry Safonov <dsafonov at virtuozzo.com>
---
criu/cr-restore.c | 1 +
criu/include/parasite-vdso.h | 2 ++
criu/include/restorer.h | 2 ++
criu/pie/parasite-vdso.c | 20 ++++++++++++++++++++
criu/pie/restorer.c | 14 ++++++++++++--
5 files changed, 37 insertions(+), 2 deletions(-)
diff --git a/criu/cr-restore.c b/criu/cr-restore.c
index 315f51614b8c..d630b97a8cb5 100644
--- a/criu/cr-restore.c
+++ b/criu/cr-restore.c
@@ -2885,6 +2885,7 @@ static int sigreturn_restore(pid_t pid, struct task_restore_args *task_args, uns
if (core->tc->has_seccomp_mode)
task_args->seccomp_mode = core->tc->seccomp_mode;
+ task_args->compatible_mode = core_is_compat(core);
/*
* Arguments for task restoration.
*/
diff --git a/criu/include/parasite-vdso.h b/criu/include/parasite-vdso.h
index 530cc01cb5e4..d50319048264 100644
--- a/criu/include/parasite-vdso.h
+++ b/criu/include/parasite-vdso.h
@@ -80,12 +80,14 @@ static inline bool is_vdso_mark(void *addr)
}
extern int vdso_do_park(struct vdso_symtable *sym_rt, unsigned long park_at, unsigned long park_size);
+int vdso_map_compat(unsigned long map_at);
extern int vdso_proxify(char *who, struct vdso_symtable *sym_rt,
unsigned long vdso_rt_parked_at, size_t index,
VmaEntry *vmas, size_t nr_vmas);
#else /* CONFIG_VDSO */
#define vdso_do_park(sym_rt, park_at, park_size) (0)
+#define vdso_map_compat(map_at) (0)
#endif /* CONFIG_VDSO */
diff --git a/criu/include/restorer.h b/criu/include/restorer.h
index fad9e09b82ad..7c0336e7bf74 100644
--- a/criu/include/restorer.h
+++ b/criu/include/restorer.h
@@ -175,6 +175,8 @@ struct task_restore_args {
int seccomp_mode;
+ bool compatible_mode;
+
#ifdef CONFIG_VDSO
unsigned long vdso_rt_size;
struct vdso_symtable vdso_sym_rt; /* runtime vdso symbols */
diff --git a/criu/pie/parasite-vdso.c b/criu/pie/parasite-vdso.c
index 7f4e6a022594..b5d12f1e1ca7 100644
--- a/criu/pie/parasite-vdso.c
+++ b/criu/pie/parasite-vdso.c
@@ -68,6 +68,26 @@ int vdso_do_park(struct vdso_symtable *sym_rt, unsigned long park_at, unsigned l
return ret;
}
+#ifdef CONFIG_X86_64
+#ifndef ARCH_MAP_VDSO_32
+# define ARCH_MAP_VDSO_32 0x2002
+#endif
+int vdso_map_compat(unsigned long map_at)
+{
+ int ret;
+
+ pr_debug("Mapping compatible vDSO at %lx\n", map_at);
+
+ ret = sys_arch_prctl(ARCH_MAP_VDSO_32, map_at);
+ return ret;
+}
+#else
+int vdso_map_compat(unsigned long map_at)
+{
+ return 0;
+}
+#endif
+
int vdso_proxify(char *who, struct vdso_symtable *sym_rt,
unsigned long vdso_rt_parked_at, size_t index,
VmaEntry *vmas, size_t nr_vmas)
diff --git a/criu/pie/restorer.c b/criu/pie/restorer.c
index 7b7299fd967b..8fbe8f8138a6 100644
--- a/criu/pie/restorer.c
+++ b/criu/pie/restorer.c
@@ -1129,13 +1129,23 @@ long __export_restore_task(struct task_restore_args *args)
pr_debug("lazy-pages: uffd %d\n", args->uffd);
}
- if (vdso_do_park(&args->vdso_sym_rt, args->vdso_rt_parked_at, vdso_rt_size))
- goto core_restore_end;
+ if (!args->compatible_mode) {
+ /* Compatible vDSO will be mapped, not moved */
+ if (vdso_do_park(&args->vdso_sym_rt,
+ args->vdso_rt_parked_at, vdso_rt_size))
+ goto core_restore_end;
+ }
if (unmap_old_vmas((void *)args->premmapped_addr, args->premmapped_len,
bootstrap_start, bootstrap_len, args->task_size))
goto core_restore_end;
+ if (args->compatible_mode) {
+ /* Map compatible vdso */
+ if (vdso_map_compat(args->vdso_rt_parked_at))
+ goto core_restore_end;
+ }
+
/* Shift private vma-s to the left */
for (i = 0; i < args->vmas_n; i++) {
vma_entry = args->vmas + i;
--
2.8.3
More information about the CRIU
mailing list