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.


More extensive error checking in checkpoint/restore + other cleanup
[palacios.git] / palacios / src / palacios / vmx.c
index 16f3e3b..649181b 100644 (file)
@@ -640,9 +640,14 @@ int v3_deinit_vmx_vmcs(struct guest_info * core) {
  * JRL: This is broken
  */
 int v3_vmx_save_core(struct guest_info * core, void * ctx){
-    uint64_t vmcs_ptr = vmcs_store();
+    struct vmx_data * vmx_info = (struct vmx_data *)(core->vmm_data);
 
-    v3_chkpt_save(ctx, "vmcs_data", PAGE_SIZE, (void *)vmcs_ptr);
+    // note that the vmcs pointer is an HPA, but we need an HVA
+    if (v3_chkpt_save(ctx, "vmcs_data", PAGE_SIZE_4KB, 
+                     V3_VAddr((void*) (vmx_info->vmcs_ptr_phys))) ==-1) {
+       PrintError("Could not save vmcs data for VMX\n");
+       return -1;
+    }
 
     return 0;
 }
@@ -650,12 +655,27 @@ int v3_vmx_save_core(struct guest_info * core, void * ctx){
 int v3_vmx_load_core(struct guest_info * core, void * ctx){
     struct vmx_data * vmx_info = (struct vmx_data *)(core->vmm_data);
     struct cr0_32 * shadow_cr0;
-    char vmcs[PAGE_SIZE_4KB];
+    addr_t vmcs_page_paddr;  //HPA
+
+    vmcs_page_paddr = (addr_t) V3_AllocPages(1);
+    
+    if (!vmcs_page_paddr) { 
+       PrintError("Could not allocate space for a vmcs in VMX\n");
+       return -1;
+    }
 
-    v3_chkpt_load(ctx, "vmcs_data", PAGE_SIZE_4KB, vmcs);
+    if (v3_chkpt_load(ctx, "vmcs_data", PAGE_SIZE_4KB, 
+                     V3_VAddr((void *)vmcs_page_paddr)) == -1) { 
+       PrintError("Could not load vmcs data for VMX\n");
+       return -1;
+    }
 
     vmcs_clear(vmx_info->vmcs_ptr_phys);
-    vmcs_load((addr_t)vmcs);
+
+    // Probably need to delete the old one... 
+    V3_FreePages((void*)(vmx_info->vmcs_ptr_phys),1);
+
+    vmcs_load(vmcs_page_paddr);
 
     v3_vmx_save_vmcs(core);
 
@@ -872,7 +892,7 @@ int
 v3_vmx_config_tsc_virtualization(struct guest_info * info) {
     struct vmx_data * vmx_info = (struct vmx_data *)(info->vmm_data);
 
-    if (info->time_state.time_flags & V3_TIME_TRAP_RDTSC) {
+    if (info->time_state.flags & VM_TIME_TRAP_RDTSC) {
        if  (!vmx_info->pri_proc_ctrls.rdtsc_exit) {
            vmx_info->pri_proc_ctrls.rdtsc_exit = 1;
            check_vmcs_write(VMCS_PROC_CTRLS, vmx_info->pri_proc_ctrls.value);
@@ -886,7 +906,11 @@ v3_vmx_config_tsc_virtualization(struct guest_info * info) {
            check_vmcs_write(VMCS_PROC_CTRLS, vmx_info->pri_proc_ctrls.value);
        }
 
-        tsc_offset = v3_tsc_host_offset(&info->time_state);
+       if (info->time_state.flags & VM_TIME_TSC_PASSTHROUGH) {
+           tsc_offset = 0;
+       } else {
+            tsc_offset = v3_tsc_host_offset(&info->time_state);
+       }
         tsc_offset_high = (uint32_t)(( tsc_offset >> 32) & 0xffffffff);
         tsc_offset_low = (uint32_t)(tsc_offset & 0xffffffff);
 
@@ -913,16 +937,16 @@ int v3_vmx_enter(struct guest_info * info) {
     // Conditionally yield the CPU if the timeslice has expired
     v3_yield_cond(info);
 
-    // disable global interrupts for vm state transition
-    v3_disable_ints();
-
     // Update timer devices late after being in the VM so that as much 
     // of the time in the VM is accounted for as possible. Also do it before
     // updating IRQ entry state so that any interrupts the timers raise get 
-    // handled on the next VM entry. Must be done with interrupts disabled.
-    v3_advance_time(info);
+    // handled on the next VM entry.
+    v3_advance_time(info, NULL);
     v3_update_timers(info);
 
+    // disable global interrupts for vm state transition
+    v3_disable_ints();
+
     if (vmcs_store() != vmx_info->vmcs_ptr_phys) {
        vmcs_clear(vmx_info->vmcs_ptr_phys);
        vmcs_load(vmx_info->vmcs_ptr_phys);
@@ -947,12 +971,9 @@ int v3_vmx_enter(struct guest_info * info) {
     }
 
 
-    // Perform last-minute time bookkeeping prior to entering the VM
-    v3_time_enter_vm(info);
+    // Perform last-minute time setup prior to entering the VM
     v3_vmx_config_tsc_virtualization(info);
 
-    
-
     if (v3_update_vmcs_host_state(info)) {
        v3_enable_ints();
         PrintError("Could not write host state\n");
@@ -1019,8 +1040,7 @@ int v3_vmx_enter(struct guest_info * info) {
     }
 
     // Immediate exit from VM time bookkeeping
-    v3_time_exit_vm(info, &guest_cycles);
-
+    v3_advance_time(info, &guest_cycles);
 
     /* Update guest state */
     v3_vmx_save_vmcs(info);
@@ -1073,6 +1093,8 @@ int v3_vmx_enter(struct guest_info * info) {
 
     // Conditionally yield the CPU if the timeslice has expired
     v3_yield_cond(info);
+    v3_advance_time(info, NULL);
+    v3_update_timers(info);
 
     if (v3_handle_vmx_exit(info, &exit_info) == -1) {
        PrintError("Error in VMX exit handler (Exit reason=%x)\n", exit_info.exit_reason);