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.


Constraints in page allocation, and code changes to use them; shadow paging allocati...
[palacios.git] / palacios / src / palacios / mmu / vmm_shdw_pg_swapbypass.c
index af23fed..06c5a40 100644 (file)
@@ -27,7 +27,7 @@
 #include <palacios/vmm_hashtable.h>
 
 
-#ifdef CONFIG_SWAPBYPASS_TELEMETRY
+#ifdef V3_CONFIG_SWAPBYPASS_TELEMETRY
 #include <palacios/vmm_telemetry.h>
 #endif
 
@@ -86,7 +86,7 @@ struct v3_swap_dev {
 struct swapbypass_vm_state {
     struct v3_swap_dev devs[256];
 
-#ifdef CONFIG_SWAPBYPASS_TELEMETRY
+#ifdef V3_CONFIG_SWAPBYPASS_TELEMETRY
     uint32_t read_faults;
     uint32_t write_faults;
     uint32_t flushes;
@@ -135,16 +135,16 @@ static struct shadow_page_data * create_new_shadow_pt(struct guest_info * core);
 
 
 
-#ifdef CONFIG_SWAPBYPASS_TELEMETRY
+#ifdef V3_CONFIG_SWAPBYPASS_TELEMETRY
 static void telemetry_cb(struct v3_vm_info * vm, void * private_data, char * hdr) {
     struct swapbypass_vm_state * swap_state = (struct swapbypass_vm_state *)(vm->shdw_impl.impl_data);
 
-    V3_Print("%sSymbiotic Swap:\n", hdr);
-    V3_Print("%s\tRead faults=%d\n", hdr, swap_state->read_faults);
-    V3_Print("%s\tWrite faults=%d\n", hdr, swap_state->write_faults);
-    V3_Print("%s\tMapped Pages=%d\n", hdr, swap_state->mapped_pages);
-    V3_Print("%s\tFlushes=%d\n", hdr, swap_state->flushes);
-    V3_Print("%s\tlist size=%d\n", hdr, swap_state->list_size);
+    V3_Print(vm, VCORE_NONE, "%sSymbiotic Swap:\n", hdr);
+    V3_Print(vm, VCORE_NONE, "%s\tRead faults=%d\n", hdr, swap_state->read_faults);
+    V3_Print(vm, VCORE_NONE, "%s\tWrite faults=%d\n", hdr, swap_state->write_faults);
+    V3_Print(vm, VCORE_NONE, "%s\tMapped Pages=%d\n", hdr, swap_state->mapped_pages);
+    V3_Print(vm, VCORE_NONE, "%s\tFlushes=%d\n", hdr, swap_state->flushes);
+    V3_Print(vm, VCORE_NONE, "%s\tlist size=%d\n", hdr, swap_state->list_size);
 }
 #endif
 
@@ -161,11 +161,11 @@ static int get_vaddr_perms(struct guest_info * info, addr_t vaddr, pte32_t * gue
 
     // symcall to check if page is in cache or on swap disk
     if (v3_sym_call3(info, SYMCALL_MEM_LOOKUP, (uint64_t *)&vaddr, (uint64_t *)&pte_val, (uint64_t *)page_perms) == -1) {
-       PrintError("Sym call error?? that's weird... \n");
+       PrintError(info->vm_info, info, "Sym call error?? that's weird... \n");
        return -1;
     }
 
-    //    V3_Print("page perms = %x\n", *(uint32_t *)page_perms);
+    //    V3_Print(info->vm_info, info, "page perms = %x\n", *(uint32_t *)page_perms);
 
     if (vaddr == 0) {
        return 1;
@@ -198,15 +198,21 @@ static addr_t map_swp_page(struct v3_vm_info * vm, pte32_t * shadow_pte, pte32_t
 
 
     if (swp_page_ptr == NULL) {
-       //      PrintError("Swapped out page not found on swap device\n");
+       //      PrintError(vm, VCORE_NONE, "Swapped out page not found on swap device\n");
        return 0;
     }
 
     shdw_ptr_list = (struct list_head *)v3_htable_search(swap_state->shdw_ptr_ht, (addr_t)*(uint32_t *)guest_pte);
 
     if (shdw_ptr_list == NULL) {
-       shdw_ptr_list = (struct list_head *)V3_Malloc(sizeof(struct list_head *));
-#ifdef CONFIG_SWAPBYPASS_TELEMETRY
+       shdw_ptr_list = (struct list_head *)V3_Malloc(sizeof(struct list_head));
+
+       if (!shdw_ptr_list) {
+           PrintError(vm, VCORE_NONE, "Cannot allocate\n");
+           return 0;
+       }
+
+#ifdef V3_CONFIG_SWAPBYPASS_TELEMETRY
        swap_state->list_size++;
 #endif
        INIT_LIST_HEAD(shdw_ptr_list);
@@ -216,8 +222,8 @@ static addr_t map_swp_page(struct v3_vm_info * vm, pte32_t * shadow_pte, pte32_t
     shdw_ptr = (struct shadow_pointer *)V3_Malloc(sizeof(struct shadow_pointer));
 
     if (shdw_ptr == NULL) {
-       PrintError("MEMORY LEAK\n");
-#ifdef CONFIG_SWAPBYPASS_TELEMETRY
+       PrintError(vm, VCORE_NONE, "MEMORY LEAK\n");
+#ifdef V3_CONFIG_SWAPBYPASS_TELEMETRY
        telemetry_cb(vm, NULL, "");
 #endif
        return 0;
@@ -242,6 +248,25 @@ static addr_t map_swp_page(struct v3_vm_info * vm, pte32_t * shadow_pte, pte32_t
 #include "vmm_shdw_pg_swapbypass_32pae.h"
 #include "vmm_shdw_pg_swapbypass_64.h"
 
+static inline int get_constraints(struct guest_info *core) 
+{
+    switch (v3_get_vm_cpu_mode(core)) {
+       case PROTECTED:
+       case PROTECTED_PAE:
+           return V3_ALLOC_PAGES_CONSTRAINT_4GB;
+           break;
+       case LONG:
+       case LONG_32_COMPAT:
+       case LONG_16_COMPAT:
+           return 0;
+           break;
+       default:
+           return V3_ALLOC_PAGES_CONSTRAINT_4GB;
+           break;
+    }
+    return V3_ALLOC_PAGES_CONSTRAINT_4GB;
+}
+
 
 static struct shadow_page_data * create_new_shadow_pt(struct guest_info * core) {
     struct v3_shdw_pg_state * state = &(core->shdw_pg_state);
@@ -255,7 +280,7 @@ static struct shadow_page_data * create_new_shadow_pt(struct guest_info * core)
 
 
        if (page_tail->cr3 != cur_cr3) {
-           PrintDebug("Reusing old shadow Page: %p (cur_CR3=%p)(page_cr3=%p) \n",
+           PrintDebug(core->vm_info, core, "Reusing old shadow Page: %p (cur_CR3=%p)(page_cr3=%p) \n",
                       (void *)(addr_t)page_tail->page_pa, 
                       (void *)(addr_t)cur_cr3, 
                       (void *)(addr_t)(page_tail->cr3));
@@ -272,9 +297,20 @@ static struct shadow_page_data * create_new_shadow_pt(struct guest_info * core)
     // else  
 
     page_tail = (struct shadow_page_data *)V3_Malloc(sizeof(struct shadow_page_data));
-    page_tail->page_pa = (addr_t)V3_AllocPages(1);
 
-    PrintDebug("Allocating new shadow Page: %p (cur_cr3=%p)\n", 
+    if (!page_tail) {
+       PrintError(core->vm_info, core, "Cannot allocate\n");
+       return NULL;
+    }
+
+    page_tail->page_pa = (addr_t)V3_AllocPagesExtended(1,PAGE_SIZE_4KB,-1,get_constraints(core));
+
+    if (!page_tail->page_pa) {
+       PrintError(core->vm_info, core, "Cannot allocate page\n");
+       return NULL;
+    }
+
+    PrintDebug(core->vm_info, core, "Allocating new shadow Page: %p (cur_cr3=%p)\n", 
               (void *)(addr_t)page_tail->page_pa, 
               (void *)(addr_t)cur_cr3);
 
@@ -341,14 +377,14 @@ int v3_swap_flush(struct v3_vm_info * vm) {
     struct swapbypass_vm_state * swap_state = (struct swapbypass_vm_state *)(vm->shdw_impl.impl_data);
     struct hashtable_iter * ht_iter = v3_create_htable_iter(swap_state->shdw_ptr_ht);
 
-    //    PrintDebug("Flushing Symbiotic Swap table\n");
+    //    PrintDebug(vm, VCORE_NONE, "Flushing Symbiotic Swap table\n");
 
-#ifdef CONFIG_SWAPBYPASS_TELEMETRY
+#ifdef V3_CONFIG_SWAPBYPASS_TELEMETRY
     swap_state->flushes++;
 #endif
 
     if (!ht_iter) {
-       PrintError("NULL iterator in swap flush!! Probably will crash soon...\n");
+       PrintError(vm, VCORE_NONE, "NULL iterator in swap flush!! Probably will crash soon...\n");
     }
 
     while (ht_iter->entry) {
@@ -361,7 +397,7 @@ int v3_swap_flush(struct v3_vm_info * vm) {
        
        list_for_each_entry_safe(shdw_ptr, tmp_shdw_ptr, shdw_ptr_list, node) {
            if (shdw_ptr == NULL) {
-               PrintError("Null shadow pointer in swap flush!! Probably crashing soon...\n");
+               PrintError(vm, VCORE_NONE, "Null shadow pointer in swap flush!! Probably crashing soon...\n");
            }
 
            // Trigger faults for next shadow access
@@ -393,7 +429,7 @@ static int sb_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     memset(sb_state, 0, sizeof(struct swapbypass_vm_state));
     sb_state->shdw_ptr_ht = v3_create_htable(0, swap_hash_fn, swap_eq_fn);
 
-#ifdef CONFIG_SWAPBYPASS_TELEMETRY
+#ifdef V3_CONFIG_SWAPBYPASS_TELEMETRY
     if (vm->enable_telemetry) {
        v3_add_telemetry_cb(vm, telemetry_cb, NULL);
     }
@@ -401,7 +437,7 @@ static int sb_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
 
     impl_state->impl_data = sb_state;
 
-    PrintDebug("Initialized SwapBypass\n");
+    PrintDebug(vm, VCORE_NONE, "Initialized SwapBypass\n");
 
 
     return 0;
@@ -415,10 +451,16 @@ static int sb_local_init(struct guest_info * core) {
     struct v3_shdw_pg_state * state = &(core->shdw_pg_state);
     struct swapbypass_local_state * swapbypass_state = NULL;
 
-    V3_Print("SWAPBYPASS local initialization\n");
+    V3_Print(core->vm_info, core, "SWAPBYPASS local initialization\n");
 
     swapbypass_state = (struct swapbypass_local_state *)V3_Malloc(sizeof(struct swapbypass_local_state));
 
+    if (!swapbypass_state) {
+       PrintError(core->vm_info, core, "Cannot allocate\n");
+       return -1;
+    }
+
+
     INIT_LIST_HEAD(&(swapbypass_state->page_list));
 
     state->local_impl_data = swapbypass_state;
@@ -439,7 +481,7 @@ static int sb_activate_shdw_pt(struct guest_info * core) {
        case LONG_16_COMPAT:
            return activate_shadow_pt_64(core);
        default:
-           PrintError("Invalid CPU mode: %s\n", v3_cpu_mode_to_str(v3_get_vm_cpu_mode(core)));
+           PrintError(core->vm_info, core, "Invalid CPU mode: %s\n", v3_cpu_mode_to_str(v3_get_vm_cpu_mode(core)));
            return -1;
     }
 
@@ -465,7 +507,7 @@ static int sb_handle_pf(struct guest_info * core, addr_t fault_addr, pf_error_t
                return handle_shadow_pagefault_64(core, fault_addr, error_code);
                break;
            default:
-               PrintError("Unhandled CPU Mode: %s\n", v3_cpu_mode_to_str(v3_get_vm_cpu_mode(core)));
+               PrintError(core->vm_info, core, "Unhandled CPU Mode: %s\n", v3_cpu_mode_to_str(v3_get_vm_cpu_mode(core)));
                return -1;
        }
 }
@@ -483,7 +525,7 @@ static int sb_handle_invlpg(struct guest_info * core, addr_t vaddr) {
        case LONG_16_COMPAT:
            return handle_shadow_invlpg_64(core, vaddr);
        default:
-           PrintError("Invalid CPU mode: %s\n", v3_cpu_mode_to_str(v3_get_vm_cpu_mode(core)));
+           PrintError(core->vm_info, core, "Invalid CPU mode: %s\n", v3_cpu_mode_to_str(v3_get_vm_cpu_mode(core)));
            return -1;
     }
 }