ia64/xen-unstable

changeset 12026:a1939d76c0e8

[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@intel.com>
author kaf24@localhost.localdomain
date Fri Oct 27 18:00:03 2006 +0100 (2006-10-27)
parents 66fe61db9e69
children ee140fbcb88d
files xen/arch/x86/hvm/hvm.c xen/arch/x86/hvm/intercept.c xen/arch/x86/hvm/io.c xen/arch/x86/hvm/svm/svm.c xen/arch/x86/hvm/vmx/vmcs.c xen/arch/x86/hvm/vmx/vmx.c xen/include/asm-x86/hvm/vpt.h
line diff
     1.1 --- a/xen/arch/x86/hvm/hvm.c	Fri Oct 27 17:50:40 2006 +0100
     1.2 +++ b/xen/arch/x86/hvm/hvm.c	Fri Oct 27 18:00:03 2006 +0100
     1.3 @@ -228,7 +228,7 @@ void hvm_do_resume(struct vcpu *v)
     1.4      hvm_stts(v);
     1.5  
     1.6      /* pick up the elapsed PIT ticks and re-enable pit_timer */
     1.7 -    if ( pt->enabled && pt->first_injected ) {
     1.8 +    if ( pt->enabled && v->vcpu_id == pt->bind_vcpu && pt->first_injected ) {
     1.9          if ( v->arch.hvm_vcpu.guest_time ) {
    1.10              hvm_set_guest_time(v, v->arch.hvm_vcpu.guest_time);
    1.11              v->arch.hvm_vcpu.guest_time = 0;
    1.12 @@ -286,6 +286,9 @@ void hvm_setup_platform(struct domain* d
    1.13      pit_init(v, cpu_khz);
    1.14      rtc_init(v, RTC_PORT(0), RTC_IRQ);
    1.15      pmtimer_init(v, ACPI_PM_TMR_BLK_ADDRESS); 
    1.16 +
    1.17 +    /* init guest tsc to start from 0 */
    1.18 +    hvm_set_guest_time(v, 0);
    1.19  }
    1.20  
    1.21  void pic_irq_request(void *data, int level)
     2.1 --- a/xen/arch/x86/hvm/intercept.c	Fri Oct 27 17:50:40 2006 +0100
     2.2 +++ b/xen/arch/x86/hvm/intercept.c	Fri Oct 27 18:00:03 2006 +0100
     2.3 @@ -325,6 +325,7 @@ struct periodic_time * create_periodic_t
     2.4          stop_timer (&pt->timer);
     2.5          pt->enabled = 0;
     2.6      }
     2.7 +    pt->bind_vcpu = 0; /* timer interrupt delivered to BSP by default */
     2.8      pt->pending_intr_nr = 0;
     2.9      pt->first_injected = 0;
    2.10      if (period < 900000) { /* < 0.9 ms */
     3.1 --- a/xen/arch/x86/hvm/io.c	Fri Oct 27 17:50:40 2006 +0100
     3.2 +++ b/xen/arch/x86/hvm/io.c	Fri Oct 27 18:00:03 2006 +0100
     3.3 @@ -683,7 +683,8 @@ void hvm_interrupt_post(struct vcpu *v, 
     3.4      struct  periodic_time *pt = 
     3.5          &(v->domain->arch.hvm_domain.pl_time.periodic_tm);
     3.6  
     3.7 -    if ( pt->enabled && is_periodic_irq(v, vector, type) ) {
     3.8 +    if ( pt->enabled && v->vcpu_id == pt->bind_vcpu 
     3.9 +            && is_periodic_irq(v, vector, type) ) {
    3.10          if ( !pt->first_injected ) {
    3.11              pt->pending_intr_nr = 0;
    3.12              pt->last_plt_gtime = hvm_get_guest_time(v);
     4.1 --- a/xen/arch/x86/hvm/svm/svm.c	Fri Oct 27 17:50:40 2006 +0100
     4.2 +++ b/xen/arch/x86/hvm/svm/svm.c	Fri Oct 27 18:00:03 2006 +0100
     4.3 @@ -761,7 +761,8 @@ static void svm_freeze_time(struct vcpu 
     4.4  {
     4.5      struct periodic_time *pt=&v->domain->arch.hvm_domain.pl_time.periodic_tm;
     4.6      
     4.7 -    if ( pt->enabled && pt->first_injected && !v->arch.hvm_vcpu.guest_time ) {
     4.8 +    if ( pt->enabled && pt->first_injected && v->vcpu_id == pt->bind_vcpu 
     4.9 +            && !v->arch.hvm_vcpu.guest_time ) {
    4.10          v->arch.hvm_vcpu.guest_time = hvm_get_guest_time(v);
    4.11          stop_timer(&(pt->timer));
    4.12      }
     5.1 --- a/xen/arch/x86/hvm/vmx/vmcs.c	Fri Oct 27 17:50:40 2006 +0100
     5.2 +++ b/xen/arch/x86/hvm/vmx/vmcs.c	Fri Oct 27 18:00:03 2006 +0100
     5.3 @@ -314,14 +314,20 @@ static void vmx_set_host_env(struct vcpu
     5.4      error |= __vmwrite(HOST_RSP, (unsigned long)get_stack_bottom());
     5.5  }
     5.6  
     5.7 +/* Update CR3, CR0, CR4, GDT, LDT, TR */
     5.8  static void vmx_do_launch(struct vcpu *v)
     5.9  {
    5.10 -/* Update CR3, CR0, CR4, GDT, LDT, TR */
    5.11      unsigned int  error = 0;
    5.12      unsigned long cr0, cr4;
    5.13  
    5.14 -    if (v->vcpu_id == 0)
    5.15 +    if ( v->vcpu_id == 0 )
    5.16          hvm_setup_platform(v->domain);
    5.17 +    else {
    5.18 +        /* Sync AP's TSC with BSP's */
    5.19 +        v->arch.hvm_vcpu.cache_tsc_offset = 
    5.20 +            v->domain->vcpu[0]->arch.hvm_vcpu.cache_tsc_offset;
    5.21 +        hvm_funcs.set_tsc_offset(v, v->arch.hvm_vcpu.cache_tsc_offset);
    5.22 +    }
    5.23  
    5.24      __asm__ __volatile__ ("mov %%cr0,%0" : "=r" (cr0) : );
    5.25  
    5.26 @@ -360,9 +366,6 @@ static void vmx_do_launch(struct vcpu *v
    5.27      __vmwrite(HOST_CR3, v->arch.cr3);
    5.28  
    5.29      v->arch.schedule_tail = arch_vmx_do_resume;
    5.30 -
    5.31 -    /* init guest tsc to start from 0 */
    5.32 -    hvm_set_guest_time(v, 0);
    5.33  }
    5.34  
    5.35  /*
     6.1 --- a/xen/arch/x86/hvm/vmx/vmx.c	Fri Oct 27 17:50:40 2006 +0100
     6.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c	Fri Oct 27 18:00:03 2006 +0100
     6.3 @@ -458,7 +458,8 @@ static void vmx_freeze_time(struct vcpu 
     6.4  {
     6.5      struct periodic_time *pt=&v->domain->arch.hvm_domain.pl_time.periodic_tm;
     6.6      
     6.7 -    if ( pt->enabled && pt->first_injected && !v->arch.hvm_vcpu.guest_time ) {
     6.8 +    if ( pt->enabled && pt->first_injected && v->vcpu_id == pt->bind_vcpu
     6.9 +            && !v->arch.hvm_vcpu.guest_time ) {
    6.10          v->arch.hvm_vcpu.guest_time = hvm_get_guest_time(v);
    6.11          stop_timer(&(pt->timer));
    6.12      }
    6.13 @@ -1972,6 +1973,13 @@ static inline void vmx_do_msr_write(stru
    6.14  
    6.15      switch (regs->ecx) {
    6.16      case MSR_IA32_TIME_STAMP_COUNTER:
    6.17 +        {
    6.18 +            struct periodic_time *pt =
    6.19 +                &(v->domain->arch.hvm_domain.pl_time.periodic_tm);
    6.20 +            if ( pt->enabled && pt->first_injected 
    6.21 +                    && v->vcpu_id == pt->bind_vcpu ) 
    6.22 +                pt->first_injected = 0;
    6.23 +        }
    6.24          hvm_set_guest_time(v, msr_content);
    6.25          break;
    6.26      case MSR_IA32_SYSENTER_CS:
     7.1 --- a/xen/include/asm-x86/hvm/vpt.h	Fri Oct 27 17:50:40 2006 +0100
     7.2 +++ b/xen/include/asm-x86/hvm/vpt.h	Fri Oct 27 18:00:03 2006 +0100
     7.3 @@ -91,6 +91,7 @@ struct periodic_time {
     7.4      char one_shot;              /* one shot time */
     7.5      char irq;
     7.6      char first_injected;        /* flag to prevent shadow window */
     7.7 +    u32 bind_vcpu;              /* vcpu timer interrupt delivers to */
     7.8      u32 pending_intr_nr;        /* the couner for pending timer interrupts */
     7.9      u32 period;                 /* frequency in ns */
    7.10      u64 period_cycles;          /* frequency in cpu cycles */