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