[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [HVM] Fix SMP timer issues:
# HG changeset patch # User kaf24@xxxxxxxxxxxxxxxxxxxxx # Node ID a1939d76c0e8e27bdac5233df7bd78c004ea8deb # Parent 66fe61db9e69e03e12d0c4086683bebfb4a67780 [HVM] Fix SMP timer issues: * Sync AP TSCs with BP at startup * Only halt BP TSC when descheduled * Correctly handle IPIs on timer vector Signed-off-by: Xiaowei Yang <xiaowei.yang@xxxxxxxxx> --- xen/arch/x86/hvm/hvm.c | 5 ++++- xen/arch/x86/hvm/intercept.c | 1 + xen/arch/x86/hvm/io.c | 3 ++- xen/arch/x86/hvm/svm/svm.c | 3 ++- xen/arch/x86/hvm/vmx/vmcs.c | 13 ++++++++----- xen/arch/x86/hvm/vmx/vmx.c | 10 +++++++++- xen/include/asm-x86/hvm/vpt.h | 1 + 7 files changed, 27 insertions(+), 9 deletions(-) diff -r 66fe61db9e69 -r a1939d76c0e8 xen/arch/x86/hvm/hvm.c --- a/xen/arch/x86/hvm/hvm.c Fri Oct 27 17:50:40 2006 +0100 +++ b/xen/arch/x86/hvm/hvm.c Fri Oct 27 18:00:03 2006 +0100 @@ -228,7 +228,7 @@ void hvm_do_resume(struct vcpu *v) hvm_stts(v); /* pick up the elapsed PIT ticks and re-enable pit_timer */ - if ( pt->enabled && pt->first_injected ) { + if ( pt->enabled && v->vcpu_id == pt->bind_vcpu && pt->first_injected ) { 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; @@ -286,6 +286,9 @@ void hvm_setup_platform(struct domain* d pit_init(v, cpu_khz); rtc_init(v, RTC_PORT(0), RTC_IRQ); pmtimer_init(v, ACPI_PM_TMR_BLK_ADDRESS); + + /* init guest tsc to start from 0 */ + hvm_set_guest_time(v, 0); } void pic_irq_request(void *data, int level) diff -r 66fe61db9e69 -r a1939d76c0e8 xen/arch/x86/hvm/intercept.c --- a/xen/arch/x86/hvm/intercept.c Fri Oct 27 17:50:40 2006 +0100 +++ b/xen/arch/x86/hvm/intercept.c Fri Oct 27 18:00:03 2006 +0100 @@ -325,6 +325,7 @@ struct periodic_time * create_periodic_t stop_timer (&pt->timer); pt->enabled = 0; } + pt->bind_vcpu = 0; /* timer interrupt delivered to BSP by default */ pt->pending_intr_nr = 0; pt->first_injected = 0; if (period < 900000) { /* < 0.9 ms */ diff -r 66fe61db9e69 -r a1939d76c0e8 xen/arch/x86/hvm/io.c --- a/xen/arch/x86/hvm/io.c Fri Oct 27 17:50:40 2006 +0100 +++ b/xen/arch/x86/hvm/io.c Fri Oct 27 18:00:03 2006 +0100 @@ -683,7 +683,8 @@ void hvm_interrupt_post(struct vcpu *v, struct periodic_time *pt = &(v->domain->arch.hvm_domain.pl_time.periodic_tm); - if ( pt->enabled && is_periodic_irq(v, vector, type) ) { + if ( pt->enabled && v->vcpu_id == pt->bind_vcpu + && is_periodic_irq(v, vector, type) ) { if ( !pt->first_injected ) { pt->pending_intr_nr = 0; pt->last_plt_gtime = hvm_get_guest_time(v); diff -r 66fe61db9e69 -r a1939d76c0e8 xen/arch/x86/hvm/svm/svm.c --- a/xen/arch/x86/hvm/svm/svm.c Fri Oct 27 17:50:40 2006 +0100 +++ b/xen/arch/x86/hvm/svm/svm.c Fri Oct 27 18:00:03 2006 +0100 @@ -761,7 +761,8 @@ static void svm_freeze_time(struct vcpu { struct periodic_time *pt=&v->domain->arch.hvm_domain.pl_time.periodic_tm; - if ( pt->enabled && pt->first_injected && !v->arch.hvm_vcpu.guest_time ) { + if ( pt->enabled && pt->first_injected && v->vcpu_id == pt->bind_vcpu + && !v->arch.hvm_vcpu.guest_time ) { v->arch.hvm_vcpu.guest_time = hvm_get_guest_time(v); stop_timer(&(pt->timer)); } diff -r 66fe61db9e69 -r a1939d76c0e8 xen/arch/x86/hvm/vmx/vmcs.c --- a/xen/arch/x86/hvm/vmx/vmcs.c Fri Oct 27 17:50:40 2006 +0100 +++ b/xen/arch/x86/hvm/vmx/vmcs.c Fri Oct 27 18:00:03 2006 +0100 @@ -314,14 +314,20 @@ static void vmx_set_host_env(struct vcpu error |= __vmwrite(HOST_RSP, (unsigned long)get_stack_bottom()); } +/* Update CR3, CR0, CR4, GDT, LDT, TR */ static void vmx_do_launch(struct vcpu *v) { -/* Update CR3, CR0, CR4, GDT, LDT, TR */ unsigned int error = 0; unsigned long cr0, cr4; - if (v->vcpu_id == 0) + if ( v->vcpu_id == 0 ) hvm_setup_platform(v->domain); + else { + /* Sync AP's TSC with BSP's */ + v->arch.hvm_vcpu.cache_tsc_offset = + v->domain->vcpu[0]->arch.hvm_vcpu.cache_tsc_offset; + hvm_funcs.set_tsc_offset(v, v->arch.hvm_vcpu.cache_tsc_offset); + } __asm__ __volatile__ ("mov %%cr0,%0" : "=r" (cr0) : ); @@ -360,9 +366,6 @@ static void vmx_do_launch(struct vcpu *v __vmwrite(HOST_CR3, v->arch.cr3); v->arch.schedule_tail = arch_vmx_do_resume; - - /* init guest tsc to start from 0 */ - hvm_set_guest_time(v, 0); } /* diff -r 66fe61db9e69 -r a1939d76c0e8 xen/arch/x86/hvm/vmx/vmx.c --- a/xen/arch/x86/hvm/vmx/vmx.c Fri Oct 27 17:50:40 2006 +0100 +++ b/xen/arch/x86/hvm/vmx/vmx.c Fri Oct 27 18:00:03 2006 +0100 @@ -458,7 +458,8 @@ static void vmx_freeze_time(struct vcpu { struct periodic_time *pt=&v->domain->arch.hvm_domain.pl_time.periodic_tm; - if ( pt->enabled && pt->first_injected && !v->arch.hvm_vcpu.guest_time ) { + if ( pt->enabled && pt->first_injected && v->vcpu_id == pt->bind_vcpu + && !v->arch.hvm_vcpu.guest_time ) { v->arch.hvm_vcpu.guest_time = hvm_get_guest_time(v); stop_timer(&(pt->timer)); } @@ -1972,6 +1973,13 @@ static inline void vmx_do_msr_write(stru switch (regs->ecx) { case MSR_IA32_TIME_STAMP_COUNTER: + { + struct periodic_time *pt = + &(v->domain->arch.hvm_domain.pl_time.periodic_tm); + if ( pt->enabled && pt->first_injected + && v->vcpu_id == pt->bind_vcpu ) + pt->first_injected = 0; + } hvm_set_guest_time(v, msr_content); break; case MSR_IA32_SYSENTER_CS: diff -r 66fe61db9e69 -r a1939d76c0e8 xen/include/asm-x86/hvm/vpt.h --- a/xen/include/asm-x86/hvm/vpt.h Fri Oct 27 17:50:40 2006 +0100 +++ b/xen/include/asm-x86/hvm/vpt.h Fri Oct 27 18:00:03 2006 +0100 @@ -91,6 +91,7 @@ struct periodic_time { char one_shot; /* one shot time */ char irq; char first_injected; /* flag to prevent shadow window */ + u32 bind_vcpu; /* vcpu timer interrupt delivers to */ u32 pending_intr_nr; /* the couner for pending timer interrupts */ u32 period; /* frequency in ns */ u64 period_cycles; /* frequency in cpu cycles */ _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |