mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-30 13:58:34 +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 "int.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#ifdef CONFIG_VDSO
|
||||||
|
#include "util-vdso.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
struct stat;
|
struct stat;
|
||||||
|
|
||||||
@ -52,6 +55,12 @@ struct kerndat_s {
|
|||||||
bool has_uffd;
|
bool has_uffd;
|
||||||
unsigned long uffd_features;
|
unsigned long uffd_features;
|
||||||
bool has_thp_disable;
|
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;
|
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_dump(void);
|
||||||
extern int vdso_init_restore(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,
|
extern int parasite_fixup_vdso(struct parasite_ctl *ctl, pid_t pid,
|
||||||
struct vm_area_list *vma_area_list);
|
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_dump() (0)
|
||||||
#define vdso_init_restore() (0)
|
#define vdso_init_restore() (0)
|
||||||
|
#define kerndat_vdso_fill_symtable() (0)
|
||||||
#define parasite_fixup_vdso(ctl, pid, vma_area_list) (0)
|
#define parasite_fixup_vdso(ctl, pid, vma_area_list) (0)
|
||||||
|
|
||||||
#endif /* CONFIG_VDSO */
|
#endif /* CONFIG_VDSO */
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#include "linux/userfaultfd.h"
|
#include "linux/userfaultfd.h"
|
||||||
#include "prctl.h"
|
#include "prctl.h"
|
||||||
#include "uffd.h"
|
#include "uffd.h"
|
||||||
|
#include "vdso.h"
|
||||||
|
|
||||||
struct kerndat_s kdat = {
|
struct kerndat_s kdat = {
|
||||||
};
|
};
|
||||||
@ -861,6 +862,9 @@ int kerndat_init(void)
|
|||||||
ret = kerndat_uffd();
|
ret = kerndat_uffd();
|
||||||
if (!ret)
|
if (!ret)
|
||||||
ret = kerndat_has_thp_disable();
|
ret = kerndat_has_thp_disable();
|
||||||
|
/* Needs kdat.compat_cr filled before */
|
||||||
|
if (!ret)
|
||||||
|
ret = kerndat_vdso_fill_symtable();
|
||||||
|
|
||||||
kerndat_lsm();
|
kerndat_lsm();
|
||||||
kerndat_mmap_min_addr();
|
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");
|
pr_perror("Failed to unmap buf for compat vdso");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* CONFIG_COMPAT */
|
|
||||||
static int vdso_fill_compat_symtable(struct vdso_maps *native,
|
|
||||||
struct vdso_maps *compat)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_COMPAT */
|
#endif /* CONFIG_COMPAT */
|
||||||
|
|
||||||
int vdso_init_dump(void)
|
int vdso_init_dump(void)
|
||||||
@ -481,7 +474,53 @@ int vdso_init_dump(void)
|
|||||||
return 0;
|
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)
|
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)) {
|
if (vdso_parse_maps(PROC_SELF, &vdso_maps)) {
|
||||||
pr_err("Failed reading self/maps for filling vdso/vvar bounds\n");
|
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");
|
pr_err("Failed to fill self vdso symtable\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
kdat.vdso_sym = vdso_maps.sym;
|
||||||
|
|
||||||
|
#ifdef CONFIG_COMPAT
|
||||||
if (vdso_fill_compat_symtable(&vdso_maps, &vdso_maps_compat)) {
|
if (vdso_fill_compat_symtable(&vdso_maps, &vdso_maps_compat)) {
|
||||||
pr_err("Failed to fill compat vdso symtable\n");
|
pr_err("Failed to fill compat vdso symtable\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
kdat.vdso_sym_compat = vdso_maps_compat.sym;
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user