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:
parent
502bc37a61
commit
274fdff60c
2 changed files with 21 additions and 3 deletions
|
@ -1102,8 +1102,7 @@ int map_unmap_region(struct vmproc *vmp, struct vir_region *r,
|
||||||
region_remove(&vmp->vm_regions_avl, r->vaddr);
|
region_remove(&vmp->vm_regions_avl, r->vaddr);
|
||||||
|
|
||||||
USE(r,
|
USE(r,
|
||||||
r->vaddr += len;
|
r->vaddr += len;);
|
||||||
r->length -= len;);
|
|
||||||
|
|
||||||
remslots = phys_slot(r->length);
|
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
|
* point to the same addresses, make them shrink by the
|
||||||
* same amount.
|
* same amount.
|
||||||
*/
|
*/
|
||||||
for(voffset = offset; voffset < r->length;
|
for(voffset = len; voffset < r->length;
|
||||||
voffset += VM_PAGE_SIZE) {
|
voffset += VM_PAGE_SIZE) {
|
||||||
if(!(pr = physblock_get(r, voffset))) continue;
|
if(!(pr = physblock_get(r, voffset))) continue;
|
||||||
assert(pr->offset >= offset);
|
assert(pr->offset >= offset);
|
||||||
|
assert(pr->offset >= len);
|
||||||
USE(pr, pr->offset -= len;);
|
USE(pr, pr->offset -= len;);
|
||||||
}
|
}
|
||||||
if(remslots)
|
if(remslots)
|
||||||
memmove(r->physblocks, r->physblocks + freeslots,
|
memmove(r->physblocks, r->physblocks + freeslots,
|
||||||
remslots * sizeof(struct phys_region *));
|
remslots * sizeof(struct phys_region *));
|
||||||
|
USE(r, r->length -= len;);
|
||||||
} else if(offset + len == r->length) {
|
} else if(offset + len == r->length) {
|
||||||
assert(len <= r->length);
|
assert(len <= r->length);
|
||||||
r->length -= len;
|
r->length -= len;
|
||||||
|
|
|
@ -75,6 +75,21 @@ readblock(int b, int blocksize, u32_t seed, char *data)
|
||||||
|
|
||||||
void testend(void) { }
|
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
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
@ -82,6 +97,8 @@ main(int argc, char *argv[])
|
||||||
|
|
||||||
start(74);
|
start(74);
|
||||||
|
|
||||||
|
basic_regression();
|
||||||
|
|
||||||
makefiles(MAXFILES);
|
makefiles(MAXFILES);
|
||||||
|
|
||||||
cachequiet(!bigflag);
|
cachequiet(!bigflag);
|
||||||
|
|
Loading…
Reference in a new issue