Commit c9194500 authored by Pavel Emelyanov's avatar Pavel Emelyanov

mem: Don't do unneeded mprotects

When a vma we restore doesn't have any pages in pagemaps there's
not need to enforce PROT_WRITE bit on it.

This only applies to non-premmaped vmas.
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
Signed-off-by: 's avatarAndrei Vagin <avagin@virtuozzo.com>
parent 91388fce
...@@ -89,6 +89,7 @@ ...@@ -89,6 +89,7 @@
#define VMA_AREA_VVAR (1 << 12) #define VMA_AREA_VVAR (1 << 12)
#define VMA_AREA_AIORING (1 << 13) #define VMA_AREA_AIORING (1 << 13)
#define VMA_NO_PROT_WRITE (1 << 29)
#define VMA_PREMMAPED (1 << 30) #define VMA_PREMMAPED (1 << 30)
#define VMA_UNSUPP (1 << 31) #define VMA_UNSUPP (1 << 31)
......
...@@ -659,6 +659,13 @@ static int premap_private_vma(struct pstree_item *t, struct vma_area *vma, void ...@@ -659,6 +659,13 @@ static int premap_private_vma(struct pstree_item *t, struct vma_area *vma, void
} }
} }
/*
* All mappings here get PROT_WRITE regardless of whether we
* put any data into it or not, because this area will get
* mremap()-ed (branch below) so we MIGHT need to have WRITE
* bits there. Ideally we'd check for the whole COW-chain
* having any data in.
*/
addr = mmap(*tgt_addr, size, addr = mmap(*tgt_addr, size,
vma->e->prot | PROT_WRITE, vma->e->prot | PROT_WRITE,
vma->e->flags | MAP_FIXED | flag, vma->e->flags | MAP_FIXED | flag,
...@@ -755,14 +762,26 @@ static int premap_priv_vmas(struct pstree_item *t, struct vm_area_list *vmas, ...@@ -755,14 +762,26 @@ static int premap_priv_vmas(struct pstree_item *t, struct vm_area_list *vmas,
if (!vma_area_is_private(vma, kdat.task_size)) if (!vma_area_is_private(vma, kdat.task_size))
continue; continue;
if (vma->pvma == NULL && pr->pieok && !vma_force_premap(vma, &vmas->h)) if (vma->pvma == NULL && pr->pieok && !vma_force_premap(vma, &vmas->h)) {
/* /*
* VMA in question is not shared with anyone. We'll * VMA in question is not shared with anyone. We'll
* restore it with its contents in restorer. * restore it with its contents in restorer.
* Now let's check whether we need to map it with
* PROT_WRITE or not.
*/ */
do {
if (pr->pe->vaddr + pr->pe->nr_pages * PAGE_SIZE <= vma->e->start)
continue; continue;
if (pr->pe->vaddr > vma->e->end)
vma->e->status |= VMA_NO_PROT_WRITE;
break;
} while (pr->advance(pr));
continue;
}
ret = premap_private_vma(t, vma, at); ret = premap_private_vma(t, vma, at);
if (ret < 0) if (ret < 0)
break; break;
} }
...@@ -831,6 +850,12 @@ static int restore_priv_vma_content(struct pstree_item *t, struct page_read *pr) ...@@ -831,6 +850,12 @@ static int restore_priv_vma_content(struct pstree_item *t, struct page_read *pr)
(nr_pages - i) * PAGE_SIZE, (nr_pages - i) * PAGE_SIZE,
vma->e->end - va); vma->e->end - va);
if (vma->e->status & VMA_NO_PROT_WRITE) {
pr_debug("VMA 0x%"PRIx64":0x%"PRIx64" RO %#lx:%lu IO\n",
vma->e->start, vma->e->end, va, nr_pages);
BUG();
}
if (pagemap_enqueue_iovec(pr, (void *)va, len, vma_io)) if (pagemap_enqueue_iovec(pr, (void *)va, len, vma_io))
return -1; return -1;
......
...@@ -600,7 +600,8 @@ static unsigned long restore_mapping(VmaEntry *vma_entry) ...@@ -600,7 +600,8 @@ static unsigned long restore_mapping(VmaEntry *vma_entry)
flags |= MAP_ANONYMOUS; flags |= MAP_ANONYMOUS;
/* A mapping of file with MAP_SHARED is up to date */ /* A mapping of file with MAP_SHARED is up to date */
if (vma_entry->fd == -1 || !(vma_entry->flags & MAP_SHARED)) if ((vma_entry->fd == -1 || !(vma_entry->flags & MAP_SHARED)) &&
!(vma_entry->status & VMA_NO_PROT_WRITE))
prot |= PROT_WRITE; prot |= PROT_WRITE;
pr_debug("\tmmap(%"PRIx64" -> %"PRIx64", %x %x %d)\n", pr_debug("\tmmap(%"PRIx64" -> %"PRIx64", %x %x %d)\n",
...@@ -1261,7 +1262,8 @@ long __export_restore_task(struct task_restore_args *args) ...@@ -1261,7 +1262,8 @@ long __export_restore_task(struct task_restore_args *args)
if (!(vma_entry_is(vma_entry, VMA_AREA_REGULAR))) if (!(vma_entry_is(vma_entry, VMA_AREA_REGULAR)))
continue; continue;
if (vma_entry->prot & PROT_WRITE) if ((vma_entry->prot & PROT_WRITE) ||
(vma_entry->status & VMA_NO_PROT_WRITE))
continue; continue;
sys_mprotect(decode_pointer(vma_entry->start), sys_mprotect(decode_pointer(vma_entry->start),
......
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