threw out sanity checks before pagetable rewrites, triggering false
page table inconsistencies. fix handle_memory logic. again.
This commit is contained in:
parent
67602ce85e
commit
7a45f80bd5
@ -59,6 +59,24 @@ PRIVATE char *map_name(struct vir_region *vr)
|
|||||||
return "NOTREACHED";
|
return "NOTREACHED";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PUBLIC void map_printregion(struct vmproc *vmp, struct vir_region *vr)
|
||||||
|
{
|
||||||
|
physr_iter iter;
|
||||||
|
struct phys_region *ph;
|
||||||
|
printf("map_printmap: map_name: %s\n", map_name(vr));
|
||||||
|
printf("\t%s (len 0x%lx), %s\n",
|
||||||
|
arch_map2str(vmp, vr->vaddr), vr->length,
|
||||||
|
map_name(vr));
|
||||||
|
printf("\t\tphysblocks:\n");
|
||||||
|
physr_start_iter_least(vr->phys, &iter);
|
||||||
|
while((ph = physr_get_iter(&iter))) {
|
||||||
|
printf("\t\t@ %s (refs %d): phys 0x%lx len 0x%lx\n",
|
||||||
|
arch_map2str(vmp, vr->vaddr + ph->offset),
|
||||||
|
ph->ph->refcount, ph->ph->phys, ph->ph->length);
|
||||||
|
physr_incr_iter(&iter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* map_printmap *
|
* map_printmap *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
@ -66,28 +84,10 @@ PUBLIC void map_printmap(vmp)
|
|||||||
struct vmproc *vmp;
|
struct vmproc *vmp;
|
||||||
{
|
{
|
||||||
struct vir_region *vr;
|
struct vir_region *vr;
|
||||||
physr_iter iter;
|
|
||||||
|
|
||||||
printf("memory regions in process %d:\n", vmp->vm_endpoint);
|
printf("memory regions in process %d:\n", vmp->vm_endpoint);
|
||||||
for(vr = vmp->vm_regions; vr; vr = vr->next) {
|
for(vr = vmp->vm_regions; vr; vr = vr->next) {
|
||||||
struct phys_region *ph;
|
map_printregion(vmp, vr);
|
||||||
int nph = 0;
|
|
||||||
printf("map_printmap: map_name: %s\n", map_name(vr));
|
|
||||||
printf("\t0x%lx - 0x%lx (len 0x%lx), %s\n",
|
|
||||||
vr->vaddr, vr->vaddr + vr->length, vr->length,
|
|
||||||
map_name(vr));
|
|
||||||
printf("\t\tphysical: ");
|
|
||||||
physr_start_iter_least(vr->phys, &iter);
|
|
||||||
while((ph = physr_get_iter(&iter))) {
|
|
||||||
printf("0x%lx-0x%lx (refs %d): phys 0x%lx ",
|
|
||||||
vr->vaddr + ph->offset,
|
|
||||||
vr->vaddr + ph->offset + ph->ph->length,
|
|
||||||
ph->ph->refcount,
|
|
||||||
ph->ph->phys);
|
|
||||||
nph++;
|
|
||||||
physr_incr_iter(&iter);
|
|
||||||
}
|
|
||||||
printf(" (phregions %d)\n", nph);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -219,11 +219,18 @@ PRIVATE int map_ph_writept(struct vmproc *vmp, struct vir_region *vr,
|
|||||||
|
|
||||||
if(pt_writemap(&vmp->vm_pt, vr->vaddr + pr->offset,
|
if(pt_writemap(&vmp->vm_pt, vr->vaddr + pr->offset,
|
||||||
pb->phys, pb->length, PTF_PRESENT | PTF_USER | rw,
|
pb->phys, pb->length, PTF_PRESENT | PTF_USER | rw,
|
||||||
WMF_OVERWRITE) != OK) {
|
#if SANITYCHECKS
|
||||||
|
!pr->written ? 0 :
|
||||||
|
#endif
|
||||||
|
WMF_OVERWRITE) != OK) {
|
||||||
printf("VM: map_writept: pt_writemap failed\n");
|
printf("VM: map_writept: pt_writemap failed\n");
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if SANITYCHECKS
|
||||||
|
USE(pr, pr->written = 1;);
|
||||||
|
#endif
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -674,6 +681,9 @@ phys_bytes what_mem;
|
|||||||
newphysr->ph = newpb;
|
newphysr->ph = newpb;
|
||||||
newphysr->parent = region;
|
newphysr->parent = region;
|
||||||
newphysr->next_ph_list = NULL; /* No other references to this block. */);
|
newphysr->next_ph_list = NULL; /* No other references to this block. */);
|
||||||
|
#if SANITYCHECKS
|
||||||
|
USE(newphysr, newphysr->written = 0;);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Update pagetable. */
|
/* Update pagetable. */
|
||||||
vm_assert(!(length % VM_PAGE_SIZE));
|
vm_assert(!(length % VM_PAGE_SIZE));
|
||||||
@ -709,15 +719,12 @@ struct phys_region *ph;
|
|||||||
struct phys_block *newpb;
|
struct phys_block *newpb;
|
||||||
u32_t af = 0;
|
u32_t af = 0;
|
||||||
|
|
||||||
SANITYCHECK(SCL_FUNCTIONS);
|
|
||||||
|
|
||||||
/* This is only to be done if there is more than one copy. */
|
/* This is only to be done if there is more than one copy. */
|
||||||
vm_assert(ph->ph->refcount > 1);
|
vm_assert(ph->ph->refcount > 1);
|
||||||
|
|
||||||
/* Do actual copy on write; allocate new physblock. */
|
/* Do actual copy on write; allocate new physblock. */
|
||||||
if(!SLABALLOC(newpb)) {
|
if(!SLABALLOC(newpb)) {
|
||||||
printf("VM: map_copy_ph_block: couldn't allocate newpb\n");
|
printf("VM: map_copy_ph_block: couldn't allocate newpb\n");
|
||||||
SANITYCHECK(SCL_FUNCTIONS);
|
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -752,7 +759,6 @@ USE(newpb,
|
|||||||
/* Copy old memory to new memory. */
|
/* Copy old memory to new memory. */
|
||||||
if((r=sys_abscopy(ph->ph->phys, newpb->phys, newpb->length)) != OK) {
|
if((r=sys_abscopy(ph->ph->phys, newpb->phys, newpb->length)) != OK) {
|
||||||
printf("VM: map_copy_ph_block: sys_abscopy failed\n");
|
printf("VM: map_copy_ph_block: sys_abscopy failed\n");
|
||||||
SANITYCHECK(SCL_FUNCTIONS);
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -763,9 +769,6 @@ USE(newpb,
|
|||||||
/* Reference new block. */
|
/* Reference new block. */
|
||||||
USE(ph, ph->ph = newpb;);
|
USE(ph, ph->ph = newpb;);
|
||||||
|
|
||||||
/* Check reference counts. */
|
|
||||||
SANITYCHECK(SCL_DETAIL);
|
|
||||||
|
|
||||||
/* Update pagetable with new address.
|
/* Update pagetable with new address.
|
||||||
* This will also make it writable.
|
* This will also make it writable.
|
||||||
*/
|
*/
|
||||||
@ -773,8 +776,6 @@ USE(newpb,
|
|||||||
if(r != OK)
|
if(r != OK)
|
||||||
vm_panic("map_copy_ph_block: map_ph_writept failed", r);
|
vm_panic("map_copy_ph_block: map_ph_writept failed", r);
|
||||||
|
|
||||||
SANITYCHECK(SCL_FUNCTIONS);
|
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -827,11 +828,19 @@ int write;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(r != OK)
|
|
||||||
printf("VM: map_pf: failed (%d)\n", r);
|
|
||||||
|
|
||||||
SANITYCHECK(SCL_FUNCTIONS);
|
SANITYCHECK(SCL_FUNCTIONS);
|
||||||
|
|
||||||
|
if(r != OK) {
|
||||||
|
printf("VM: map_pf: failed (%d)\n", r);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if SANITYCHECKS
|
||||||
|
if(OK != pt_checkrange(&vmp->vm_pt, region->vaddr+offset, VM_PAGE_SIZE, write)) {
|
||||||
|
vm_panic("map_pf: pt_checkrange failed", r);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -868,6 +877,7 @@ int write;
|
|||||||
changes++; \
|
changes++; \
|
||||||
} }
|
} }
|
||||||
|
|
||||||
|
|
||||||
SANITYCHECK(SCL_FUNCTIONS);
|
SANITYCHECK(SCL_FUNCTIONS);
|
||||||
|
|
||||||
vm_assert(region->flags & VR_ANON);
|
vm_assert(region->flags & VR_ANON);
|
||||||
@ -876,19 +886,33 @@ int write;
|
|||||||
vm_assert(!(length % VM_PAGE_SIZE));
|
vm_assert(!(length % VM_PAGE_SIZE));
|
||||||
vm_assert(!write || (region->flags & VR_WRITABLE));
|
vm_assert(!write || (region->flags & VR_WRITABLE));
|
||||||
|
|
||||||
physr_start_iter(region->phys, &iter, offset, AVL_GREATER_EQUAL);
|
physr_start_iter(region->phys, &iter, offset, AVL_LESS_EQUAL);
|
||||||
physr = physr_get_iter(&iter);
|
physr = physr_get_iter(&iter);
|
||||||
|
|
||||||
if(!physr || offset < physr->offset) {
|
if(!physr) {
|
||||||
physr_iter previter;
|
physr_start_iter(region->phys, &iter, offset, AVL_GREATER_EQUAL);
|
||||||
struct phys_region *prevphysr;
|
physr = physr_get_iter(&iter);
|
||||||
previter = iter;
|
}
|
||||||
physr_decr_iter(&iter);
|
|
||||||
prevphysr = physr_get_iter(&iter);
|
|
||||||
|
|
||||||
FREE_RANGE_HERE(prevphysr, physr);
|
#define RESET_ITER(it, where, what) { \
|
||||||
|
physr_start_iter(region->phys, &it, where, AVL_EQUAL); \
|
||||||
|
what = physr_get_iter(&it); \
|
||||||
|
if(!what) vm_panic("thing missing", NO_NUM); \
|
||||||
|
}
|
||||||
|
|
||||||
iter = previter;
|
FREE_RANGE_HERE(NULL, physr);
|
||||||
|
|
||||||
|
if(physr) {
|
||||||
|
RESET_ITER(iter, physr->offset, physr);
|
||||||
|
if(physr->offset + physr->ph->length <= offset) {
|
||||||
|
physr_incr_iter(&iter);
|
||||||
|
physr = physr_get_iter(&iter);
|
||||||
|
|
||||||
|
if(physr) {
|
||||||
|
FREE_RANGE_HERE(NULL, physr);
|
||||||
|
RESET_ITER(iter, physr->offset, physr);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while(physr) {
|
while(physr) {
|
||||||
@ -926,6 +950,7 @@ int write;
|
|||||||
if(nextphysr) {
|
if(nextphysr) {
|
||||||
if(nextphysr->offset >= offset + length)
|
if(nextphysr->offset >= offset + length)
|
||||||
break;
|
break;
|
||||||
|
RESET_ITER(iter, nextphysr->offset, nextphysr);
|
||||||
}
|
}
|
||||||
physr = nextphysr;
|
physr = nextphysr;
|
||||||
}
|
}
|
||||||
@ -934,6 +959,15 @@ int write;
|
|||||||
|
|
||||||
vm_assert(changes > 0);
|
vm_assert(changes > 0);
|
||||||
|
|
||||||
|
#if SANITYCHECKS
|
||||||
|
if(OK != pt_checkrange(&vmp->vm_pt, region->vaddr+offset, length, write)) {
|
||||||
|
printf("handle mem %s-", arch_map2str(vmp, region->vaddr+offset));
|
||||||
|
printf("%s failed\n", arch_map2str(vmp, region->vaddr+offset+length));
|
||||||
|
map_printregion(vmp, region);
|
||||||
|
vm_panic("checkrange failed", NO_NUM);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -988,8 +1022,6 @@ PRIVATE struct vir_region *map_copy_region(struct vmproc *vmp, struct vir_region
|
|||||||
);
|
);
|
||||||
physr_init(newvr->phys);
|
physr_init(newvr->phys);
|
||||||
|
|
||||||
SANITYCHECK(SCL_FUNCTIONS);
|
|
||||||
|
|
||||||
physr_start_iter_least(vr->phys, &iter);
|
physr_start_iter_least(vr->phys, &iter);
|
||||||
while((ph = physr_get_iter(&iter))) {
|
while((ph = physr_get_iter(&iter))) {
|
||||||
struct phys_region *newph;
|
struct phys_region *newph;
|
||||||
@ -1002,16 +1034,16 @@ PRIVATE struct vir_region *map_copy_region(struct vmproc *vmp, struct vir_region
|
|||||||
newph->next_ph_list = NULL;
|
newph->next_ph_list = NULL;
|
||||||
newph->parent = newvr;
|
newph->parent = newvr;
|
||||||
newph->offset = ph->offset;);
|
newph->offset = ph->offset;);
|
||||||
|
#if SANITYCHECKS
|
||||||
|
USE(newph, newph->written = 0;);
|
||||||
|
#endif
|
||||||
physr_insert(newvr->phys, newph);
|
physr_insert(newvr->phys, newph);
|
||||||
SANITYCHECK(SCL_DETAIL);
|
|
||||||
vm_assert(countregions(vr) == cr);
|
vm_assert(countregions(vr) == cr);
|
||||||
physr_incr_iter(&iter);
|
physr_incr_iter(&iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
vm_assert(countregions(vr) == countregions(newvr));
|
vm_assert(countregions(vr) == countregions(newvr));
|
||||||
|
|
||||||
SANITYCHECK(SCL_FUNCTIONS);
|
|
||||||
|
|
||||||
return newvr;
|
return newvr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1057,13 +1089,10 @@ struct vmproc *src;
|
|||||||
physr_iter iter_orig, iter_new;
|
physr_iter iter_orig, iter_new;
|
||||||
struct vir_region *newvr;
|
struct vir_region *newvr;
|
||||||
struct phys_region *orig_ph, *new_ph;
|
struct phys_region *orig_ph, *new_ph;
|
||||||
SANITYCHECK(SCL_DETAIL);
|
|
||||||
if(!(newvr = map_copy_region(dst, vr))) {
|
if(!(newvr = map_copy_region(dst, vr))) {
|
||||||
map_free_proc(dst);
|
map_free_proc(dst);
|
||||||
SANITYCHECK(SCL_FUNCTIONS);
|
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
}
|
}
|
||||||
SANITYCHECK(SCL_DETAIL);
|
|
||||||
USE(newvr, newvr->parent = dst;);
|
USE(newvr, newvr->parent = dst;);
|
||||||
if(prevvr) { USE(prevvr, prevvr->next = newvr;); }
|
if(prevvr) { USE(prevvr, prevvr->next = newvr;); }
|
||||||
else { dst->vm_regions = newvr; }
|
else { dst->vm_regions = newvr; }
|
||||||
@ -1096,18 +1125,11 @@ struct vmproc *src;
|
|||||||
physr_incr_iter(&iter_new);
|
physr_incr_iter(&iter_new);
|
||||||
}
|
}
|
||||||
vm_assert(!physr_get_iter(&iter_new));
|
vm_assert(!physr_get_iter(&iter_new));
|
||||||
SANITYCHECK(SCL_DETAIL);
|
|
||||||
prevvr = newvr;
|
prevvr = newvr;
|
||||||
SANITYCHECK(SCL_DETAIL);
|
|
||||||
}
|
}
|
||||||
SANITYCHECK(SCL_DETAIL);
|
|
||||||
|
|
||||||
PT_SANE(&src->vm_pt);
|
|
||||||
|
|
||||||
map_writept(src);
|
map_writept(src);
|
||||||
PT_SANE(&src->vm_pt);
|
|
||||||
map_writept(dst);
|
map_writept(dst);
|
||||||
PT_SANE(&dst->vm_pt);
|
|
||||||
|
|
||||||
SANITYCHECK(SCL_FUNCTIONS);
|
SANITYCHECK(SCL_FUNCTIONS);
|
||||||
return OK;
|
return OK;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user