diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2008-08-27 09:47:24 +0100 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2008-08-27 09:47:24 +0100 |
commit | fe2998c24a7163659b848897b54219b5f0b03120 (patch) | |
tree | 54489cb70ce87e5ba7d667556eebd2f5dfff7123 /extras/mini-os/lib/sys.c | |
parent | 2f43a7baa99a38222117be970dbd4f098bcb76ea (diff) | |
download | xen-fe2998c24a7163659b848897b54219b5f0b03120.tar.gz xen-fe2998c24a7163659b848897b54219b5f0b03120.tar.bz2 xen-fe2998c24a7163659b848897b54219b5f0b03120.zip |
stubdom: make munmap work in batches to fix stack overflow
Signed-off-by: Samuel Thibault <samuel.thibault@eu.citrix.com>
Diffstat (limited to 'extras/mini-os/lib/sys.c')
-rw-r--r-- | extras/mini-os/lib/sys.c | 54 |
1 files changed, 32 insertions, 22 deletions
diff --git a/extras/mini-os/lib/sys.c b/extras/mini-os/lib/sys.c index 6267a3bb04..2141d00c65 100644 --- a/extras/mini-os/lib/sys.c +++ b/extras/mini-os/lib/sys.c @@ -1143,34 +1143,44 @@ void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset } else ASSERT(0); } +#define UNMAP_BATCH ((STACK_SIZE / 2) / sizeof(multicall_entry_t)) int munmap(void *start, size_t length) { - int i, n = length / PAGE_SIZE; - multicall_entry_t call[n]; - unsigned char (*data)[PAGE_SIZE] = start; - int ret; + int total = length / PAGE_SIZE; ASSERT(!((unsigned long)start & ~PAGE_MASK)); - ASSERT(!(length & ~PAGE_MASK)); + while (total) { + int n = UNMAP_BATCH; + if (n > total) + n = total; + { + int i; + multicall_entry_t call[n]; + unsigned char (*data)[PAGE_SIZE] = start; + int ret; - for (i = 0; i < n; i++) { - call[i].op = __HYPERVISOR_update_va_mapping; - call[i].args[0] = (unsigned long) &data[i]; - call[i].args[1] = 0; - call[i].args[2] = 0; - call[i].args[3] = UVMF_INVLPG; - } + for (i = 0; i < n; i++) { + call[i].op = __HYPERVISOR_update_va_mapping; + call[i].args[0] = (unsigned long) &data[i]; + call[i].args[1] = 0; + call[i].args[2] = 0; + call[i].args[3] = UVMF_INVLPG; + } - ret = HYPERVISOR_multicall(call, n); - if (ret) { - errno = -ret; - return -1; - } + ret = HYPERVISOR_multicall(call, n); + if (ret) { + errno = -ret; + return -1; + } - for (i = 0; i < n; i++) { - if (call[i].result) { - errno = call[i].result; - return -1; - } + for (i = 0; i < n; i++) { + if (call[i].result) { + errno = call[i].result; + return -1; + } + } + } + start += n * PAGE_SIZE; + total -= n; } return 0; } |