117 lines
3.5 KiB
Diff
117 lines
3.5 KiB
Diff
From a6664afab4b925f8ae74b6fe20e3634f42690e90 Mon Sep 17 00:00:00 2001
|
|
From: Alexander Graf <agraf@suse.de>
|
|
Date: Sun, 4 Mar 2012 02:41:14 +0100
|
|
Subject: [PATCH] linux-user: resolve reserved_va vma downwards
|
|
|
|
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>
|
|
|
|
---
|
|
|
|
This replaces the other patches I sent out earlier today.
|
|
---
|
|
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 6a5dfde..d61d731 100644
|
|
--- a/linux-user/main.c
|
|
+++ b/linux-user/main.c
|
|
@@ -3437,6 +3437,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 e4db455..2620f88 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 0x18000000
|
|
#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 aa06acf..5dc0720 100644
|
|
--- a/linux-user/qemu.h
|
|
+++ b/linux-user/qemu.h
|
|
@@ -254,6 +254,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);
|