VM bugfix & regression test

The bug in the offset correction code for the 'shrink region from
below' case can easily case an assert(foundregion->offset == offset)
to trigger (if the blocks are touched afterwards, e.g. on fork())
as the offsets become wrong. This commit is a fix & regression test.

Change-Id: I28ed403e3891362a2dea674a49e786d3450d2983
This commit is contained in:
Ben Gras 2014-01-08 17:43:19 +01:00 committed by Gerrit Code Review
parent 502bc37a61
commit 274fdff60c
2 changed files with 21 additions and 3 deletions

View file

@ -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;

View file

@ -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);