Commit 6603b419 authored by Michael Holzheu's avatar Michael Holzheu Committed by Pavel Emelyanov

s390:criu: Add TASK_SIZE check for dump and restore

For kernels that don't have commit ee71d16d22 ("s390/mm: make TASK_SIZE
independent from the number of page table levels") criu sets TASK_SIZE
to 4 TB on s390 (see compel_task_size()).

When dumping tasks >= 4 TB on such systems, we would silently loose
memory >= 4TB.

So add a check and refuse to dump the task in that case.

When restoring tasks >= 4 TB on such systems, the remap() call for
moving the vmas at the end of the restor process would fail
and a very unclear error message is printed.

So add a check and write a more speaking error message in that case.
Reviewed-by: 's avatarAlice Frosi <alice@linux.vnet.ibm.com>
Signed-off-by: 's avatarMichael Holzheu <holzheu@linux.vnet.ibm.com>
Signed-off-by: 's avatarAndrei Vagin <avagin@virtuozzo.com>
parent c2f30337
......@@ -741,6 +741,21 @@ static inline bool vma_force_premap(struct vma_area *vma, struct list_head *head
return false;
}
/*
* Ensure for s390x that vma is below task size on restore system
*/
static int task_size_check(pid_t pid, VmaEntry *entry)
{
#ifdef __s390x__
if (entry->end <= kdat.task_size)
return 0;
pr_err("Can't restore high memory region %lx-%lx because kernel does only support vmas up to %lx\n", entry->start, entry->end, kdat.task_size);
return -1;
#else
return 0;
#endif
}
static int premap_priv_vmas(struct pstree_item *t, struct vm_area_list *vmas,
void **at, struct page_read *pr)
{
......@@ -752,6 +767,10 @@ static int premap_priv_vmas(struct pstree_item *t, struct vm_area_list *vmas,
filemap_ctx_init(true);
list_for_each_entry(vma, &vmas->h, list) {
if (task_size_check(vpid(t), vma->e)) {
ret = -1;
break;
}
if (pstart > vma->e->start) {
ret = -1;
pr_err("VMA-s are not sorted in the image file\n");
......
......@@ -665,6 +665,22 @@ static int vma_list_add(struct vma_area *vma_area,
return 0;
}
/*
* On s390 we have old kernels where the global task size assumption of
* criu does not work. See also compel_task_size() for s390.
*/
static int task_size_check(pid_t pid, VmaEntry *entry)
{
#ifdef __s390x__
if (entry->end <= kdat.task_size)
return 0;
pr_err("Can't dump high memory region %lx-%lx of task %d because kernel commit ee71d16d22bb is missing\n", entry->start, entry->end, pid);
return -1;
#else
return 0;
#endif
}
int parse_smaps(pid_t pid, struct vm_area_list *vma_area_list,
dump_filemap_t dump_filemap)
{
......@@ -750,6 +766,9 @@ int parse_smaps(pid_t pid, struct vm_area_list *vma_area_list,
vma_area->e->pgoff = pgoff;
vma_area->e->prot = PROT_NONE;
if (task_size_check(pid, vma_area->e))
goto err;
if (r == 'r')
vma_area->e->prot |= PROT_READ;
if (w == 'w')
......
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