Commit 3755e414 authored by Dmitry Safonov's avatar Dmitry Safonov Committed by Andrei Vagin

restorer/vdso: use compat vdso symtab in restorer

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.

travis-ci: success for Rectify 32-bit compatible C/R on x86
Signed-off-by: 's avatarDmitry Safonov <dsafonov@virtuozzo.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
Signed-off-by: 's avatarAndrei Vagin <avagin@virtuozzo.com>
parent b6eb6f16
......@@ -2892,6 +2892,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
......@@ -2936,12 +2937,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
......@@ -3163,7 +3168,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
......
......@@ -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 */
......
......@@ -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);
......
......@@ -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();
......
......@@ -1122,12 +1122,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++) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment