Commit 288cf517 authored by Jamie Liu's avatar Jamie Liu Committed by Pavel Emelyanov

restore: mutate tgt_addr in map_private_vma

prepare_mappings() uses the return value of map_private_vma() for the
size of the mapped vma. Unfortunately the return value of
map_private_vma() is an int, resulting in breakage when the size exceeds
31 bits. Change map_private_vma() to return only an error code, and
mutate addr in-place.
Signed-off-by: 's avatarJamie Liu <jamieliu@google.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 777255fb
...@@ -217,7 +217,7 @@ err: ...@@ -217,7 +217,7 @@ err:
} }
/* Map a private vma, if it is not mapped by a parent yet */ /* Map a private vma, if it is not mapped by a parent yet */
static int map_private_vma(pid_t pid, struct vma_area *vma, void *tgt_addr, static int map_private_vma(pid_t pid, struct vma_area *vma, void **tgt_addr,
struct vma_area **pvma, struct list_head *pvma_list) struct vma_area **pvma, struct list_head *pvma_list)
{ {
int ret; int ret;
...@@ -284,7 +284,7 @@ static int map_private_vma(pid_t pid, struct vma_area *vma, void *tgt_addr, ...@@ -284,7 +284,7 @@ static int map_private_vma(pid_t pid, struct vma_area *vma, void *tgt_addr,
pr_info("Map 0x%016"PRIx64"-0x%016"PRIx64" 0x%016"PRIx64" vma\n", pr_info("Map 0x%016"PRIx64"-0x%016"PRIx64" 0x%016"PRIx64" vma\n",
vma->e->start, vma->e->end, vma->e->pgoff); vma->e->start, vma->e->end, vma->e->pgoff);
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, vma->e->flags | MAP_FIXED,
vma->e->fd, vma->e->pgoff); vma->e->fd, vma->e->pgoff);
...@@ -301,8 +301,8 @@ static int map_private_vma(pid_t pid, struct vma_area *vma, void *tgt_addr, ...@@ -301,8 +301,8 @@ static int map_private_vma(pid_t pid, struct vma_area *vma, void *tgt_addr,
vma->ppage_bitmap = p->page_bitmap; vma->ppage_bitmap = p->page_bitmap;
addr = mremap(paddr, size, size, addr = mremap(paddr, size, size,
MREMAP_FIXED | MREMAP_MAYMOVE, tgt_addr); MREMAP_FIXED | MREMAP_MAYMOVE, *tgt_addr);
if (addr != tgt_addr) { if (addr != *tgt_addr) {
pr_perror("Unable to remap a private vma"); pr_perror("Unable to remap a private vma");
return -1; return -1;
} }
...@@ -321,7 +321,8 @@ static int map_private_vma(pid_t pid, struct vma_area *vma, void *tgt_addr, ...@@ -321,7 +321,8 @@ static int map_private_vma(pid_t pid, struct vma_area *vma, void *tgt_addr,
if (vma_area_is(vma, VMA_FILE_PRIVATE)) if (vma_area_is(vma, VMA_FILE_PRIVATE))
close(vma->e->fd); close(vma->e->fd);
return size; *tgt_addr += size;
return 0;
} }
static int restore_priv_vma_content(pid_t pid) static int restore_priv_vma_content(pid_t pid)
...@@ -518,11 +519,9 @@ static int prepare_mappings(int pid) ...@@ -518,11 +519,9 @@ static int prepare_mappings(int pid)
if (!vma_priv(vma->e)) if (!vma_priv(vma->e))
continue; continue;
ret = map_private_vma(pid, vma, addr, &pvma, parent_vmas); ret = map_private_vma(pid, vma, &addr, &pvma, parent_vmas);
if (ret < 0) if (ret < 0)
break; break;
addr += ret;
} }
if (ret >= 0) if (ret >= 0)
......
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