mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-30 13:58:34 +00:00
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: Dmitry Safonov <dsafonov@virtuozzo.com> Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
This commit is contained in:
parent
3f6cce9850
commit
b8f3fca489
@ -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 */
|
||||
|
22
criu/vdso.c
22
criu/vdso.c
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user