Commit 6273fc97 authored by Mike Rapoport's avatar Mike Rapoport Committed by Andrei Vagin

uffd: add handling of zero pages

When get_page returns 0, it means that a page is mapped by a vma but it is
not found in the pagemap. This happens when a page is a zero page and
threofre skipped by dump.
Use UFFDIO_ZEROMAP to create a zero page in the restored process address
space.
Signed-off-by: 's avatarMike Rapoport <rppt@linux.vnet.ibm.com>
Acked-by: 's avatarAdrian Reber <areber@redhat.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
parent 58edba63
...@@ -256,7 +256,7 @@ static int uffd_copy_page(int uffd, __u64 address, void *dest) ...@@ -256,7 +256,7 @@ static int uffd_copy_page(int uffd, __u64 address, void *dest)
rc = get_page(address, dest); rc = get_page(address, dest);
if (rc <= 0) if (rc <= 0)
return -1; return rc;
uffdio_copy.dst = address; uffdio_copy.dst = address;
uffdio_copy.src = (unsigned long) dest; uffdio_copy.src = (unsigned long) dest;
...@@ -285,9 +285,37 @@ static int uffd_copy_page(int uffd, __u64 address, void *dest) ...@@ -285,9 +285,37 @@ static int uffd_copy_page(int uffd, __u64 address, void *dest)
} }
static int uffd_zero_page(int uffd, __u64 address)
{
struct uffdio_zeropage uffdio_zeropage;
unsigned long ps = page_size();
int rc;
uffdio_zeropage.range.start = address;
uffdio_zeropage.range.len = ps;
uffdio_zeropage.mode = 0;
pr_debug("uffdio_zeropage.range.start 0x%llx\n", uffdio_zeropage.range.start);
rc = ioctl(uffd, UFFDIO_ZEROPAGE, &uffdio_zeropage);
pr_debug("ioctl UFFDIO_ZEROPAGE rc 0x%x\n", rc);
pr_debug("uffdio_zeropage.zeropage 0x%llx\n", uffdio_zeropage.zeropage);
if (rc) {
pr_err("UFFDIO_ZEROPAGE error %d\n", rc);
return -1;
}
return ps;
}
static int uffd_handle_page(int uffd, __u64 address, void *dest) static int uffd_handle_page(int uffd, __u64 address, void *dest)
{ {
return uffd_copy_page(uffd, address, dest); int rc;
rc = uffd_copy_page(uffd, address, dest);
if (rc == 0)
rc = uffd_zero_page(uffd, address);
return rc;
} }
static int collect_uffd_pages(struct page_read *pr, struct list_head *uffd_list) static int collect_uffd_pages(struct page_read *pr, struct list_head *uffd_list)
......
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