aboutsummaryrefslogtreecommitdiffstats
path: root/extras/mini-os/lib
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2008-08-27 09:47:24 +0100
committerKeir Fraser <keir.fraser@citrix.com>2008-08-27 09:47:24 +0100
commitfe2998c24a7163659b848897b54219b5f0b03120 (patch)
tree54489cb70ce87e5ba7d667556eebd2f5dfff7123 /extras/mini-os/lib
parent2f43a7baa99a38222117be970dbd4f098bcb76ea (diff)
downloadxen-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')
-rw-r--r--extras/mini-os/lib/sys.c54
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;
}