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.


Changes to try to make time handling better. Also disabled TSC offsetting for now...
Patrick G. Bridges [Thu, 22 Sep 2011 18:50:53 +0000 (12:50 -0600)]
palacios/src/devices/apic.c
palacios/src/palacios/svm.c
palacios/src/palacios/vmm_time.c
palacios/src/palacios/vmx.c

index 6b21f81..d83f0bd 100644 (file)
@@ -220,7 +220,7 @@ struct apic_state {
 
     uint32_t tmr_cur_cnt;
     uint32_t tmr_init_cnt;
-
+    uint32_t missed_ints;
 
     struct local_vec_tbl_reg ext_intr_vec_tbl[4];
 
@@ -295,6 +295,7 @@ static void init_apic_state(struct apic_state * apic, uint32_t id) {
     apic->rem_rd_data = 0x00000000;
     apic->tmr_init_cnt = 0x00000000;
     apic->tmr_cur_cnt = 0x00000000;
+    apic->missed_ints = 0;
 
     apic->lapic_id.val = id;
     
@@ -1562,10 +1563,33 @@ static int apic_begin_irq(struct guest_info * core, void * private_data, int irq
 }
 
 
+/* Timer Functions */
+
+static void apic_inject_timer_intr(struct guest_info *core,
+                                  void * priv_data) {
+    struct apic_dev_state * apic_dev = (struct apic_dev_state *)(priv_data);
+    struct apic_state * apic = &(apic_dev->apics[core->vcpu_id]); 
+    // raise irq
+    PrintDebug("apic %u: core %u: Raising APIC Timer interrupt (periodic=%d) (icnt=%d) (div=%d)\n",
+              apic->lapic_id.val, core->vcpu_id,
+              apic->tmr_vec_tbl.tmr_mode, apic->tmr_init_cnt, shift_num);
+
+    if (apic_intr_pending(core, priv_data)) {
+        PrintDebug("apic %u: core %u: Overriding pending IRQ %d\n", 
+                  apic->lapic_id.val, core->vcpu_id, 
+                  apic_get_intr_number(core, priv_data));
+    }
 
+    if (activate_internal_irq(apic, APIC_TMR_INT) == -1) {
+       PrintError("apic %u: core %u: Could not raise Timer interrupt\n",
+                  apic->lapic_id.val, core->vcpu_id);
+    }
+
+    return;
+}
+       
 
 
-/* Timer Functions */
 
 static void apic_update_time(struct guest_info * core, 
                             uint64_t cpu_cycles, uint64_t cpu_freq, 
@@ -1631,40 +1655,18 @@ static void apic_update_time(struct guest_info * core,
 
     if (tmr_ticks < apic->tmr_cur_cnt) {
        apic->tmr_cur_cnt -= tmr_ticks;
+       if (apic->missed_ints) {
+           apic_inject_timer_intr(core, priv_data);
+           apic->missed_ints--;
+       }
     } else {
        tmr_ticks -= apic->tmr_cur_cnt;
        apic->tmr_cur_cnt = 0;
 
-       // raise irq
-       PrintDebug("apic %u: core %u: Raising APIC Timer interrupt (periodic=%d) (icnt=%d) (div=%d)\n",
-                  apic->lapic_id.val, core->vcpu_id,
-                  apic->tmr_vec_tbl.tmr_mode, apic->tmr_init_cnt, shift_num);
-
-       if (apic_intr_pending(core, priv_data)) {
-           PrintDebug("apic %u: core %u: Overriding pending IRQ %d\n", 
-                      apic->lapic_id.val, core->vcpu_id, 
-                      apic_get_intr_number(core, priv_data));
-       }
+       apic_inject_timer_intr(core, priv_data);
 
-       if (activate_internal_irq(apic, APIC_TMR_INT) == -1) {
-           PrintError("apic %u: core %u: Could not raise Timer interrupt\n",
-                      apic->lapic_id.val, core->vcpu_id);
-       }
-    
        if (apic->tmr_vec_tbl.tmr_mode == APIC_TMR_PERIODIC) {
-           static unsigned int nexits = 0;
-           static unsigned int missed_ints = 0;
-
-           nexits++;
-           missed_ints += tmr_ticks / apic->tmr_init_cnt;
-
-           if ((missed_ints > 0) && (nexits >= 5000)) {
-               V3_Print("apic %u: core %u: missed %u timer interrupts total in last %u exits.\n",
-                        apic->lapic_id.val, core->vcpu_id, missed_ints, nexits); 
-               missed_ints = 0;
-               nexits = 0;
-           }
-
+           apic->missed_ints += tmr_ticks / apic->tmr_init_cnt;
            tmr_ticks = tmr_ticks % apic->tmr_init_cnt;
            apic->tmr_cur_cnt = apic->tmr_init_cnt - tmr_ticks;
        }
@@ -1673,7 +1675,6 @@ static void apic_update_time(struct guest_info * core,
     return;
 }
 
-
 static struct intr_ctrl_ops intr_ops = {
     .intr_pending = apic_intr_pending,
     .get_intr_number = apic_get_intr_number,
index 115e19c..5319f90 100644 (file)
@@ -610,7 +610,7 @@ int v3_svm_enter(struct guest_info * info) {
 #endif
 
     v3_time_enter_vm(info);
-    guest_ctrl->TSC_OFFSET = v3_tsc_host_offset(&info->time_state);
+    // guest_ctrl->TSC_OFFSET = v3_tsc_host_offset(&info->time_state);
 
 
     //V3_Print("Calling v3_svm_launch\n");
index 781bae7..fa8f5cd 100644 (file)
@@ -172,21 +172,21 @@ static int skew_guest_time(struct guest_info * info) {
     guest_time = v3_get_guest_time(time_state);
 
     if (guest_time < target_guest_time) {
-       uint64_t max_skew, desired_skew, skew;
+       sint64_t max_skew, desired_skew, skew;
 
        if (time_state->enter_time) {
            /* Limit forward skew to 10% of the amount the guest has
             * run since we last could skew time */
-           max_skew = (guest_time - time_state->enter_time) / 10;
+           max_skew = ((sint64_t)guest_time - (sint64_t)time_state->enter_time) / 10;
        } else {
            max_skew = 0;
        }
 
-       desired_skew = target_guest_time - guest_time;
+       desired_skew = (sint64_t)target_guest_time - (sint64_t)guest_time;
        skew = desired_skew > max_skew ? max_skew : desired_skew;
-       PrintDebug("Guest %llu cycles behind where it should be.\n",
+       PrintDebug("Guest %lld cycles behind where it should be.\n",
                   desired_skew);
-       PrintDebug("Limit on forward skew is %llu. Skewing forward %llu.\n",
+       PrintDebug("Limit on forward skew is %lld. Skewing forward %lld.\n",
                   max_skew, skew); 
        
        v3_offset_time(info, skew);
@@ -228,10 +228,10 @@ v3_time_enter_vm( struct guest_info * info )
     struct vm_time * time_state = &(info->time_state);
     uint64_t guest_time, host_time;
 
-    guest_time = v3_get_guest_time(time_state);
     host_time = v3_get_host_time(time_state);
+    guest_time = v3_get_guest_time(time_state);
     time_state->enter_time = host_time;
-    time_state->guest_host_offset = guest_time - host_time;
+    time_state->guest_host_offset = (sint64_t)guest_time - (sint64_t)host_time;
 
     return 0;
 }
index e733eb5..5a48935 100644 (file)
@@ -838,11 +838,10 @@ int v3_vmx_enter(struct guest_info * info) {
     // Perform last-minute time bookkeeping prior to entering the VM
     v3_time_enter_vm(info);
 
-    tsc_offset_high = (uint32_t)((v3_tsc_host_offset(&info->time_state) >> 32) & 0xffffffff);
-    tsc_offset_low = (uint32_t)(v3_tsc_host_offset(&info->time_state) & 0xffffffff);
-    check_vmcs_write(VMCS_TSC_OFFSET_HIGH, tsc_offset_high);
-    check_vmcs_write(VMCS_TSC_OFFSET, tsc_offset_low);
-
+    // tsc_offset_high = (uint32_t)((v3_tsc_host_offset(&info->time_state) >> 32) & 0xffffffff);
+    // tsc_offset_low = (uint32_t)(v3_tsc_host_offset(&info->time_state) & 0xffffffff);
+    // check_vmcs_write(VMCS_TSC_OFFSET_HIGH, tsc_offset_high);
+    // check_vmcs_write(VMCS_TSC_OFFSET, tsc_offset_low);
 
     if (v3_update_vmcs_host_state(info)) {
        v3_enable_ints();