2
0
mirror of https://github.com/checkpoint-restore/criu synced 2025-09-05 08:45:49 +00:00

vdso: Remap runtime vdso copy to safe place

Runtime vdso need to be kept in some safe place when all
self-vmas are unmapped. So we reserve space for it in restorer
blob area and then remap it into. It's quite important to do
a remap here rather than data copy because otherwise pfn
of vdso disappear and in future we won't be able to detect
vdso are on dumping stage.

Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
This commit is contained in:
Cyrill Gorcunov
2013-05-24 01:42:14 +04:00
committed by Pavel Emelyanov
parent e44b3dbe84
commit b051c66fb6
7 changed files with 73 additions and 3 deletions

View File

@@ -1796,6 +1796,10 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
int *siginfo_priv_nr;
unsigned long siginfo_size = 0;
unsigned long vdso_rt_vma_size = 0;
unsigned long vdso_rt_size = 0;
unsigned long vdso_rt_delta = 0;
struct vm_area_list self_vmas;
int i;
@@ -1856,6 +1860,15 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
rst_tcp_socks_size +
siginfo_size;
/*
* Figure out how much memory runtime vdso will need.
*/
vdso_rt_vma_size = vdso_vma_size(&vdso_sym_rt);
if (vdso_rt_vma_size) {
vdso_rt_delta = ALIGN(restore_bootstrap_len, PAGE_SIZE) - restore_bootstrap_len;
vdso_rt_size = vdso_rt_vma_size + vdso_rt_delta;
}
/*
* Restorer is a blob (code + args) that will get mapped in some
* place, that should _not_ intersect with both -- current mappings
@@ -1868,15 +1881,16 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
*/
exec_mem_hint = restorer_get_vma_hint(pid, &rst_vmas.h, &self_vmas.h,
restore_bootstrap_len);
restore_bootstrap_len +
vdso_rt_size);
if (exec_mem_hint == -1) {
pr_err("No suitable area for task_restore bootstrap (%ldK)\n",
restore_bootstrap_len);
restore_bootstrap_len + vdso_rt_size);
goto err;
}
pr_info("Found bootstrap VMA hint at: 0x%lx (needs ~%ldK)\n", exec_mem_hint,
KBYTES(restore_bootstrap_len));
KBYTES(restore_bootstrap_len + vdso_rt_size));
ret = remap_restorer_blob((void *)exec_mem_hint);
if (ret < 0)
@@ -2051,6 +2065,16 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
memcpy(&task_args->t->blk_sigset, &core->tc->blk_sigset, sizeof(k_rtsigset_t));
task_args->t->has_blk_sigset = true;
/*
* Restorer needs own copy of vdso parameters. Runtime
* vdso must be kept non intersecting with anything else,
* since we need it being accessible even when own
* self-vmas are unmaped.
*/
mem += (unsigned long)rst_tcp_socks_size;
task_args->vdso_rt_parked_at = (unsigned long)mem + vdso_rt_delta;
task_args->vdso_sym_rt = vdso_sym_rt;
/*
* Adjust stack.
*/