]> Zhao Yanbai Git Server - minix.git/commitdiff
vm: break: allow brk() on any region
authorBen Gras <ben@minix3.org>
Fri, 6 Apr 2012 23:19:28 +0000 (01:19 +0200)
committerBen Gras <ben@minix3.org>
Thu, 12 Apr 2012 00:57:59 +0000 (02:57 +0200)
use the user-supplied point to lookup which region to perform brk() on,
and if it's a reasonable one, do it, no matter what vm's notion of the
heap region is.

servers/vm/break.c
servers/vm/proto.h
servers/vm/region.c

index 6882bc1ac674f1b4250f54141ac9b5bfd4513ebb..bc4a0687a543f23adde466a7c769ed1534264d11 100644 (file)
@@ -167,19 +167,11 @@ int real_brk(vmp, v)
 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);
 }
index 0d3ea3f8a7877f2ee381fd5ac3f252976d43eaa2..14dd12febb73062d0d91338c5514f34ed8901b2e 100644 (file)
@@ -144,6 +144,7 @@ struct vir_region * map_page_region(struct vmproc *vmp, vir_bytes min,
 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);
index 2a3cabebab786dd8dc85f15e5bf392f056c68686..744ad3ee6dd0996b79130bbfefd992762f085154 100644 (file)
@@ -1665,6 +1665,42 @@ struct vir_region *map_proc_kernel(struct vmproc *vmp)
        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                       *
  *========================================================================*/