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.


symbiotic fixups
Jack Lange [Fri, 30 Oct 2009 23:22:49 +0000 (18:22 -0500)]
12 files changed:
palacios/include/palacios/vmm_sym_swap.h
palacios/src/devices/ide.c
palacios/src/devices/keyboard.c
palacios/src/devices/sym_swap.c
palacios/src/palacios/Makefile
palacios/src/palacios/svm.c
palacios/src/palacios/svm_handler.c
palacios/src/palacios/vm_guest.c
palacios/src/palacios/vmm.c
palacios/src/palacios/vmm_shadow_paging_32.h
palacios/src/palacios/vmm_sym_iface.c
palacios/src/palacios/vmm_sym_swap.c

index e613051..a8646ef 100644 (file)
@@ -49,6 +49,7 @@ struct v3_sym_swap_state {
     uint32_t read_faults;
     uint32_t write_faults;
     uint32_t flushes;
+    uint32_t mapped_pages;
 #endif
 
     // shadow pointers
@@ -70,10 +71,8 @@ int v3_register_swap_disk(struct guest_info * info, int dev_index,
 
 int v3_swap_in_notify(struct guest_info * info, int pg_index, int dev_index);
 
-int v3_sym_get_addr_info(struct guest_info * info, addr_t vadd, 
-                        int (*cb)(struct guest_info * info));
-
 
+int v3_get_vaddr_perms(struct guest_info * info, addr_t vaddr, pte32_t * guest_pte, pf_error_t * page_perms);
 addr_t v3_get_swapped_pg_addr(struct guest_info * info, pte32_t * shadow_pte, pte32_t * guest_pte);
 
 int v3_swap_flush(struct guest_info * info);
index b1c13a6..e8fbdc5 100644 (file)
@@ -280,7 +280,7 @@ static inline int is_lba_enabled(struct ide_channel * channel) {
 /* Drive Commands */
 static void ide_raise_irq(struct vm_device * dev, struct ide_channel * channel) {
     if (channel->ctrl_reg.irq_disable == 0) {
-        PrintError("Raising IDE Interrupt %d\n", channel->irq);
+       //        PrintError("Raising IDE Interrupt %d\n", channel->irq);
         channel->dma_status.int_gen = 1;
         v3_raise_irq(dev->vm, channel->irq);
     }
index 7fce87c..c05b00e 100644 (file)
@@ -327,7 +327,9 @@ static int key_event_handler(struct guest_info * info,
     if (evt->scan_code == 0x44) { // F10 debug dump
        v3_print_guest_state(info);
        //      PrintGuestPageTables(info, info->shdw_pg_state.guest_cr3);
-    } else if (evt->scan_code == 0x43) { // F9 Sym test
+    } 
+#ifdef CONFIG_SYMBIOTIC
+else if (evt->scan_code == 0x43) { // F9 Sym test
        PrintDebug("Testing sym call\n");
        sym_arg_t a0 = 0x1111;
        sym_arg_t a1 = 0x2222;
@@ -345,7 +347,7 @@ static int key_event_handler(struct guest_info * info,
        sym_arg_t addr = 0;
        v3_sym_call1(info, SYMCALL_MEM_LOOKUP, &addr);
     }
-
+#endif
 
 
     addr_t irq_state = v3_lock_irqsave(state->kb_lock);
index 4b7270d..d6740c4 100644 (file)
@@ -116,12 +116,12 @@ static inline void * get_swap_entry(uint32_t pg_index, void * private_data) {
     struct vm_device * dev = (struct vm_device *)private_data;
     struct swap_state * swap = (struct swap_state *)(dev->private_data);
     void * pg_addr = NULL;
-    int ret = 0;
+    // int ret = 0;
 
-    if ((ret = get_index_usage(swap, pg_index))) {
-       // CAREFUL: The index might be offset by 1, because the first 4K is the header
-       pg_addr = (void *)(swap->swap_space + (pg_index * 4096));
-    }
+    //    if ((ret = get_index_usage(swap, pg_index))) {
+    // CAREFUL: The index might be offset by 1, because the first 4K is the header
+    pg_addr = (void *)(swap->swap_space + (pg_index * 4096));
+    //    }
 
     return pg_addr;
 }
index d01dd6a..f5621bd 100644 (file)
@@ -31,7 +31,6 @@ obj-y := \
        vmm_xed.o \
        vmm_binaries.o \
        vmm_cpuid.o \
-       vmm_sym_iface.o \
 
 
 obj-$(CONFIG_SVM) +=    svm.o \
@@ -58,4 +57,6 @@ obj-$(CONFIG_INSTRUMENT_VMM) += vmm_instrument.o
 obj-$(CONFIG_TELEMETRY) += vmm_telemetry.o 
 obj-$(CONFIG_SOCKET) +=  vmm_socket.o
 
-obj-$(CONFIG_SYMBIOTIC_SWAP) += vmm_sym_swap.o
+obj-$(CONFIG_SYMBIOTIC) += vmm_sym_iface.o
+
+obj-$(CONFIG_SYMBIOTIC_SWAP) += vmm_sym_swap.o 
index 8f87be9..a72f596 100644 (file)
@@ -338,18 +338,16 @@ static int update_irq_state(struct guest_info * info) {
        
        guest_ctrl->EVENTINJ.valid = 1;
 
-       PrintDebug("<%d> Injecting Exception %d (CR2=%p) (EIP=%p)\n", 
-                  (int)info->num_exits, 
-                  guest_ctrl->EVENTINJ.vector, 
-                  (void *)(addr_t)info->ctrl_regs.cr2,
-                  (void *)(addr_t)info->rip);
 
 
 #ifdef CONFIG_DEBUG_INTERRUPTS
-       PrintDebug("Injecting Exception %d (EIP=%p)\n", 
+       PrintDebug("<%d> Injecting Exception %d (CR2=%p) (EIP=%p)\n", 
+                  (int)info->num_exits, 
                   guest_ctrl->EVENTINJ.vector, 
+                  (void *)(addr_t)info->ctrl_regs.cr2,
                   (void *)(addr_t)info->rip);
 #endif
+
        v3_injecting_excp(info, excp);
 
 
@@ -408,7 +406,7 @@ static int update_irq_state(struct guest_info * info) {
  * CAUTION and DANGER!!! 
  * 
  * The VMCB CANNOT(!!) be accessed outside of the clgi/stgi calls inside this function
- * When exectuing a symbiotic call the VMCB WILL be overwritten, so any dependencies 
+ * When exectuing a symbiotic call, the VMCB WILL be overwritten, so any dependencies 
  * on its contents will cause things to break. The contents at the time of the exit WILL 
  * change before the exit handler is executed.
  */
index 951cc8f..9c20ae6 100644 (file)
@@ -227,7 +227,7 @@ int v3_handle_svm_exit(struct guest_info * info, addr_t exit_code, addr_t exit_i
            }
            break;
        case VMEXIT_PAUSE:
-           PrintDebug("Guest paused\n");
+           //      PrintDebug("Guest paused\n");
            if (v3_handle_svm_pause(info) == -1) { 
                return -1;
            }
index 04d887d..44673cb 100644 (file)
@@ -291,16 +291,23 @@ void v3_print_stack(struct guest_info * info) {
 
 
     linear_addr = get_addr_linear(info, info->vm_regs.rsp, &(info->segments.ss));
-    
+    V3_Print("Stack  at %p:\n", (void *)linear_addr);
+   
     if (info->mem_mode == PHYSICAL_MEM) {
-       guest_pa_to_host_va(info, linear_addr, &host_addr);
+       if (guest_pa_to_host_va(info, linear_addr, &host_addr) == -1) {
+           PrintError("Could not translate Stack address\n");
+           return;
+       }
     } else if (info->mem_mode == VIRTUAL_MEM) {
-       guest_va_to_host_va(info, linear_addr, &host_addr);
+       if (guest_va_to_host_va(info, linear_addr, &host_addr) == -1) {
+           PrintError("Could not translate Virtual Stack address\n");
+           return;
+       }
     }
     
     V3_Print("Host Address of rsp = 0x%p\n", (void *)host_addr);
-    V3_Print("Stack  at %p:\n", (void *)host_addr);
-
     // We start i at one because the current stack pointer points to an unused stack element
     for (i = 0; i <= 24; i++) {
        if (cpu_mode == LONG) {
index 536f7da..1571c48 100644 (file)
@@ -204,19 +204,17 @@ int v3_vm_enter(struct guest_info * info) {
 #ifdef CONFIG_SVM
        case V3_SVM_CPU:
        case V3_SVM_REV3_CPU:
-           v3_svm_enter(info);
+           return v3_svm_enter(info);
            break;
 #endif
 #if CONFIG_VMX && 0
        case V3_VMX_CPU:
        case V3_VMX_EPT_CPU:
-           v3_vmx_enter(info);
+           return v3_vmx_enter(info);
            break;
 #endif
        default:
            PrintError("Attemping to enter a guest on an invalid CPU\n");
            return -1;
     }
-
-    return 0;
 }
index 9febd7c..256f0de 100644 (file)
@@ -88,7 +88,7 @@ static inline int handle_shadow_pagefault_32(struct guest_info * info, addr_t fa
        PrintDebug("Injecting PDE pf to guest: (guest access error=%d) (shdw access error=%d)  (pf error code=%d)\n", 
                   *(uint_t *)&guest_pde_access, *(uint_t *)&shadow_pde_access, *(uint_t *)&error_code);
        if (inject_guest_pf(info, fault_addr, error_code) == -1) {
-           PrintError("Could not inject guest page fault\n");
+           PrintError("Could not inject guest page fault for vaddr %p\n", (void *)fault_addr);
            return -1;
        }
        return 0;
@@ -104,7 +104,7 @@ static inline int handle_shadow_pagefault_32(struct guest_info * info, addr_t fa
                   shadow_pde_access, guest_pde_access);
        
        if (inject_guest_pf(info, fault_addr, error_code) == -1) {
-           PrintError("Could not inject guest page fault\n");
+           PrintError("Could not inject guest page fault for vaddr %p\n", (void *)fault_addr);
            return -1;
        }
        return 0;
@@ -118,7 +118,7 @@ static inline int handle_shadow_pagefault_32(struct guest_info * info, addr_t fa
               (shadow_pde_access != PT_ACCESS_OK)) {
        // inject page fault in guest
        if (inject_guest_pf(info, fault_addr, error_code) == -1) {
-           PrintError("Could not inject guest page fault\n");
+           PrintError("Could not inject guest page fault for vaddr %p\n", (void *)fault_addr);
            return -1;
        }
        PrintDebug("Unknown Error occurred (shadow_pde_access=%d)\n", shadow_pde_access);
@@ -196,15 +196,6 @@ static inline int handle_shadow_pagefault_32(struct guest_info * info, addr_t fa
     return 0;
 }
 
-#ifdef CONFIG_SYMBIOTIC_SWAP
-
-static int sym_swap_callback(struct guest_info * info) {
-
-    return 0;
-}
-
-
-#endif
 
 static int handle_pte_shadow_pagefault_32(struct guest_info * info, addr_t fault_addr, pf_error_t error_code,
                                          pte32_t * shadow_pt, pte32_t * guest_pt) {
@@ -239,6 +230,7 @@ static int handle_pte_shadow_pagefault_32(struct guest_info * info, addr_t fault
        
 #ifdef CONFIG_SYMBIOTIC_SWAP
        if (is_swapped_pte32(guest_pte)) {
+           pf_error_t swap_perms;
 
 #ifdef CONFIG_SYMBIOTIC_SWAP_TELEMETRY
            if (error_code.write == 0) {
@@ -248,53 +240,55 @@ static int handle_pte_shadow_pagefault_32(struct guest_info * info, addr_t fault
            }
 #endif
 
-           // This will trigger a callback...
-           v3_sym_get_addr_info(info, fault_addr, sym_swap_callback);
+           if (v3_get_vaddr_perms(info, fault_addr, guest_pte, &swap_perms) == -1) {
+               PrintError("Error getting Swapped page permissions\n");
+               return -1;
+           }
+
 
-           return 0;
+           // swap_perms.write == 1 || error_code.write == 0
+           // swap_perms.user == 0 || error_code.user == 1
 
-           /*
-             if (error_code.write == 0) {
-             V3_Print("Page fault on swapped out page (vaddr=%p) (pte=%x) (error_code=%x)\n", 
-             (void *)fault_addr, *(uint32_t *)guest_pte, *(uint32_t *)&error_code);
-               
-             addr_t swp_pg_addr = v3_get_swapped_pg_addr(info, shadow_pte, guest_pte);
-               
-             if (swp_pg_addr == 0) {
-             if (inject_guest_pf(info, fault_addr, error_code) == -1) {
-             PrintError("Could not inject guest page fault\n");
-             return -1;
-             }
-             } else {
+           // This checks for permissions violations that require a guest PF injection
+           if ( (swap_perms.present == 1) && 
+                ( (swap_perms.write == 1) || 
+                  (error_code.write == 0) ) &&
+                ( (swap_perms.user == 1) || 
+                  (error_code.user == 0) ) ) {
+               addr_t swp_pg_addr = 0;
 
+               V3_Print("Page fault on swapped out page (vaddr=%p) (pte=%x) (error_code=%x)\n", 
+                        (void *)fault_addr, *(uint32_t *)guest_pte, *(uint32_t *)&error_code);
+
+               swp_pg_addr = v3_get_swapped_pg_addr(info, shadow_pte, guest_pte);
+
+               V3_Print("Swapped page address=%p\n", (void *)swp_pg_addr);
+
+               if (swp_pg_addr != 0) {
+                   shadow_pte->writable = swap_perms.write;
+                   shadow_pte->user_page = swap_perms.user;
                    
-             shadow_pte->accessed = 1;
-             shadow_pte->writable = 0;
-                   
-             if ((fault_addr & 0xc0000000) == 0xc0000000) {
-             shadow_pte->user_page = 0;
-             } else {
-             shadow_pte->user_page = 1;
-             }
+                   shadow_pte->write_through = 0;
+                   shadow_pte->cache_disable = 0;
+                   shadow_pte->global_page = 0;
                    
-             shadow_pte->write_through = 0;
-             shadow_pte->cache_disable = 0;
-             shadow_pte->global_page = 0;
+                   shadow_pte->present = 1;
                    
-             shadow_pte->present = 1;
+                   shadow_pte->page_base_addr = swp_pg_addr;
                    
-             shadow_pte->page_base_addr = swp_pg_addr;
-             }
-               
-             return 0;
-             }
-           */
+#ifdef CONFIG_SYMBIOTIC_SWAP_TELEMETRY
+                   info->swap_state.mapped_pages++;
+#endif
+
+                   return 0;
+               }
+           }
        }
 #endif
        
 
        if (inject_guest_pf(info, fault_addr, error_code) == -1) {
-           PrintError("Could not inject guest page fault\n");
+           PrintError("Could not inject guest page fault for vaddr %p\n", (void *)fault_addr);
            return -1;
        }       
 
@@ -377,7 +371,7 @@ static int handle_pte_shadow_pagefault_32(struct guest_info * info, addr_t fault
     } else {
        // Inject page fault into the guest     
        if (inject_guest_pf(info, fault_addr, error_code) == -1) {
-           PrintError("Could not inject guest page fault\n");
+           PrintError("Could not inject guest page fault for vaddr %p\n", (void *)fault_addr);
            return -1;
        }
 
index 43d62c5..2a3caf0 100644 (file)
@@ -237,9 +237,8 @@ static int sym_call_err(struct guest_info * info, uint_t hcall_id, void * privat
 static int sym_call_ret(struct guest_info * info, uint_t hcall_id, void * private_data) {
     struct v3_sym_state * state = (struct v3_sym_state *)&(info->sym_state);
 
-    PrintError("Return from sym call\n");
-    v3_print_guest_state(info);
-    v3_print_mem_map(info);
+    //    PrintError("Return from sym call\n");
+    //   v3_print_guest_state(info);
 
     state->sym_call_returned = 1;
 
@@ -269,8 +268,8 @@ int v3_sym_call(struct guest_info * info,
     struct v3_segment sym_ss;
     uint64_t trash_args[5] = { [0 ... 4] = 0 };
 
-    PrintDebug("Making Sym call\n");
-    v3_print_guest_state(info);
+    //   PrintDebug("Making Sym call\n");
+    //    v3_print_guest_state(info);
 
     if ((state->sym_page->sym_call_enabled == 0) ||
        (state->sym_call_active == 1)) {
@@ -318,8 +317,8 @@ int v3_sym_call(struct guest_info * info,
     state->sym_call_active = 1;
     state->sym_call_returned = 0;
 
-    PrintDebug("Sym state\n");
-    v3_print_guest_state(info);
+    //    PrintDebug("Sym state\n");
+    //  v3_print_guest_state(info);
 
     // Do the sym call entry
     if (execute_symcall(info) == -1) {
@@ -348,8 +347,8 @@ int v3_sym_call(struct guest_info * info,
 
 
 
-    PrintDebug("restoring guest state\n");
-    v3_print_guest_state(info);
+    //    PrintDebug("restoring guest state\n");
+    //    v3_print_guest_state(info);
 
     return 0;
 }
index 24f2869..a4117b8 100644 (file)
@@ -76,6 +76,7 @@ static void telemetry_cb(struct guest_info * info, void * private_data, char * h
     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);
 }
 #endif
@@ -148,7 +149,7 @@ int v3_swap_flush(struct guest_info * info) {
     struct v3_sym_swap_state * swap_state = &(info->swap_state);
     struct hashtable_iter * ht_iter = v3_create_htable_iter(swap_state->shdw_ptr_ht);
 
-    PrintDebug("Flushing Symbiotic Swap table\n");
+    //    PrintDebug("Flushing Symbiotic Swap table\n");
 
 #ifdef CONFIG_SYMBIOTIC_SWAP_TELEMETRY
     swap_state->flushes++;
@@ -177,11 +178,18 @@ int v3_swap_flush(struct guest_info * info) {
     return 0;
 }
 
+int v3_get_vaddr_perms(struct guest_info * info, addr_t vaddr, pte32_t * guest_pte, pf_error_t * page_perms) {
+    uint32_t pte_val = *(uint32_t *)guest_pte;
 
-int v3_sym_get_addr_info(struct guest_info * info, addr_t vaddr,
-                           int (*cb)(struct guest_info * info)) {
-    return 0;
+    // 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");
+       return -1;
+    }
+
+    V3_Print("page perms = %x\n", *(uint32_t *)page_perms);
 
+    return 0;
 }
 
 
@@ -198,6 +206,8 @@ addr_t v3_get_swapped_pg_addr(struct guest_info * info, pte32_t * shadow_pte, pt
        return 0;
     }
 
+
+
     swp_page_ptr = swp_dev->ops->get_swap_entry(get_pg_index(guest_pte), swp_dev->private_data);
 
     if (swp_page_ptr == NULL) {