[CRIU] [PATCHv3 15/23] restorer/vdso: use compat vdso symtab in restorer

Dmitry Safonov dsafonov at virtuozzo.com
Fri Dec 9 10:19:41 PST 2016


No need to fill symtab at restorer - previous commit add vdso filling at
startup: on vdso_init().
Now it's possible just to use the symtab and sizes if we need them.

Signed-off-by: Dmitry Safonov <dsafonov at virtuozzo.com>
---
 criu/cr-restore.c            | 13 +++++++++----
 criu/include/parasite-vdso.h |  5 ++---
 criu/include/vdso.h          |  1 +
 criu/pie/parasite-vdso.c     | 28 +++-------------------------
 criu/pie/restorer.c          |  9 +++------
 5 files changed, 18 insertions(+), 38 deletions(-)

diff --git a/criu/cr-restore.c b/criu/cr-restore.c
index c73b7c7ea5c7..79fb210d82a5 100644
--- a/criu/cr-restore.c
+++ b/criu/cr-restore.c
@@ -2886,6 +2886,7 @@ static int sigreturn_restore(pid_t pid, struct task_restore_args *task_args, uns
 	struct restore_mem_zone *mz;
 
 #ifdef CONFIG_VDSO
+	struct vdso_symtable vdso_symtab_rt;
 	unsigned long vdso_rt_size = 0;
 #endif
 
@@ -2930,12 +2931,16 @@ static int sigreturn_restore(pid_t pid, struct task_restore_args *task_args, uns
 			current->nr_threads, KBYTES(task_args->bootstrap_len));
 
 #ifdef CONFIG_VDSO
+	if (core_is_compat(core))
+		vdso_symtab_rt = vdso_compat_rt;
+	else
+		vdso_symtab_rt = vdso_sym_rt;
 	/*
 	 * Figure out how much memory runtime vdso and vvar will need.
 	 */
-	vdso_rt_size = vdso_vma_size(&vdso_sym_rt);
-	if (vdso_rt_size && vvar_vma_size(&vdso_sym_rt))
-		vdso_rt_size += ALIGN(vvar_vma_size(&vdso_sym_rt), PAGE_SIZE);
+	vdso_rt_size = vdso_vma_size(&vdso_symtab_rt);
+	if (vdso_rt_size && vvar_vma_size(&vdso_symtab_rt))
+		vdso_rt_size += ALIGN(vvar_vma_size(&vdso_symtab_rt), PAGE_SIZE);
 	task_args->bootstrap_len += vdso_rt_size;
 #endif
 
@@ -3158,7 +3163,7 @@ static int sigreturn_restore(pid_t pid, struct task_restore_args *task_args, uns
 	 */
 	mem += rst_mem_size;
 	task_args->vdso_rt_parked_at = (unsigned long)mem;
-	task_args->vdso_sym_rt = vdso_sym_rt;
+	task_args->vdso_sym_rt = vdso_symtab_rt;
 	task_args->vdso_rt_size = vdso_rt_size;
 #endif
 
diff --git a/criu/include/parasite-vdso.h b/criu/include/parasite-vdso.h
index 85db6e8264b7..efb282a60656 100644
--- a/criu/include/parasite-vdso.h
+++ b/criu/include/parasite-vdso.h
@@ -80,15 +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);
-extern int vdso_map_compat(unsigned long map_at, unsigned long *park_size,
-		struct vdso_symtable *sym_rt);
+extern 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, bool compat_vdso);
 
 #else /* CONFIG_VDSO */
 #define vdso_do_park(sym_rt, park_at, park_size)		(0)
-#define vdso_map_compat(map_at, park_size, sym_rt)		(0)
+#define vdso_map_compat(map_at)					(0)
 
 #endif /* CONFIG_VDSO */
 
diff --git a/criu/include/vdso.h b/criu/include/vdso.h
index ea6bfabbf3ec..9b6010c03d64 100644
--- a/criu/include/vdso.h
+++ b/criu/include/vdso.h
@@ -11,6 +11,7 @@
 #include "util-vdso.h"
 
 extern struct vdso_symtable vdso_sym_rt;
+extern struct vdso_symtable vdso_compat_rt;
 
 extern int vdso_init(void);
 
diff --git a/criu/pie/parasite-vdso.c b/criu/pie/parasite-vdso.c
index a88018da05fe..cb1fdd3f250d 100644
--- a/criu/pie/parasite-vdso.c
+++ b/criu/pie/parasite-vdso.c
@@ -69,10 +69,8 @@ int vdso_do_park(struct vdso_symtable *sym_rt, unsigned long park_at, unsigned l
 }
 
 #if defined(CONFIG_X86_64) && defined(CONFIG_COMPAT)
-int vdso_map_compat(unsigned long map_at, unsigned long *park_size,
-		struct vdso_symtable *sym_rt)
+int vdso_map_compat(unsigned long map_at)
 {
-	unsigned long search_vdso;
 	int ret;
 
 	pr_debug("Mapping compatible vDSO at %lx\n", map_at);
@@ -80,25 +78,7 @@ int vdso_map_compat(unsigned long map_at, unsigned long *park_size,
 	ret = sys_arch_prctl(ARCH_MAP_VDSO_32, map_at);
 	if (ret < 0)
 		return ret;
-	*park_size = (unsigned long)ret;
-
-	/*
-	 * We could map VVAR firstly, or VDSO.
-	 * Try to find VDSO pages in this couple of parking pages.
-	 * XXX: Please, FIXME - compat vdso/vvar sizes should be counted
-	 * at CRIU start time by parsing /proc/<...>/maps then by searching
-	 * ELF magic.
-	 */
-	for (search_vdso = map_at; search_vdso < map_at + *park_size;
-			search_vdso += PAGE_SIZE)
-	{
-		ret = vdso_fill_symtable_compat(search_vdso,
-			map_at + *park_size - search_vdso, sym_rt);
-		if (!ret)
-			return 0;
-	}
-	pr_err("Failed to parse a arch_prctl-mapped vDSO %d\n", ret);
-	return ret;
+	return 0;
 }
 
 int __vdso_fill_symtable(uintptr_t mem, size_t size,
@@ -110,9 +90,7 @@ int __vdso_fill_symtable(uintptr_t mem, size_t size,
 		return vdso_fill_symtable(mem, size, t);
 }
 #else
-int vdso_map_compat(unsigned long __always_unused map_at,
-		unsigned long __always_unused *park_size,
-		struct vdso_symtable __always_unused *sym_rt)
+int vdso_map_compat(unsigned long __always_unused map_at)
 {
 	/* shouldn't be called on !CONFIG_COMPAT */
 	BUG();
diff --git a/criu/pie/restorer.c b/criu/pie/restorer.c
index 3ab86df3e6fc..ccd0fbdf189d 100644
--- a/criu/pie/restorer.c
+++ b/criu/pie/restorer.c
@@ -1181,12 +1181,9 @@ long __export_restore_task(struct task_restore_args *args)
 				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,
-				&vdso_rt_size, &args->vdso_sym_rt))
-			goto core_restore_end;
-	}
+	/* Map compatible vdso */
+	if (args->compatible_mode && 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++) {
-- 
2.10.2



More information about the CRIU mailing list