mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-29 13:28:27 +00:00
vdso/kdat: Store symtable in kerndat_s
Don't need to parse vdso symtable each restore - it's boot-persistent, so move it into criu.kdat file on tmpfs. That will also remove syscalls made for filling compat vdso symtable by compat vdso helper. Reviewed-by: Cyrill Gorcunov <gorcunov@openvz.org> Signed-off-by: Dmitry Safonov <dsafonov@virtuozzo.com> Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
This commit is contained in:
parent
78402658c2
commit
7ad5df9e9f
@ -5,6 +5,9 @@
|
||||
|
||||
#include "int.h"
|
||||
#include "config.h"
|
||||
#ifdef CONFIG_VDSO
|
||||
#include "util-vdso.h"
|
||||
#endif
|
||||
|
||||
struct stat;
|
||||
|
||||
@ -52,6 +55,12 @@ struct kerndat_s {
|
||||
bool has_uffd;
|
||||
unsigned long uffd_features;
|
||||
bool has_thp_disable;
|
||||
#ifdef CONFIG_VDSO
|
||||
struct vdso_symtable vdso_sym;
|
||||
#ifdef CONFIG_COMPAT
|
||||
struct vdso_symtable vdso_sym_compat;
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
extern struct kerndat_s kdat;
|
||||
|
@ -15,6 +15,7 @@ extern struct vdso_maps vdso_maps_compat;
|
||||
|
||||
extern int vdso_init_dump(void);
|
||||
extern int vdso_init_restore(void);
|
||||
extern int kerndat_vdso_fill_symtable(void);
|
||||
|
||||
extern int parasite_fixup_vdso(struct parasite_ctl *ctl, pid_t pid,
|
||||
struct vm_area_list *vma_area_list);
|
||||
@ -28,6 +29,7 @@ extern void compat_vdso_helper(struct vdso_maps *native, int pipe_fd,
|
||||
|
||||
#define vdso_init_dump() (0)
|
||||
#define vdso_init_restore() (0)
|
||||
#define kerndat_vdso_fill_symtable() (0)
|
||||
#define parasite_fixup_vdso(ctl, pid, vma_area_list) (0)
|
||||
|
||||
#endif /* CONFIG_VDSO */
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include "linux/userfaultfd.h"
|
||||
#include "prctl.h"
|
||||
#include "uffd.h"
|
||||
#include "vdso.h"
|
||||
|
||||
struct kerndat_s kdat = {
|
||||
};
|
||||
@ -861,6 +862,9 @@ int kerndat_init(void)
|
||||
ret = kerndat_uffd();
|
||||
if (!ret)
|
||||
ret = kerndat_has_thp_disable();
|
||||
/* Needs kdat.compat_cr filled before */
|
||||
if (!ret)
|
||||
ret = kerndat_vdso_fill_symtable();
|
||||
|
||||
kerndat_lsm();
|
||||
kerndat_mmap_min_addr();
|
||||
|
57
criu/vdso.c
57
criu/vdso.c
@ -457,13 +457,6 @@ out_unmap:
|
||||
pr_perror("Failed to unmap buf for compat vdso");
|
||||
return ret;
|
||||
}
|
||||
|
||||
#else /* CONFIG_COMPAT */
|
||||
static int vdso_fill_compat_symtable(struct vdso_maps *native,
|
||||
struct vdso_maps *compat)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_COMPAT */
|
||||
|
||||
int vdso_init_dump(void)
|
||||
@ -481,7 +474,53 @@ int vdso_init_dump(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check vdso/vvar sized read from maps to kdat values.
|
||||
* We do not read /proc/self/maps for compatible vdso as it's
|
||||
* not parked as run-time vdso in restorer, but mapped with
|
||||
* arch_prlctl(MAP_VDSO_32) API.
|
||||
* By that reason we verify only native sizes.
|
||||
*/
|
||||
static int is_kdat_vdso_sym_valid(void)
|
||||
{
|
||||
if (vdso_maps.sym.vdso_size != kdat.vdso_sym.vdso_size)
|
||||
return false;
|
||||
if (vdso_maps.sym.vvar_size != kdat.vdso_sym.vvar_size)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int vdso_init_restore(void)
|
||||
{
|
||||
if (kdat.vdso_sym.vdso_size == VDSO_BAD_SIZE) {
|
||||
pr_err("Kdat has empty vdso symtable\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Already filled vdso_maps during kdat test */
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
#ifdef CONFIG_COMPAT
|
||||
vdso_maps_compat.sym = kdat.vdso_sym_compat;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kerndat_vdso_fill_symtable(void)
|
||||
{
|
||||
if (vdso_parse_maps(PROC_SELF, &vdso_maps)) {
|
||||
pr_err("Failed reading self/maps for filling vdso/vvar bounds\n");
|
||||
@ -492,11 +531,15 @@ int vdso_init_restore(void)
|
||||
pr_err("Failed to fill self vdso symtable\n");
|
||||
return -1;
|
||||
}
|
||||
kdat.vdso_sym = vdso_maps.sym;
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
if (vdso_fill_compat_symtable(&vdso_maps, &vdso_maps_compat)) {
|
||||
pr_err("Failed to fill compat vdso symtable\n");
|
||||
return -1;
|
||||
}
|
||||
kdat.vdso_sym_compat = vdso_maps_compat.sym;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user