Commit b8f3fca4 authored by Dmitry Safonov's avatar Dmitry Safonov Committed by Andrei Vagin

vdso: Don't parse self-maps if kdat.can_map_vdso

Just map vdso at restorer's parking zone, no need for
searching it in CRIU and remap it to park zone.
That will save some open()/read()/close() syscalls
for parsing maps file.
Signed-off-by: 's avatarDmitry Safonov <dsafonov@virtuozzo.com>
Signed-off-by: 's avatarAndrei Vagin <avagin@virtuozzo.com>
parent 3f6cce98
......@@ -54,6 +54,7 @@
#define kdat_compatible_cr() 0
#define kdat_can_map_vdso() 0
#define arch_map_vdso(map, compat) -1
int restore_gpregs(struct rt_sigframe *f, UserAarch64RegsEntry *r);
int restore_nonsigframe_gpregs(UserAarch64RegsEntry *r);
......
......@@ -55,6 +55,7 @@
#define kdat_compatible_cr() 0
#define kdat_can_map_vdso() 0
#define arch_map_vdso(map, compat) -1
int restore_gpregs(struct rt_sigframe *f, UserArmRegsEntry *r);
int restore_nonsigframe_gpregs(UserArmRegsEntry *r);
......
......@@ -50,6 +50,7 @@
#define kdat_compatible_cr() 0
#define kdat_can_map_vdso() 0
#define arch_map_vdso(map, compat) -1
int restore_gpregs(struct rt_sigframe *f, UserPpc64RegsEntry *r);
int restore_nonsigframe_gpregs(UserPpc64RegsEntry *r);
......
......@@ -76,6 +76,10 @@ static inline int set_compat_robust_list(uint32_t head_ptr, uint32_t len)
# define ARCH_MAP_VDSO_32 0x2002
#endif
#ifndef ARCH_MAP_VDSO_64
# define ARCH_MAP_VDSO_64 0x2003
#endif
extern int kdat_compatible_cr(void);
extern int kdat_can_map_vdso(void);
......@@ -114,5 +118,6 @@ int restore_nonsigframe_gpregs(UserX86RegsEntry *r);
int ptrace_set_breakpoint(pid_t pid, void *addr);
int ptrace_flush_breakpoints(pid_t pid);
extern int arch_map_vdso(unsigned long map_at, bool compatible);
#endif
......@@ -13,6 +13,16 @@
#include "log.h"
#include "cpu.h"
int arch_map_vdso(unsigned long map_at, bool compatible)
{
int vdso_type = compatible ? ARCH_MAP_VDSO_32 : ARCH_MAP_VDSO_64;
pr_debug("Mapping %s vDSO at %lx\n",
compatible ? "compatible" : "native", map_at);
return sys_arch_prctl(vdso_type, map_at);
}
int restore_nonsigframe_gpregs(UserX86RegsEntry *r)
{
long ret;
......
......@@ -3310,6 +3310,7 @@ static int sigreturn_restore(pid_t pid, struct task_restore_args *task_args, uns
task_args->vdso_rt_parked_at = (unsigned long)mem;
task_args->vdso_maps_rt = vdso_maps_rt;
task_args->vdso_rt_size = vdso_rt_size;
task_args->can_map_vdso = kdat.can_map_vdso;
#endif
new_sp = restorer_stack(task_args->t->mz);
......
......@@ -191,6 +191,7 @@ struct task_restore_args {
bool compatible_mode;
bool can_map_vdso;
#ifdef CONFIG_VDSO
unsigned long vdso_rt_size;
struct vdso_maps vdso_maps_rt; /* runtime vdso symbols */
......
......@@ -74,19 +74,8 @@ int vdso_do_park(struct vdso_maps *rt, unsigned long park_at,
return ret;
}
/* XXX: move in arch/ */
#if defined(CONFIG_X86_64) && defined(CONFIG_COMPAT)
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);
if (ret < 0)
return ret;
return 0;
}
int __vdso_fill_symtable(uintptr_t mem, size_t size,
struct vdso_symtable *t, bool compat_vdso)
{
......@@ -96,12 +85,6 @@ 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)
{
/* shouldn't be called on !CONFIG_COMPAT */
BUG();
return 0;
}
int __vdso_fill_symtable(uintptr_t mem, size_t size,
struct vdso_symtable *t, bool __always_unused compat_vdso)
{
......
......@@ -1156,6 +1156,9 @@ static bool vdso_needs_parking(struct task_restore_args *args)
if (args->compatible_mode)
return false;
if (args->can_map_vdso)
return false;
return !vdso_unmapped(args);
}
......@@ -1226,10 +1229,12 @@ long __export_restore_task(struct task_restore_args *args)
bootstrap_start, bootstrap_len, args->task_size))
goto core_restore_end;
/* Map compatible vdso */
if (!vdso_unmapped(args) && args->compatible_mode) {
if (vdso_map_compat(args->vdso_rt_parked_at))
/* Map vdso that wasn't parked */
if (!vdso_unmapped(args) && args->can_map_vdso) {
if (arch_map_vdso(args->vdso_rt_parked_at,
args->compatible_mode) < 0) {
goto core_restore_end;
}
}
/* Shift private vma-s to the left */
......
......@@ -572,14 +572,22 @@ int vdso_init_restore(void)
if (vdso_maps.vdso_start != VDSO_BAD_ADDR)
return 0;
if (vdso_parse_maps(PROC_SELF, &vdso_maps)) {
pr_err("Failed reading self/maps for filling vdso/vvar bounds\n");
return -1;
}
/*
* Parsing self-maps here only to find vvar/vdso vmas in
* criu's address space, for further remapping to restorer's
* parking zone. Don't need to do this if map-vdso API
* is present.
*/
if (!kdat.can_map_vdso) {
if (vdso_parse_maps(PROC_SELF, &vdso_maps)) {
pr_err("Failed reading self/maps for filling vdso/vvar bounds\n");
return -1;
}
if (!is_kdat_vdso_sym_valid()) {
pr_err("Kdat sizes of vdso/vvar differ to maps file \n");
return -1;
if (!is_kdat_vdso_sym_valid()) {
pr_err("Kdat sizes of vdso/vvar differ to maps file \n");
return -1;
}
}
vdso_maps.sym = kdat.vdso_sym;
......
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