struct vmproc *vmp;
vir_bytes v;
{
- vir_bytes new_sp;
- vir_clicks new_clicks;
- int r;
-
- new_clicks = (vir_clicks) (CLICK_CEIL(v) >> CLICK_SHIFT);
- if (new_clicks < vmp->vm_arch.vm_seg[D].mem_vir) {
- printf("VM: real_brk failed because new_clicks too high: %d\n",
- new_clicks);
- return(ENOMEM);
- }
- new_clicks -= vmp->vm_arch.vm_seg[D].mem_vir;
- if ((r=get_stack_ptr(vmp->vm_endpoint, &new_sp)) != OK)
- panic("couldn't get stack pointer: %d", r);
- r = adjust(vmp, new_clicks, new_sp);
- return r;
+ if(!(vmp->vm_flags & VMF_HASPT))
+ return OK;
+
+ if(map_region_extend_upto_v(vmp, v) == OK)
+ return OK;
+
+ return(ENOMEM);
}
struct vir_region * map_proc_kernel(struct vmproc *dst);
int map_region_extend(struct vmproc *vmp, struct vir_region *vr,
vir_bytes delta);
+int map_region_extend_upto_v(struct vmproc *vmp, vir_bytes vir);
int map_region_shrink(struct vir_region *vr, vir_bytes delta);
int map_unmap_region(struct vmproc *vmp, struct vir_region *vr,
vir_bytes len);
return vr; /* Return pointer not useful, just non-NULL. */
}
+int map_region_extend_upto_v(struct vmproc *vmp, vir_bytes v)
+{
+ vir_bytes offset, o, end;
+ struct vir_region *vr, *nextvr;
+
+ offset = arch_vir2map(vmp, v);
+
+ if((o=(offset % VM_PAGE_SIZE))) {
+ offset+= VM_PAGE_SIZE - o;
+ }
+
+ if(!(vr = region_search(&vmp->vm_regions_avl, offset, AVL_LESS_EQUAL))) {
+ printf("VM: nothing to extend\n");
+ return ENOMEM;
+ }
+
+ if(!(vr->flags & VR_ANON)) {
+ printf("VM: memory range to extend not anonymous\n");
+ return ENOMEM;
+ }
+
+ assert(vr->vaddr <= offset);
+ if((nextvr = getnextvr(vr))) {
+ assert(offset < nextvr->vaddr);
+ }
+
+ end = vr->vaddr + vr->length;
+
+ if(offset < end)
+ return map_region_shrink(vr, end - offset);
+
+ return map_region_extend(vmp, vr, offset - end);
+
+ return ENOMEM;
+}
+
/*========================================================================*
* map_region_extend *
*========================================================================*/