Message ID | 59e9d91c7ae1b655997aec61c08eec1685414117.1333729958.git.riku.voipio@linaro.org |
---|---|
State | New |
Headers | show |
On 6 April 2012 17:35, <riku.voipio@linaro.org> wrote: > From: Peter Maydell <peter.maydell@linaro.org> > > After consulting with Paul Brook, we concluded that it's best to search > the VMA space downwards, so that we don't even get the chance to conflict > with the brk range. > > This patch resolves a bunch of allocation conflicts when using -R. > > Signed-off-by: Alexander Graf <agraf@suse.de> > [minor changes to get it to apply -- PMM] > > Signed-off-by: Riku Voipio <riku.voipio@linaro.org> Something odd has happened here. This patch claims to be From: me but has Alex's signoff. I suspect it should really be From: Alex. (I'm guessing maybe you cherry-picked this from the qemu-linaro tree? It looks like I was a bit careless when I put the patch into that, and didn't fix up the From attribution when the patch didn't apply cleanly.) -- PMM > --- > linux-user/main.c | 1 + > linux-user/mmap.c | 35 ++++++++++++++++++++++++----------- > linux-user/qemu.h | 1 + > 3 files changed, 26 insertions(+), 11 deletions(-) > > diff --git a/linux-user/main.c b/linux-user/main.c > index 2570140..aa95db3 100644 > --- a/linux-user/main.c > +++ b/linux-user/main.c > @@ -3420,6 +3420,7 @@ int main(int argc, char **argv, char **envp) > guest_base = HOST_PAGE_ALIGN((unsigned long)p); > } > qemu_log("Reserved 0x%lx bytes of guest address space\n", reserved_va); > + mmap_next_start = reserved_va; > } > > if (reserved_va || have_guest_base) { > diff --git a/linux-user/mmap.c b/linux-user/mmap.c > index 994c02b..7125d1c 100644 > --- a/linux-user/mmap.c > +++ b/linux-user/mmap.c > @@ -212,7 +212,7 @@ static int mmap_frag(abi_ulong real_start, > #else > # define TASK_UNMAPPED_BASE 0x40000000 > #endif > -static abi_ulong mmap_next_start = TASK_UNMAPPED_BASE; > +abi_ulong mmap_next_start = TASK_UNMAPPED_BASE; > > unsigned long last_brk; > > @@ -222,7 +222,7 @@ unsigned long last_brk; > static abi_ulong mmap_find_vma_reserved(abi_ulong start, abi_ulong size) > { > abi_ulong addr; > - abi_ulong last_addr; > + abi_ulong end_addr; > int prot; > int looped = 0; > > @@ -230,25 +230,38 @@ static abi_ulong mmap_find_vma_reserved(abi_ulong start, abi_ulong size) > return (abi_ulong)-1; > } > > - last_addr = start; > - for (addr = start; last_addr + size != addr; addr += qemu_host_page_size) { > - if (last_addr + size >= RESERVED_VA > - || (abi_ulong)(last_addr + size) < last_addr) { > + size = HOST_PAGE_ALIGN(size); > + end_addr = start + size; > + if (end_addr > RESERVED_VA) { > + end_addr = RESERVED_VA; > + } > + addr = end_addr - qemu_host_page_size; > + > + while (1) { > + if (addr > end_addr) { > if (looped) { > return (abi_ulong)-1; > } > - last_addr = qemu_host_page_size; > - addr = 0; > + end_addr = RESERVED_VA; > + addr = end_addr - qemu_host_page_size; > looped = 1; > continue; > } > prot = page_get_flags(addr); > if (prot) { > - last_addr = addr + qemu_host_page_size; > + end_addr = addr; > + } > + if (addr + size == end_addr) { > + break; > } > + addr -= qemu_host_page_size; > + } > + > + if (start == mmap_next_start) { > + mmap_next_start = addr; > } > - mmap_next_start = addr; > - return last_addr; > + > + return addr; > } > #endif > > diff --git a/linux-user/qemu.h b/linux-user/qemu.h > index 6889567..dd74cc0 100644 > --- a/linux-user/qemu.h > +++ b/linux-user/qemu.h > @@ -251,6 +251,7 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size, > abi_ulong new_addr); > int target_msync(abi_ulong start, abi_ulong len, int flags); > extern unsigned long last_brk; > +extern abi_ulong mmap_next_start; > void mmap_lock(void); > void mmap_unlock(void); > abi_ulong mmap_find_vma(abi_ulong, abi_ulong); > -- > 1.7.5.4 >
diff --git a/linux-user/main.c b/linux-user/main.c index 2570140..aa95db3 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -3420,6 +3420,7 @@ int main(int argc, char **argv, char **envp) guest_base = HOST_PAGE_ALIGN((unsigned long)p); } qemu_log("Reserved 0x%lx bytes of guest address space\n", reserved_va); + mmap_next_start = reserved_va; } if (reserved_va || have_guest_base) { diff --git a/linux-user/mmap.c b/linux-user/mmap.c index 994c02b..7125d1c 100644 --- a/linux-user/mmap.c +++ b/linux-user/mmap.c @@ -212,7 +212,7 @@ static int mmap_frag(abi_ulong real_start, #else # define TASK_UNMAPPED_BASE 0x40000000 #endif -static abi_ulong mmap_next_start = TASK_UNMAPPED_BASE; +abi_ulong mmap_next_start = TASK_UNMAPPED_BASE; unsigned long last_brk; @@ -222,7 +222,7 @@ unsigned long last_brk; static abi_ulong mmap_find_vma_reserved(abi_ulong start, abi_ulong size) { abi_ulong addr; - abi_ulong last_addr; + abi_ulong end_addr; int prot; int looped = 0; @@ -230,25 +230,38 @@ static abi_ulong mmap_find_vma_reserved(abi_ulong start, abi_ulong size) return (abi_ulong)-1; } - last_addr = start; - for (addr = start; last_addr + size != addr; addr += qemu_host_page_size) { - if (last_addr + size >= RESERVED_VA - || (abi_ulong)(last_addr + size) < last_addr) { + size = HOST_PAGE_ALIGN(size); + end_addr = start + size; + if (end_addr > RESERVED_VA) { + end_addr = RESERVED_VA; + } + addr = end_addr - qemu_host_page_size; + + while (1) { + if (addr > end_addr) { if (looped) { return (abi_ulong)-1; } - last_addr = qemu_host_page_size; - addr = 0; + end_addr = RESERVED_VA; + addr = end_addr - qemu_host_page_size; looped = 1; continue; } prot = page_get_flags(addr); if (prot) { - last_addr = addr + qemu_host_page_size; + end_addr = addr; + } + if (addr + size == end_addr) { + break; } + addr -= qemu_host_page_size; + } + + if (start == mmap_next_start) { + mmap_next_start = addr; } - mmap_next_start = addr; - return last_addr; + + return addr; } #endif diff --git a/linux-user/qemu.h b/linux-user/qemu.h index 6889567..dd74cc0 100644 --- a/linux-user/qemu.h +++ b/linux-user/qemu.h @@ -251,6 +251,7 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size, abi_ulong new_addr); int target_msync(abi_ulong start, abi_ulong len, int flags); extern unsigned long last_brk; +extern abi_ulong mmap_next_start; void mmap_lock(void); void mmap_unlock(void); abi_ulong mmap_find_vma(abi_ulong, abi_ulong);