diff --git a/servers/vm/region.c b/servers/vm/region.c index 9728bdd1c..7450fd844 100644 --- a/servers/vm/region.c +++ b/servers/vm/region.c @@ -1102,8 +1102,7 @@ int map_unmap_region(struct vmproc *vmp, struct vir_region *r, region_remove(&vmp->vm_regions_avl, r->vaddr); USE(r, - r->vaddr += len; - r->length -= len;); + r->vaddr += len;); remslots = phys_slot(r->length); @@ -1113,15 +1112,17 @@ int map_unmap_region(struct vmproc *vmp, struct vir_region *r, * point to the same addresses, make them shrink by the * same amount. */ - for(voffset = offset; voffset < r->length; + for(voffset = len; voffset < r->length; voffset += VM_PAGE_SIZE) { if(!(pr = physblock_get(r, voffset))) continue; assert(pr->offset >= offset); + assert(pr->offset >= len); USE(pr, pr->offset -= len;); } if(remslots) memmove(r->physblocks, r->physblocks + freeslots, remslots * sizeof(struct phys_region *)); + USE(r, r->length -= len;); } else if(offset + len == r->length) { assert(len <= r->length); r->length -= len; diff --git a/test/test74.c b/test/test74.c index 8ccdaaaa0..7c7f24811 100644 --- a/test/test74.c +++ b/test/test74.c @@ -75,6 +75,21 @@ readblock(int b, int blocksize, u32_t seed, char *data) void testend(void) { } +void basic_regression(void) +{ + void *block; +#define BLOCKSIZE (PAGE_SIZE*10) + block = minix_mmap(0, BLOCKSIZE, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON, -1, 0); + + if(block == MAP_FAILED) { e(1); exit(1); } + + memset(block, 0, BLOCKSIZE); + + /* shrink from bottom */ + minix_munmap(block, PAGE_SIZE); +} + int main(int argc, char *argv[]) { @@ -82,6 +97,8 @@ main(int argc, char *argv[]) start(74); + basic_regression(); + makefiles(MAXFILES); cachequiet(!bigflag);