ia64/xen-unstable

changeset 8281:37e19db6ecc3

Improve VMX guest TSC accuracy when guests are
competing for the same physical CPU.

Signed-off-by: Eddie Dong <eddie.dong@intel.com>
author kaf24@firebug.cl.cam.ac.uk
date Thu Dec 08 15:13:38 2005 +0100 (2005-12-08)
parents 08c0861679ce
children 29055c5ad51d
files xen/arch/x86/vmx.c xen/arch/x86/vmx_intercept.c xen/arch/x86/vmx_io.c xen/arch/x86/vmx_vmcs.c xen/include/asm-x86/vmx_vpit.h
line diff
     1.1 --- a/xen/arch/x86/vmx.c	Thu Dec 08 08:57:55 2005 +0000
     1.2 +++ b/xen/arch/x86/vmx.c	Thu Dec 08 15:13:38 2005 +0100
     1.3 @@ -108,7 +108,7 @@ void vmx_relinquish_resources(struct vcp
     1.4      destroy_vmcs(&v->arch.arch_vmx);
     1.5      free_monitor_pagetable(v);
     1.6      vpit = &v->domain->arch.vmx_platform.vmx_pit;
     1.7 -    if ( vpit->ticking && active_ac_timer(&(vpit->pit_timer)) )
     1.8 +    if ( active_ac_timer(&(vpit->pit_timer)) )
     1.9          rem_ac_timer(&vpit->pit_timer);
    1.10      if ( active_ac_timer(&v->arch.arch_vmx.hlt_timer) ) {
    1.11          rem_ac_timer(&v->arch.arch_vmx.hlt_timer);
     2.1 --- a/xen/arch/x86/vmx_intercept.c	Thu Dec 08 08:57:55 2005 +0000
     2.2 +++ b/xen/arch/x86/vmx_intercept.c	Thu Dec 08 15:13:38 2005 +0100
     2.3 @@ -387,7 +387,6 @@ void vmx_hooks_assist(struct vcpu *v)
     2.4          }
     2.5          else {
     2.6              init_ac_timer(&vpit->pit_timer, pit_timer_fn, v, v->processor);
     2.7 -            vpit->ticking = 1;
     2.8          }
     2.9  
    2.10          /* init count for this channel */
     3.1 --- a/xen/arch/x86/vmx_io.c	Thu Dec 08 08:57:55 2005 +0000
     3.2 +++ b/xen/arch/x86/vmx_io.c	Thu Dec 08 15:13:38 2005 +0100
     3.3 @@ -793,29 +793,39 @@ static __inline__ int find_highest_irq(u
     3.4      return __fls(pintr[0]);
     3.5  }
     3.6  
     3.7 +void set_tsc_shift(struct vcpu *v,struct vmx_virpit *vpit)
     3.8 +{
     3.9 +    u64   drift;
    3.10 +
    3.11 +    if ( vpit->first_injected )
    3.12 +        drift = vpit->period_cycles * vpit->pending_intr_nr;
    3.13 +    else 
    3.14 +        drift = 0;
    3.15 +    drift = v->arch.arch_vmx.tsc_offset - drift;
    3.16 +    __vmwrite(TSC_OFFSET, drift);
    3.17 +
    3.18 +#if defined (__i386__)
    3.19 +    __vmwrite(TSC_OFFSET_HIGH, (drift >> 32));
    3.20 +#endif
    3.21 +}
    3.22 +
    3.23  #define BSP_CPU(v)    (!(v->vcpu_id))
    3.24  static inline void
    3.25  interrupt_post_injection(struct vcpu * v, int vector, int type)
    3.26  {
    3.27      struct vmx_virpit *vpit = &(v->domain->arch.vmx_platform.vmx_pit);
    3.28 -    u64    drift;
    3.29  
    3.30      if ( is_pit_irq(v, vector, type) ) {
    3.31          if ( !vpit->first_injected ) {
    3.32 +            vpit->pending_intr_nr = 0;
    3.33 +            vpit->scheduled = NOW() + vpit->period;
    3.34 +            set_ac_timer(&vpit->pit_timer, vpit->scheduled);
    3.35              vpit->first_injected = 1;
    3.36 -            vpit->pending_intr_nr = 0;
    3.37          } else {
    3.38              vpit->pending_intr_nr--;
    3.39          }
    3.40          vpit->inject_point = NOW();
    3.41 -        drift = vpit->period_cycles * vpit->pending_intr_nr;
    3.42 -        drift = v->arch.arch_vmx.tsc_offset - drift;
    3.43 -        __vmwrite(TSC_OFFSET, drift);
    3.44 -
    3.45 -#if defined (__i386__)
    3.46 -        __vmwrite(TSC_OFFSET_HIGH, (drift >> 32));
    3.47 -#endif
    3.48 -
    3.49 +        set_tsc_shift (v, vpit);
    3.50      }
    3.51  
    3.52      switch(type)
    3.53 @@ -982,8 +992,10 @@ void vmx_do_resume(struct vcpu *v)
    3.54              vmx_wait_io();
    3.55      }
    3.56      /* pick up the elapsed PIT ticks and re-enable pit_timer */
    3.57 -    if ( vpit->ticking )
    3.58 +    if ( vpit->first_injected ) {
    3.59          pickup_deactive_ticks(vpit);
    3.60 +    }
    3.61 +    set_tsc_shift(v,vpit);
    3.62  
    3.63      /* We can't resume the guest if we're waiting on I/O */
    3.64      ASSERT(!test_bit(ARCH_VMX_IO_WAIT, &v->arch.arch_vmx.flags));
     4.1 --- a/xen/arch/x86/vmx_vmcs.c	Thu Dec 08 08:57:55 2005 +0000
     4.2 +++ b/xen/arch/x86/vmx_vmcs.c	Thu Dec 08 15:13:38 2005 +0100
     4.3 @@ -290,6 +290,7 @@ static void vmx_do_launch(struct vcpu *v
     4.4  /* Update CR3, GDT, LDT, TR */
     4.5      unsigned int  error = 0;
     4.6      unsigned long cr0, cr4;
     4.7 +    u64     host_tsc;
     4.8  
     4.9      if (v->vcpu_id == 0)
    4.10          vmx_setup_platform(v->domain);
    4.11 @@ -337,6 +338,10 @@ static void vmx_do_launch(struct vcpu *v
    4.12      __vmwrite(HOST_RSP, (unsigned long)get_stack_bottom());
    4.13  
    4.14      v->arch.schedule_tail = arch_vmx_do_resume;
    4.15 +    /* init guest tsc to start from 0 */
    4.16 +    rdtscll(host_tsc);
    4.17 +    v->arch.arch_vmx.tsc_offset = 0 - host_tsc;
    4.18 +    set_tsc_shift (v, &v->domain->arch.vmx_platform.vmx_pit);
    4.19  }
    4.20  
    4.21  /*
    4.22 @@ -366,7 +371,6 @@ static inline int construct_init_vmcs_gu
    4.23      error |= __vmwrite(PAGE_FAULT_ERROR_CODE_MATCH, 0);
    4.24  
    4.25      /* TSC */
    4.26 -    error |= __vmwrite(TSC_OFFSET, 0);
    4.27      error |= __vmwrite(CR3_TARGET_COUNT, 0);
    4.28  
    4.29      /* Guest Selectors */
     5.1 --- a/xen/include/asm-x86/vmx_vpit.h	Thu Dec 08 08:57:55 2005 +0000
     5.2 +++ b/xen/include/asm-x86/vmx_vpit.h	Thu Dec 08 15:13:38 2005 +0100
     5.3 @@ -27,7 +27,6 @@ struct vmx_virpit {
     5.4      unsigned int pending_intr_nr; /* the couner for pending timer interrupts */
     5.5      u32 period;		/* pit frequency in ns */
     5.6      int first_injected;                 /* flag to prevent shadow window */
     5.7 -    int ticking;    /* indicating it is ticking */
     5.8  
     5.9      /* virtual PIT state for handle related I/O */
    5.10      int read_state;
    5.11 @@ -51,5 +50,6 @@ static __inline__ s_time_t get_pit_sched
    5.12      else
    5.13          return -1;
    5.14  }
    5.15 +extern void set_tsc_shift(struct vcpu *v,struct vmx_virpit *vpit);
    5.16  
    5.17  #endif /* _VMX_VIRPIT_H_ */