From: Patrick G. Bridges Date: Mon, 24 Oct 2011 18:00:01 +0000 (-0600) Subject: Cleaned up time management stuff, being more careful on signs of various time computa... X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=commitdiff_plain;h=8a3dbb70c29175bad79764a0b2f3961b98138bb2 Cleaned up time management stuff, being more careful on signs of various time computations. A more thorough review and thinking of times and differences between them, particularly for future time dilation extensions, is needed. Also removed a few unnecessary prints. --- diff --git a/linux_module/mm.c b/linux_module/mm.c index 04dcab3..e4852c3 100644 --- a/linux_module/mm.c +++ b/linux_module/mm.c @@ -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))) { diff --git a/palacios/src/devices/Kconfig b/palacios/src/devices/Kconfig index 23a88ff..e9b2dc8 100644 --- a/palacios/src/devices/Kconfig +++ b/palacios/src/devices/Kconfig @@ -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 diff --git a/palacios/src/devices/apic.c b/palacios/src/devices/apic.c index f0a9d04..5aa5e13 100644 --- a/palacios/src/devices/apic.c +++ b/palacios/src/devices/apic.c @@ -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; } } diff --git a/palacios/src/palacios/svm.c b/palacios/src/palacios/svm.c index cd741c9..f9dad0b 100644 --- a/palacios/src/palacios/svm.c +++ b/palacios/src/palacios/svm.c @@ -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"); diff --git a/palacios/src/palacios/vmm.c b/palacios/src/palacios/vmm.c index 341996a..8b4eed5 100644 --- a/palacios/src/palacios/vmm.c +++ b/palacios/src/palacios/vmm.c @@ -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); } diff --git a/palacios/src/palacios/vmm_time.c b/palacios/src/palacios/vmm_time.c index 27bb2fc..2295b3f 100644 --- a/palacios/src/palacios/vmm_time.c +++ b/palacios/src/palacios/vmm_time.c @@ -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);