[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [HVM] Sync per vcpu LAPIC timer with its TSC:
# HG changeset patch # User kfraser@xxxxxxxxxxxxxxxxxxxxx # Date 1166611293 0 # Node ID 516e4faac066437af4b41014da831d2ad8ae0493 # Parent 2a1edeedf28d9c72492255fba638fbca61da7ee3 [HVM] Sync per vcpu LAPIC timer with its TSC: - benefits LAPIC calibration - makes scheduling policy based on LAPIC more precise - makes LAPIC timer code becomes simpler and cleaner after using periodic time layer Signed-off-by: Xiaowei Yang <xiaowei.yang@xxxxxxxxx> --- xen/arch/x86/hvm/hvm.c | 3 xen/arch/x86/hvm/io.c | 15 -- xen/arch/x86/hvm/irq.c | 6 - xen/arch/x86/hvm/svm/intr.c | 2 xen/arch/x86/hvm/vlapic.c | 199 +++++++++------------------------ xen/arch/x86/hvm/vmx/intr.c | 4 xen/arch/x86/hvm/vpt.c | 231 +++++++++++++++++++++++++++++++++++++++ xen/include/asm-x86/hvm/vlapic.h | 24 ++-- xen/include/asm-x86/hvm/vpt.h | 8 - 9 files changed, 314 insertions(+), 178 deletions(-) diff -r 2a1edeedf28d -r 516e4faac066 xen/arch/x86/hvm/hvm.c --- a/xen/arch/x86/hvm/hvm.c Wed Dec 20 10:37:23 2006 +0000 +++ b/xen/arch/x86/hvm/hvm.c Wed Dec 20 10:41:33 2006 +0000 @@ -87,7 +87,8 @@ void hvm_migrate_timers(struct vcpu *v) pit_migrate_timers(v); rtc_migrate_timers(v); pmtimer_migrate_timers(v); - migrate_timer(&vcpu_vlapic(v)->vlapic_timer, v->processor); + if ( vcpu_vlapic(v)->pt.enabled ) + migrate_timer(&vcpu_vlapic(v)->pt.timer, v->processor); } void hvm_do_resume(struct vcpu *v) diff -r 2a1edeedf28d -r 516e4faac066 xen/arch/x86/hvm/io.c --- a/xen/arch/x86/hvm/io.c Wed Dec 20 10:37:23 2006 +0000 +++ b/xen/arch/x86/hvm/io.c Wed Dec 20 10:41:33 2006 +0000 @@ -689,21 +689,6 @@ static void hvm_mmio_assist(struct cpu_u } } -void hvm_interrupt_post(struct vcpu *v, int vector, int type) -{ - pt_intr_post(v, vector, type); - - switch(type) { - case APIC_DM_EXTINT: - break; - - default: - vlapic_post_injection(v, vector, type); - break; - } -} - - void hvm_io_assist(struct vcpu *v) { vcpu_iodata_t *vio; diff -r 2a1edeedf28d -r 516e4faac066 xen/arch/x86/hvm/irq.c --- a/xen/arch/x86/hvm/irq.c Wed Dec 20 10:37:23 2006 +0000 +++ b/xen/arch/x86/hvm/irq.c Wed Dec 20 10:41:33 2006 +0000 @@ -229,10 +229,9 @@ int cpu_has_pending_irq(struct vcpu *v) int cpu_has_pending_irq(struct vcpu *v) { struct hvm_domain *plat = &v->domain->arch.hvm_domain; - int dummy; /* APIC */ - if ( cpu_get_apic_interrupt(v, &dummy) != -1 ) + if ( vlapic_has_interrupt(v) != -1 ) return 1; /* PIC */ @@ -267,6 +266,9 @@ int get_intr_vector(struct vcpu* v, int int is_irq_masked(struct vcpu *v, int irq) { + if ( is_lvtt(v, irq) ) + return !is_lvtt_enabled(v); + if ( v->domain->arch.hvm_domain.irq.vpic[irq >> 3].imr & (1 << (irq & 7)) && domain_vioapic(v->domain)->redirtbl[irq].fields.mask ) return 1; diff -r 2a1edeedf28d -r 516e4faac066 xen/arch/x86/hvm/svm/intr.c --- a/xen/arch/x86/hvm/svm/intr.c Wed Dec 20 10:37:23 2006 +0000 +++ b/xen/arch/x86/hvm/svm/intr.c Wed Dec 20 10:41:33 2006 +0000 @@ -141,7 +141,7 @@ asmlinkage void svm_intr_assist(void) break; } - hvm_interrupt_post(v, intr_vector, intr_type); + pt_intr_post(v, intr_vector, intr_type); } /* diff -r 2a1edeedf28d -r 516e4faac066 xen/arch/x86/hvm/vlapic.c --- a/xen/arch/x86/hvm/vlapic.c Wed Dec 20 10:37:23 2006 +0000 +++ b/xen/arch/x86/hvm/vlapic.c Wed Dec 20 10:41:33 2006 +0000 @@ -39,9 +39,8 @@ #define VLAPIC_VERSION 0x00050014 #define VLAPIC_LVT_NUM 6 -extern u32 get_apic_bus_cycle(void); - -#define APIC_BUS_CYCLE_NS (((s_time_t)get_apic_bus_cycle()) / 1000) +/* vlapic's frequence is 100 MHz */ +#define APIC_BUS_CYCLE_NS 10 #define LVT_MASK \ APIC_LVT_MASKED | APIC_SEND_PENDING | APIC_VECTOR_MASK @@ -122,11 +121,6 @@ static int vlapic_test_and_set_irr(int v return vlapic_test_and_set_vector(vector, vlapic->regs + APIC_IRR); } -static void vlapic_set_irr(int vector, struct vlapic *vlapic) -{ - vlapic_set_vector(vector, vlapic->regs + APIC_IRR); -} - static void vlapic_clear_irr(int vector, struct vlapic *vlapic) { vlapic_clear_vector(vector, vlapic->regs + APIC_IRR); @@ -433,46 +427,19 @@ static void vlapic_ipi(struct vlapic *vl static uint32_t vlapic_get_tmcct(struct vlapic *vlapic) { - uint32_t counter_passed; - s_time_t passed, now = NOW(); - uint32_t tmcct = vlapic_get_reg(vlapic, APIC_TMCCT); - - if ( unlikely(now <= vlapic->timer_last_update) ) - { - passed = ~0x0LL - vlapic->timer_last_update + now; - HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "time elapsed."); - } - else - passed = now - vlapic->timer_last_update; - - counter_passed = passed / (APIC_BUS_CYCLE_NS * vlapic->timer_divisor); - - tmcct -= counter_passed; - - if ( tmcct <= 0 ) - { - if ( unlikely(!vlapic_lvtt_period(vlapic)) ) - { - tmcct = 0; - /* FIXME: should we add interrupt here? */ - } - else - { - do { - tmcct += vlapic_get_reg(vlapic, APIC_TMICT); - } while ( tmcct <= 0 ); - } - } - - vlapic->timer_last_update = now; - vlapic_set_reg(vlapic, APIC_TMCCT, tmcct); + struct vcpu *v = current; + uint32_t tmcct, tmict = vlapic_get_reg(vlapic, APIC_TMICT); + uint64_t counter_passed; + + counter_passed = (hvm_get_guest_time(v) - vlapic->pt.last_plt_gtime) // TSC + * 1000000000ULL / ticks_per_sec(v) // NS + / APIC_BUS_CYCLE_NS / vlapic->timer_divisor; + tmcct = tmict - counter_passed; HVM_DBG_LOG(DBG_LEVEL_VLAPIC_TIMER, - "timer initial count 0x%x, timer current count 0x%x, " - "update 0x%016"PRIx64", now 0x%016"PRIx64", offset 0x%x.", - vlapic_get_reg(vlapic, APIC_TMICT), - vlapic_get_reg(vlapic, APIC_TMCCT), - vlapic->timer_last_update, now, counter_passed); + "timer initial count %d, timer current count %d, " + "offset %"PRId64".", + tmict, tmcct, counter_passed); return tmcct; } @@ -486,6 +453,9 @@ static void vlapic_set_tdcr(struct vlapi /* Update the demangled timer_divisor. */ val = ((val & 3) | ((val & 8) >> 1)) + 1; vlapic->timer_divisor = 1 << (val & 7); + + HVM_DBG_LOG(DBG_LEVEL_VLAPIC_TIMER, + "vlapic_set_tdcr timer_divisor: %d.", vlapic->timer_divisor); } static void vlapic_read_aligned(struct vlapic *vlapic, unsigned int offset, @@ -577,6 +547,7 @@ static void vlapic_write(struct vcpu *v, * According to the IA32 Manual, all accesses should be 32 bits. * Some OSes do 8- or 16-byte accesses, however. */ + val &= 0xffffffff; if ( len != 4 ) { unsigned int tmp; @@ -671,6 +642,7 @@ static void vlapic_write(struct vcpu *v, break; case APIC_LVTT: /* LVT Timer Reg */ + vlapic->pt.irq = val & APIC_VECTOR_MASK; case APIC_LVTTHMR: /* LVT Thermal Monitor */ case APIC_LVTPC: /* LVT Performance Counter */ case APIC_LVT0: /* LVT LINT0 Reg */ @@ -684,25 +656,16 @@ static void vlapic_write(struct vcpu *v, case APIC_TMICT: { - s_time_t now = NOW(), offset; - - stop_timer(&vlapic->vlapic_timer); + uint64_t period = APIC_BUS_CYCLE_NS * (uint32_t)val * vlapic->timer_divisor; vlapic_set_reg(vlapic, APIC_TMICT, val); - vlapic_set_reg(vlapic, APIC_TMCCT, val); - vlapic->timer_last_update = now; - - offset = APIC_BUS_CYCLE_NS * vlapic->timer_divisor * val; - - set_timer(&vlapic->vlapic_timer, now + offset); + create_periodic_time(&vlapic->pt, period, vlapic->pt.irq, + vlapic_lvtt_period(vlapic), NULL, vlapic); HVM_DBG_LOG(DBG_LEVEL_VLAPIC, - "bus cycle is %"PRId64"ns, now 0x%016"PRIx64", " - "timer initial count 0x%x, offset 0x%016"PRIx64", " - "expire @ 0x%016"PRIx64".", - APIC_BUS_CYCLE_NS, now, - vlapic_get_reg(vlapic, APIC_TMICT), - offset, now + offset); + "bus cycle is %uns, " + "initial count %lu, period %"PRIu64"ns", + APIC_BUS_CYCLE_NS, val, period); } break; @@ -751,48 +714,6 @@ void vlapic_msr_set(struct vlapic *vlapi HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "apic base msr is 0x%016"PRIx64".", vlapic->apic_base_msr); -} - -void vlapic_timer_fn(void *data) -{ - struct vlapic *vlapic = data; - uint32_t timer_vector; - s_time_t now; - - if ( unlikely(!vlapic_enabled(vlapic) || - !vlapic_lvt_enabled(vlapic, APIC_LVTT)) ) - return; - - timer_vector = vlapic_lvt_vector(vlapic, APIC_LVTT); - now = NOW(); - - vlapic->timer_last_update = now; - - if ( vlapic_test_and_set_irr(timer_vector, vlapic) ) - vlapic->timer_pending_count++; - - if ( vlapic_lvtt_period(vlapic) ) - { - s_time_t offset; - uint32_t tmict = vlapic_get_reg(vlapic, APIC_TMICT); - - vlapic_set_reg(vlapic, APIC_TMCCT, tmict); - - offset = APIC_BUS_CYCLE_NS * vlapic->timer_divisor * tmict; - - set_timer(&vlapic->vlapic_timer, now + offset); - } - else - vlapic_set_reg(vlapic, APIC_TMCCT, 0); - - vcpu_kick(vlapic_vcpu(vlapic)); - - HVM_DBG_LOG(DBG_LEVEL_VLAPIC_TIMER, - "now 0x%016"PRIx64", expire @ 0x%016"PRIx64", " - "timer initial count 0x%x, timer current count 0x%x.", - now, vlapic->vlapic_timer.expires, - vlapic_get_reg(vlapic, APIC_TMICT), - vlapic_get_reg(vlapic, APIC_TMCCT)); } int vlapic_accept_pic_intr(struct vcpu *v) @@ -809,7 +730,7 @@ int vlapic_accept_pic_intr(struct vcpu * vlapic_hw_disabled(vlapic))); } -int cpu_get_apic_interrupt(struct vcpu *v, int *mode) +int vlapic_has_interrupt(struct vcpu *v) { struct vlapic *vlapic = vcpu_vlapic(v); int highest_irr; @@ -822,42 +743,22 @@ int cpu_get_apic_interrupt(struct vcpu * ((highest_irr & 0xF0) <= vlapic_get_ppr(vlapic)) ) return -1; + return highest_irr; +} + +int cpu_get_apic_interrupt(struct vcpu *v, int *mode) +{ + int vector = vlapic_has_interrupt(v); + struct vlapic *vlapic = vcpu_vlapic(v); + + if ( vector == -1 ) + return -1; + + vlapic_set_vector(vector, vlapic->regs + APIC_ISR); + vlapic_clear_irr(vector, vlapic); + *mode = APIC_DM_FIXED; - return highest_irr; -} - -void vlapic_post_injection(struct vcpu *v, int vector, int deliver_mode) -{ - struct vlapic *vlapic = vcpu_vlapic(v); - - switch ( deliver_mode ) - { - case APIC_DM_FIXED: - case APIC_DM_LOWEST: - vlapic_set_vector(vector, vlapic->regs + APIC_ISR); - vlapic_clear_irr(vector, vlapic); - if ( (vector == vlapic_lvt_vector(vlapic, APIC_LVTT)) && - (vlapic->timer_pending_count != 0) ) - { - vlapic->timer_pending_count--; - vlapic_set_irr(vector, vlapic); - } - break; - - case APIC_DM_REMRD: - gdprintk(XENLOG_WARNING, "Ignoring delivery mode 3.\n"); - break; - - case APIC_DM_SMI: - case APIC_DM_NMI: - case APIC_DM_INIT: - case APIC_DM_STARTUP: - break; - - default: - gdprintk(XENLOG_WARNING, "Invalid delivery mode\n"); - break; - } + return vector; } /* Reset the VLPAIC back to its power-on/reset state. */ @@ -918,8 +819,7 @@ int vlapic_init(struct vcpu *v) if ( v->vcpu_id == 0 ) vlapic->apic_base_msr |= MSR_IA32_APICBASE_BSP; - init_timer(&vlapic->vlapic_timer, - vlapic_timer_fn, vlapic, v->processor); + init_timer(&vlapic->pt.timer, pt_timer_fn, &vlapic->pt, v->processor); return 0; } @@ -928,7 +828,22 @@ void vlapic_destroy(struct vcpu *v) { struct vlapic *vlapic = vcpu_vlapic(v); - kill_timer(&vlapic->vlapic_timer); + kill_timer(&vlapic->pt.timer); unmap_domain_page_global(vlapic->regs); free_domheap_page(vlapic->regs_page); } + +int is_lvtt(struct vcpu *v, int vector) +{ + return vcpu_vlapic(v)->pt.enabled && + vector == vlapic_lvt_vector(vcpu_vlapic(v), APIC_LVTT); +} + +int is_lvtt_enabled(struct vcpu *v) +{ + if ( unlikely(!vlapic_enabled(vcpu_vlapic(v))) || + !vlapic_lvt_enabled(vcpu_vlapic(v), APIC_LVTT)) + return 0; + + return 1; +} diff -r 2a1edeedf28d -r 516e4faac066 xen/arch/x86/hvm/vmx/intr.c --- a/xen/arch/x86/hvm/vmx/intr.c Wed Dec 20 10:37:23 2006 +0000 +++ b/xen/arch/x86/hvm/vmx/intr.c Wed Dec 20 10:41:33 2006 +0000 @@ -175,8 +175,8 @@ asmlinkage void vmx_intr_assist(void) BUG(); break; } - - hvm_interrupt_post(v, highest_vector, intr_type); + + pt_intr_post(v, highest_vector, intr_type); } /* diff -r 2a1edeedf28d -r 516e4faac066 xen/arch/x86/hvm/vpt.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xen/arch/x86/hvm/vpt.c Wed Dec 20 10:41:33 2006 +0000 @@ -0,0 +1,231 @@ +/* + * vpt.c: Virtual Platform Timer + * + * Copyright (c) 2006, Xiaowei Yang, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + */ +#include <xen/time.h> +#include <asm/hvm/support.h> +#include <asm/hvm/vpt.h> +#include <asm/event.h> + +static __inline__ void missed_ticks(struct periodic_time *pt) +{ + s_time_t missed_ticks; + + missed_ticks = NOW() - pt->scheduled; + if ( missed_ticks > 0 ) + { + missed_ticks = missed_ticks / (s_time_t) pt->period + 1; + if ( missed_ticks > 1000 ) + { + /* TODO: Adjust guest time together */ + pt->pending_intr_nr++; + } + else + { + pt->pending_intr_nr += missed_ticks; + } + pt->scheduled += missed_ticks * pt->period; + } +} + +void pt_freeze_time(struct vcpu *v) +{ + struct list_head *head = &v->arch.hvm_vcpu.tm_list; + struct list_head *list; + struct periodic_time *pt; + + if ( test_bit(_VCPUF_blocked, &v->vcpu_flags) ) + return; + + v->arch.hvm_vcpu.guest_time = hvm_get_guest_time(v); + + list_for_each( list, head ) + { + pt = list_entry(list, struct periodic_time, list); + stop_timer(&pt->timer); + } +} + +void pt_thaw_time(struct vcpu *v) +{ + struct list_head *head = &v->arch.hvm_vcpu.tm_list; + struct list_head *list; + struct periodic_time *pt; + + if ( v->arch.hvm_vcpu.guest_time ) + { + hvm_set_guest_time(v, v->arch.hvm_vcpu.guest_time); + v->arch.hvm_vcpu.guest_time = 0; + + list_for_each( list, head ) + { + pt = list_entry(list, struct periodic_time, list); + missed_ticks(pt); + set_timer(&pt->timer, pt->scheduled); + } + } +} + +/* Hook function for the platform periodic time */ +void pt_timer_fn(void *data) +{ + struct periodic_time *pt = data; + + pt->pending_intr_nr++; + pt->scheduled += pt->period; + + missed_ticks(pt); + + if ( !pt->one_shot ) + set_timer(&pt->timer, pt->scheduled); + + vcpu_kick(pt->vcpu); +} + +void pt_update_irq(struct vcpu *v) +{ + struct list_head *head = &v->arch.hvm_vcpu.tm_list; + struct list_head *list; + struct periodic_time *pt; + uint64_t max_lag = -1ULL; + int irq = -1; + + list_for_each( list, head ) + { + pt = list_entry(list, struct periodic_time, list); + if ( !is_irq_masked(v, pt->irq) && pt->pending_intr_nr + && pt->last_plt_gtime + pt->period < max_lag ) + { + max_lag = pt->last_plt_gtime + pt->period; + irq = pt->irq; + } + } + + if ( is_lvtt(v, irq) ) + vlapic_set_irq(vcpu_vlapic(v), irq, 0); + else if ( irq >= 0 ) + { + hvm_isa_irq_deassert(v->domain, irq); + hvm_isa_irq_assert(v->domain, irq); + } +} + +struct periodic_time *is_pt_irq(struct vcpu *v, int vector, int type) +{ + struct list_head *head = &v->arch.hvm_vcpu.tm_list; + struct list_head *list; + struct periodic_time *pt; + struct RTCState *rtc = &v->domain->arch.hvm_domain.pl_time.vrtc; + int vec; + + list_for_each( list, head ) + { + pt = list_entry(list, struct periodic_time, list); + if ( !pt->pending_intr_nr ) + continue; + + if ( is_lvtt(v, pt->irq) ) + { + if (pt->irq == vector) + return pt; + else + continue; + } + + vec = get_intr_vector(v, pt->irq, type); + + /* RTC irq need special care */ + if ( vector != vec || (pt->irq == 8 && !is_rtc_periodic_irq(rtc)) ) + continue; + + return pt; + } + + return NULL; +} + +void pt_intr_post(struct vcpu *v, int vector, int type) +{ + struct periodic_time *pt = is_pt_irq(v, vector, type); + + if (pt == NULL) + return; + + pt->pending_intr_nr--; + pt->last_plt_gtime += pt->period_cycles; + hvm_set_guest_time(pt->vcpu, pt->last_plt_gtime); + + if (pt->cb) + pt->cb(pt->vcpu, pt->priv); +} + +/* If pt is enabled, discard pending intr */ +void pt_reset(struct vcpu *v) +{ + struct list_head *head = &v->arch.hvm_vcpu.tm_list; + struct list_head *list; + struct periodic_time *pt; + + list_for_each( list, head ) + { + pt = list_entry(list, struct periodic_time, list); + if ( pt->enabled ) + { + pt->pending_intr_nr = 0; + pt->last_plt_gtime = hvm_get_guest_time(pt->vcpu); + pt->scheduled = NOW() + pt->period; + set_timer(&pt->timer, pt->scheduled); + } + } +} + +void create_periodic_time(struct periodic_time *pt, uint64_t period, + uint8_t irq, char one_shot, time_cb *cb, void *data) +{ + destroy_periodic_time(pt); + + pt->enabled = 1; + if (period < 900000) /* < 0.9 ms */ + { + printk("HVM_PlatformTime: program too small period %"PRIu64"\n", period); + period = 900000; /* force to 0.9ms */ + } + pt->period = period; + pt->vcpu = current; + pt->last_plt_gtime = hvm_get_guest_time(pt->vcpu); + pt->irq = irq; + pt->period_cycles = (u64)period * cpu_khz / 1000000L; + pt->one_shot = one_shot; + pt->scheduled = NOW() + period; + pt->cb = cb; + pt->priv = data; + + list_add(&pt->list, ¤t->arch.hvm_vcpu.tm_list); + set_timer(&pt->timer, pt->scheduled); +} + +void destroy_periodic_time(struct periodic_time *pt) +{ + if ( pt->enabled ) + { + pt->enabled = 0; + pt->pending_intr_nr = 0; + list_del(&pt->list); + stop_timer(&pt->timer); + } +} diff -r 2a1edeedf28d -r 516e4faac066 xen/include/asm-x86/hvm/vlapic.h --- a/xen/include/asm-x86/hvm/vlapic.h Wed Dec 20 10:37:23 2006 +0000 +++ b/xen/include/asm-x86/hvm/vlapic.h Wed Dec 20 10:41:33 2006 +0000 @@ -23,6 +23,7 @@ #include <asm/msr.h> #include <public/hvm/ioreq.h> +#include <asm/hvm/vpt.h> #define MAX_VECTOR 256 @@ -49,14 +50,14 @@ #define vlapic_enabled(vlapic) (!vlapic_disabled(vlapic)) struct vlapic { - uint64_t apic_base_msr; - uint32_t disabled; /* VLAPIC_xx_DISABLED */ - uint32_t timer_divisor; - struct timer vlapic_timer; - int timer_pending_count; - s_time_t timer_last_update; - struct page_info *regs_page; - void *regs; + uint64_t apic_base_msr; + uint32_t disabled; /* VLAPIC_xx_DISABLED */ + uint32_t timer_divisor; + struct periodic_time pt; + int timer_pending_count; + s_time_t timer_last_update; + struct page_info *regs_page; + void *regs; }; static inline uint32_t vlapic_get_reg(struct vlapic *vlapic, uint32_t reg) @@ -70,13 +71,11 @@ static inline void vlapic_set_reg( *((uint32_t *)(vlapic->regs + reg)) = val; } - int vlapic_set_irq(struct vlapic *vlapic, uint8_t vec, uint8_t trig); - -void vlapic_post_injection(struct vcpu *v, int vector, int deliver_mode); int vlapic_find_highest_irr(struct vlapic *vlapic); +int vlapic_has_interrupt(struct vcpu *v); int cpu_get_apic_interrupt(struct vcpu *v, int *mode); int vlapic_init(struct vcpu *v); @@ -91,4 +90,7 @@ struct vlapic *apic_round_robin( int vlapic_match_logical_addr(struct vlapic *vlapic, uint8_t mda); +int is_lvtt(struct vcpu *v, int vector); +int is_lvtt_enabled(struct vcpu *v); + #endif /* __ASM_X86_HVM_VLAPIC_H__ */ diff -r 2a1edeedf28d -r 516e4faac066 xen/include/asm-x86/hvm/vpt.h --- a/xen/include/asm-x86/hvm/vpt.h Wed Dec 20 10:37:23 2006 +0000 +++ b/xen/include/asm-x86/hvm/vpt.h Wed Dec 20 10:41:33 2006 +0000 @@ -42,10 +42,10 @@ struct periodic_time { struct list_head list; char enabled; char one_shot; /* one shot time */ - int irq; + u8 irq; struct vcpu *vcpu; /* vcpu timer interrupt delivers to */ u32 pending_intr_nr; /* the couner for pending timer interrupts */ - u32 period; /* frequency in ns */ + u64 period; /* frequency in ns */ u64 period_cycles; /* frequency in cpu cycles */ s_time_t scheduled; /* scheduled timer interrupt */ u64 last_plt_gtime; /* platform time when last IRQ is injected */ @@ -115,8 +115,8 @@ struct periodic_time *is_pt_irq(struct v struct periodic_time *is_pt_irq(struct vcpu *v, int vector, int type); void pt_intr_post(struct vcpu *v, int vector, int type); void pt_reset(struct vcpu *v); -void create_periodic_time(struct periodic_time *pt, u32 period, char irq, - char one_shot, time_cb *cb, void *data); +void create_periodic_time(struct periodic_time *pt, uint64_t period, + uint8_t irq, char one_shot, time_cb *cb, void *data); void destroy_periodic_time(struct periodic_time *pt); int pv_pit_handler(int port, int data, int write); _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |