Commit f3e322a1 authored by Andrey Vagin's avatar Andrey Vagin Committed by Pavel Emelyanov

restore: don't unmap premmapped private vma-s (v2)

Private vma-s are mapped before forking children, then they are
remapped to corrected places in restorer.c.

In restorer all unneeded vma-s are unmaped. VMA-s from premmapped
regions should not be unmaped.

v2: replace guard pages on arithmetic in restorer
Signed-off-by: 's avatarAndrey Vagin <avagin@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 1a9d87de
...@@ -1588,6 +1588,8 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core) ...@@ -1588,6 +1588,8 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
mem += self_vmas_len; mem += self_vmas_len;
task_args->tgt_vmas = vma_list_remap(mem, vmas_len, &rst_vma_list); task_args->tgt_vmas = vma_list_remap(mem, vmas_len, &rst_vma_list);
task_args->premmapped_addr = (unsigned long) premmapped_addr;
task_args->premmapped_len = premmapped_len;
if (!task_args->tgt_vmas) if (!task_args->tgt_vmas)
goto err; goto err;
......
...@@ -99,6 +99,8 @@ struct task_restore_core_args { ...@@ -99,6 +99,8 @@ struct task_restore_core_args {
struct task_entries *task_entries; struct task_entries *task_entries;
VmaEntry *self_vmas; VmaEntry *self_vmas;
VmaEntry *tgt_vmas; VmaEntry *tgt_vmas;
unsigned long premmapped_addr;
unsigned long premmapped_len;
rt_sigaction_t sigchld_act; rt_sigaction_t sigchld_act;
struct itimerval itimers[3]; struct itimerval itimers[3];
......
...@@ -333,6 +333,7 @@ long __export_restore_task(struct task_restore_core_args *args) ...@@ -333,6 +333,7 @@ long __export_restore_task(struct task_restore_core_args *args)
long ret = -1; long ret = -1;
VmaEntry *vma_entry; VmaEntry *vma_entry;
u64 va; u64 va;
unsigned long premmapped_end = args->premmapped_addr + args->premmapped_len;
struct rt_sigframe *rt_sigframe; struct rt_sigframe *rt_sigframe;
unsigned long new_sp; unsigned long new_sp;
...@@ -350,12 +351,33 @@ long __export_restore_task(struct task_restore_core_args *args) ...@@ -350,12 +351,33 @@ long __export_restore_task(struct task_restore_core_args *args)
pr_info("Switched to the restorer %d\n", my_pid); pr_info("Switched to the restorer %d\n", my_pid);
for (vma_entry = args->self_vmas; vma_entry->start != 0; vma_entry++) { for (vma_entry = args->self_vmas; vma_entry->start != 0; vma_entry++) {
unsigned long addr = vma_entry->start;
unsigned long len;
if (!vma_entry_is(vma_entry, VMA_AREA_REGULAR)) if (!vma_entry_is(vma_entry, VMA_AREA_REGULAR))
continue; continue;
if (sys_munmap((void *)vma_entry->start, vma_entry_len(vma_entry))) { pr_debug("Examine %lx-%lx\n", vma_entry->start, vma_entry->end);
pr_err("Munmap fail for %lx\n", vma_entry->start);
goto core_restore_end; if (addr < args->premmapped_addr) {
if (vma_entry->end >= args->premmapped_addr)
len = args->premmapped_addr - addr;
else
len = vma_entry->end - vma_entry->start;
if (sys_munmap((void *) addr, len)) {
pr_err("munmap fail for %lx - %lx\n", addr, addr + len);
goto core_restore_end;
}
}
if (vma_entry->end > premmapped_end) {
if (vma_entry->start < premmapped_end)
addr = premmapped_end;
len = vma_entry->end - addr;
if (sys_munmap((void *) addr, len)) {
pr_err("munmap fail for %lx - %lx\n", addr, addr + len);
goto core_restore_end;
}
} }
} }
......
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