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.


Cleaned up time management stuff, being more careful on signs of various time computa...
Patrick G. Bridges [Mon, 24 Oct 2011 18:00:01 +0000 (12:00 -0600)]
linux_module/mm.c
palacios/src/devices/Kconfig
palacios/src/devices/apic.c
palacios/src/palacios/svm.c
palacios/src/palacios/vmm.c
palacios/src/palacios/vmm_time.c

index 04dcab3..e4852c3 100644 (file)
@@ -107,25 +107,25 @@ uintptr_t alloc_palacios_pgs(u64 num_pages, u32 alignment) {
     
        WARN(!pgs, "Could not allocate pages\n");
        
-       printk("%llu pages (order=%d) aquired from alloc_pages\n", 
-              num_pages, order);
+       /* printk("%llu pages (order=%d) aquired from alloc_pages\n", 
+              num_pages, order); */
 
        addr = page_to_pfn(pgs) << PAGE_SHIFT; 
     } else {
-       printk("Allocating %llu pages from bitmap allocator\n", num_pages);
+       //printk("Allocating %llu pages from bitmap allocator\n", num_pages);
        //addr = pool.base_addr;
        addr = alloc_contig_pgs(num_pages, alignment);
     }
 
 
-    printk("Returning from alloc addr=%p, vaddr=%p\n", (void *)addr, __va(addr));
+    //printk("Returning from alloc addr=%p, vaddr=%p\n", (void *)addr, __va(addr));
     return addr;
 }
 
 
 
 void free_palacios_pgs(uintptr_t pg_addr, int num_pages) {
-    printk("Freeing Memory page %p\n", (void *)pg_addr);
+    //printk("Freeing Memory page %p\n", (void *)pg_addr);
 
     if ((pg_addr >= pool.base_addr) && 
        (pg_addr < pool.base_addr + (4096 * pool.num_pages))) {
index 23a88ff..e9b2dc8 100644 (file)
@@ -6,6 +6,13 @@ config APIC
        help 
          Includes the Virtual APIC device
 
+config APIC_ENQUEUE_MISSED_TMR_IRQS
+       bool "Enqueue missed APIC timer interrpts"
+       default n
+       depends on APIC
+       help
+         Make up missed APIC periodic timer interrupts on later 
+         exits into the virtual machine
 
 config DEBUG_APIC
        bool "APIC Debugging"
@@ -14,8 +21,6 @@ config DEBUG_APIC
        help 
          Enable debugging for the APIC
 
-
-
 config IO_APIC
        bool "IOAPIC"
        depends on APIC
index f0a9d04..5aa5e13 100644 (file)
@@ -1655,12 +1655,14 @@ 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) {
+#ifdef V3_CONFIG_APIC_ENQUEUE_MISSED_TMR_IRQS
+       if (apic->missed_ints && !apic_intr_pending(core, priv_data)) {
            PrintDebug("apic %u: core %u: Injecting queued APIC timer interrupt.\n",
                       apic->lapic_id.val, core->vcpu_id);
            apic_inject_timer_intr(core, priv_data);
            apic->missed_ints--;
        }
+#endif /* CONFIG_APIC_ENQUEUE_MISSED_TMR_IRQS */ 
     } else {
        tmr_ticks -= apic->tmr_cur_cnt;
        apic->tmr_cur_cnt = 0;
@@ -1669,12 +1671,9 @@ static void apic_update_time(struct guest_info * core,
 
        if (apic->tmr_vec_tbl.tmr_mode == APIC_TMR_PERIODIC) {
            int queued_ints = tmr_ticks / apic->tmr_init_cnt;
-           if (queued_ints)
-               PrintDebug("apic %u: core %u: Deferring %u APIC timer interrupts.\n",
-                          apic->lapic_id.val, core->vcpu_id, queued_ints);
-           apic->missed_ints += queued_ints;
            tmr_ticks = tmr_ticks % apic->tmr_init_cnt;
            apic->tmr_cur_cnt = apic->tmr_init_cnt - tmr_ticks;
+           apic->missed_ints += queued_ints;
        }
     }
 
index cd741c9..f9dad0b 100644 (file)
@@ -509,6 +509,7 @@ int v3_svm_enter(struct guest_info * info) {
     vmcb_ctrl_t * guest_ctrl = GET_VMCB_CTRL_AREA((vmcb_t*)(info->vmm_data));
     vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data)); 
     addr_t exit_code = 0, exit_info1 = 0, exit_info2 = 0;
+    sint64_t tsc_offset;
 
     // Conditionally yield the CPU if the timeslice has expired
     v3_yield_cond(info);
@@ -569,7 +570,8 @@ 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);
+    tsc_offset = v3_tsc_host_offset(&info->time_state);
+    guest_ctrl->TSC_OFFSET = tsc_offset;
 
 
     //V3_Print("Calling v3_svm_launch\n");
index 341996a..8b4eed5 100644 (file)
@@ -563,11 +563,10 @@ void v3_yield_cond(struct guest_info * info) {
     cur_cycle = v3_get_host_time(&info->time_state);
 
     if (cur_cycle > (info->yield_start_cycle + info->vm_info->yield_cycle_period)) {
-
-       /*
-         PrintDebug("Conditional Yield (cur_cyle=%p, start_cycle=%p, period=%p)\n", 
-         (void *)cur_cycle, (void *)info->yield_start_cycle, (void *)info->yield_cycle_period);
-       */
+       //PrintDebug("Conditional Yield (cur_cyle=%p, start_cycle=%p, period=%p)\n", 
+       //           (void *)cur_cycle, (void *)info->yield_start_cycle, 
+       //         (void *)info->yield_cycle_period);
+       
        V3_Yield();
        info->yield_start_cycle = v3_get_host_time(&info->time_state);
     }
index 27bb2fc..2295b3f 100644 (file)
@@ -99,7 +99,7 @@ int v3_start_time(struct guest_info * info) {
 int v3_offset_time( struct guest_info * info, sint64_t offset )
 {
     struct vm_time * time_state = &(info->time_state);
-//    PrintDebug("Adding additional offset of %lld to guest time.\n", offset);
+    PrintDebug("Adding additional offset of %lld to guest time.\n", offset);
     time_state->guest_host_offset += offset;
     return 0;
 }
@@ -152,7 +152,7 @@ static int yield_host_time(struct guest_info * info) {
 
     /* We do *not* assume the guest timer was paused in the VM. If it was
      * this offseting is 0. If it wasn't, we need this. */
-    v3_offset_time(info, (sint64_t)old_guest_time - (sint64_t)guest_time);
+    v3_offset_time(info, (sint64_t)(old_guest_time - guest_time));
 
     return 0;
 }
@@ -175,12 +175,12 @@ static int skew_guest_time(struct guest_info * info) {
        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 = ((sint64_t)guest_time - (sint64_t)time_state->enter_time) / 10;
+           max_skew = (sint64_t)(guest_time - time_state->enter_time) / 10.0;
        } else {
            max_skew = 0;
        }
 
-       desired_skew = (sint64_t)target_guest_time - (sint64_t)guest_time;
+       desired_skew = (sint64_t)(target_guest_time - guest_time);
        skew = desired_skew > max_skew ? max_skew : desired_skew;
        PrintDebug("Guest %lld cycles behind where it should be.\n",
                   desired_skew);
@@ -226,13 +226,21 @@ int
 v3_time_enter_vm( struct guest_info * info )
 {
     struct vm_time * time_state = &(info->time_state);
-    uint64_t guest_time, host_time;
+    uint64_t host_time;
 
     host_time = v3_get_host_time(time_state);
-    guest_time = v3_get_guest_time(time_state);
     time_state->enter_time = host_time;
 #ifdef V3_CONFIG_TIME_DILATION
-    time_state->guest_host_offset = (sint64_t)guest_time - (sint64_t)host_time;
+    { 
+        uint64_t guest_time;
+       sint64_t offset;
+        guest_time = v3_compute_guest_time(time_state, host_time);
+       // XXX we probably want to use an inline function to do these
+        // time differences to deal with sign and overflow carefully
+       offset = (sint64_t)guest_time - (sint64_t)host_time;
+       PrintDebug("v3_time_enter_vm: guest time offset %lld from host time.\n", offset);
+        time_state->guest_host_offset = offset;
+    }
 #else
     time_state->guest_host_offset = 0;
 #endif
@@ -269,11 +277,11 @@ int v3_remove_timer(struct guest_info * info, struct v3_timer * timer) {
 void v3_update_timers(struct guest_info * info) {
     struct vm_time *time_state = &info->time_state;
     struct v3_timer * tmp_timer;
-    uint64_t old_time = info->time_state.last_update;
     sint64_t cycles;
+    uint64_t old_time = info->time_state.last_update;
 
     time_state->last_update = v3_get_guest_time(time_state);
-    cycles = time_state->last_update - old_time;
+    cycles = (sint64_t)(time_state->last_update - old_time);
     V3_ASSERT(cycles >= 0);
 
     //    V3_Print("Updating timers with %lld elapsed cycles.\n", cycles);