[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.