Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Merge branch 'devel' of ssh://palacios@newskysaw.cs.northwestern.edu/home/palacios...
Patrick Bridges [Wed, 11 Aug 2010 15:41:59 +0000 (09:41 -0600)]
1  2 
palacios/src/palacios/vmm_mem.c

@@@ -50,23 -50,44 +50,23 @@@ static int unhandled_err(struct guest_i
      return -1;
  }
  
 -
 -static inline uint32_t get_alignment(char * align_str) {
 -    if (align_str != NULL) {
 -      if (strncasecmp(align_str, "2MB", strlen("2MB")) == 0) {
 -          return PAGE_SIZE_2MB;
 -      } else if (strncasecmp(align_str, "4MB", strlen("4MB")) == 0) {
 -          return PAGE_SIZE_4MB;
 -      }
 -    }
 -    
 -    // default is 4KB alignment
 -    return PAGE_SIZE_4KB;
 -}
 -
  int v3_init_mem_map(struct v3_vm_info * vm) {
      struct v3_mem_map * map = &(vm->mem_map);
 -    v3_cfg_tree_t * pg_cfg = v3_cfg_subtree(vm->cfg_data->cfg, "memory");
 -    uint32_t alignment = get_alignment(v3_cfg_val(pg_cfg, "alignment"));
      addr_t mem_pages = vm->mem_size >> 12;
  
      memset(&(map->base_region), 0, sizeof(struct v3_mem_region));
  
      map->mem_regions.rb_node = NULL;
  
 -
      // There is an underlying region that contains all of the guest memory
      // PrintDebug("Mapping %d pages of memory (%u bytes)\n", (int)mem_pages, (uint_t)info->mem_size);
  
      map->base_region.guest_start = 0;
      map->base_region.guest_end = mem_pages * PAGE_SIZE_4KB;
  
 -#ifdef ALIGNED_PG_ALLOC
 -    map->base_region.host_addr = (addr_t)V3_AllocAlignedPages(mem_pages, alignment);
 +#ifdef CONFIG_ALIGNED_PG_ALLOC
 +    map->base_region.host_addr = (addr_t)V3_AllocAlignedPages(mem_pages, vm->mem_align);
  #else
 -    if (alignment != PAGE_SIZE_4KB) {
 -      PrintError("Aligned page allocations are not supported in this host (requested alignment=%d)\n", alignment);
 -      PrintError("Ignoring alignment request\n");
 -    }
      map->base_region.host_addr = (addr_t)V3_AllocPages(mem_pages);
  #endif
  
@@@ -290,30 -311,38 +290,38 @@@ struct v3_mem_region * v3_get_mem_regio
  
  
  
- /* Search the "hooked" memory regions for a region that ends after the given address.  If the
-  * address is invalid, return NULL. Else, return the first region found or the base region if no
-  * region ends after the given address.
+ /* Given an address, find the successor region. If the address is within a region, return that
+  * region. Input is an address, because the address may not have a region associated with it.
+  *
+  * Returns a region following or touching the given address. If address is invalid, NULL is
+  * returned, else the base region is returned if no region exists at or after the given address.
   */
  struct v3_mem_region * v3_get_next_mem_region( struct v3_vm_info * vm, uint16_t core_id, addr_t guest_addr) {
-     struct rb_node * n = vm->mem_map.mem_regions.rb_node;
-     struct v3_mem_region * reg = NULL;
-     // Keep going to the right in the tree while the address is greater than the current region's
-     // end address.
-     while (n) {
-         reg = rb_entry(n, struct v3_mem_region, tree_node);
-         if (guest_addr >= reg->guest_end) { // reg is [start,end)
-             n = n->rb_right;
-         } else {
-           if ((core_id == reg->core_id) || (reg->core_id == V3_MEM_CORE_ANY)) {
-               return reg;
-           } else {
-               n = n->rb_right;
+     struct rb_node * current_n                = vm->mem_map.mem_regions.rb_node;
+     struct rb_node * successor_n      = NULL; /* left-most node greater than guest_addr */
+     struct v3_mem_region * current_r  = NULL;
+     /* current_n tries to find the region containing guest_addr, going right when smaller and left when
+      * greater. Each time current_n becomes greater than guest_addr, update successor <- current_n.
+      * current_n becomes successively closer to guest_addr than the previous time it was greater
+      * than guest_addr.
+      */
+     /* | is address, ---- is region, + is intersection */
+     while (current_n) {
+         current_r = rb_entry(current_n, struct v3_mem_region, tree_node);
+       if (current_r->guest_start > guest_addr) { /* | ---- */
+           successor_n = current_n;
+           current_n = current_n->rb_left;
+       } else {
+           if (current_r->guest_end > guest_addr) {
+               return current_r; /* +--- or --+- */
            }
-         }
+           current_n = current_n->rb_right; /* ---- | */
+       }
      }
  
-     // There is no registered region, so we check if it's a valid address in the base region
+     /* Address does not have its own region. Check if it's a valid address in the base region */
  
      if (guest_addr >= vm->mem_map.base_region.guest_end) {
        PrintError("%s: Guest Address Exceeds Base Memory Size (ga=%p), (limit=%p)\n",