Commit 38daf50f authored by Fyodor's avatar Fyodor Committed by Pavel Emelyanov

page-xfer: fix wrong hole address offset

CRIU doesn't save vaddr of each anon shmem page in anon shared mem pagemap img.
It saves page offset from the beginning of anon shared memory area.
CRIU calls page_xfer_dump_pages() with non zero @off argument
to convert dumper virtual addresses to such offsets.

The problem is in page_xfer_dump_pages() code. It substracts @off
only for pages in pagemap but not for holes in pagemap.
Bug is fixed in this patch.
This patch is just a copy-paste of valid code path for pages to code path for holes.

Bug is not currently reproduced in CRIU because:
1. Only anon shmem provides non-zero @off value to page_xfer_dump_pages()
2. Anon shared memory doesn't create holes in its pagemap (for now)

This bugfix is a preparation for anon shared memory deduplication patchset.
Signed-off-by: 's avatarFyodor Bocharov <fbocharov@yandex.ru>
Signed-off-by: 's avatarEugene Batalov <eabatalov89@gmail.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 2a250921
...@@ -699,6 +699,8 @@ int page_xfer_dump_pages(struct page_xfer *xfer, struct page_pipe *pp, ...@@ -699,6 +699,8 @@ int page_xfer_dump_pages(struct page_xfer *xfer, struct page_pipe *pp,
struct iovec *iov = &ppb->iov[i]; struct iovec *iov = &ppb->iov[i];
while (hole && (hole->iov_base < iov->iov_base)) { while (hole && (hole->iov_base < iov->iov_base)) {
BUG_ON(hole->iov_base < (void *)off);
hole->iov_base -= off;
pr_debug("\th %p [%u]\n", hole->iov_base, pr_debug("\th %p [%u]\n", hole->iov_base,
(unsigned int)(hole->iov_len / PAGE_SIZE)); (unsigned int)(hole->iov_len / PAGE_SIZE));
if (xfer->write_hole(xfer, hole)) if (xfer->write_hole(xfer, hole))
...@@ -722,6 +724,8 @@ int page_xfer_dump_pages(struct page_xfer *xfer, struct page_pipe *pp, ...@@ -722,6 +724,8 @@ int page_xfer_dump_pages(struct page_xfer *xfer, struct page_pipe *pp,
} }
while (hole) { while (hole) {
BUG_ON(hole->iov_base < (void *)off);
hole->iov_base -= off;
pr_debug("\th* %p [%u]\n", hole->iov_base, pr_debug("\th* %p [%u]\n", hole->iov_base,
(unsigned int)(hole->iov_len / PAGE_SIZE)); (unsigned int)(hole->iov_len / PAGE_SIZE));
if (xfer->write_hole(xfer, hole)) if (xfer->write_hole(xfer, hole))
......
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