ia64/xen-unstable

changeset 3920:bfab968fcfa1

bitkeeper revision 1.1236.1.19 (421e762a-grjFXfk-0fR1nd4ASovMA)

[PATCH] Support 1000 HZ guests

- Support guests with 1000 Hz
- cleanup the trailing garbage in vmx_virtpit.h
- Don't queue up pending timer interrupts before the first interrupt is injected
- This fixes the low bogomips problem
- Protect xen against guests programming a bad value for the counter

Signed-off-by: Edwin Zhai <edwin.zhai@intel.com>
Signed-off-by: Arun Sharma <arun.sharma@intel.com>
author arun.sharma@intel.com[iap10]
date Fri Feb 25 00:49:46 2005 +0000 (2005-02-25)
parents 55eb56401a79
children 4aa083685db4
files xen/arch/x86/vmx_intercept.c xen/arch/x86/vmx_io.c xen/include/asm-x86/vmx_virpit.h xen/include/xen/lib.h
line diff
     1.1 --- a/xen/arch/x86/vmx_intercept.c	Fri Feb 25 00:37:10 2005 +0000
     1.2 +++ b/xen/arch/x86/vmx_intercept.c	Fri Feb 25 00:49:46 2005 +0000
     1.3 @@ -203,7 +203,7 @@ static void pit_timer_fn(unsigned long d
     1.4  
     1.5  
     1.6  /* Only some PIT operations such as load init counter need a hypervisor hook.
     1.7 - * leave many other operations in user space DM
     1.8 + * leave all other operations in user space DM
     1.9   */
    1.10  void vmx_hooks_assist(struct exec_domain *d)
    1.11  {
    1.12 @@ -213,11 +213,20 @@ void vmx_hooks_assist(struct exec_domain
    1.13      struct vmx_virpit_t *vpit = &(d->arch.arch_vmx.vmx_platform.vmx_pit);
    1.14      int rw_mode;
    1.15  
    1.16 -    if (p->state == STATE_IORESP_HOOK) { /*load init count*/
    1.17 -        vpit->init_val = (p->u.data & 0xFFFF) ; /* frequency(ms) of pit */
    1.18 -        vpit->period = (vpit->init_val) * 1000 / PIT_FREQ; /* frequency(ms) of pit */
    1.19 +    /* load init count*/
    1.20 +    if (p->state == STATE_IORESP_HOOK) { 
    1.21 +        /* init count for this channel */
    1.22 +        vpit->init_val = (p->u.data & 0xFFFF) ; 
    1.23 +        /* frequency(ms) of pit */
    1.24 +        vpit->period = DIV_ROUND(((vpit->init_val) * 1000), PIT_FREQ); 
    1.25 +        if (vpit->period < 1) {
    1.26 +            printk("VMX_PIT: guest programmed too small an init_val: %lx\n",
    1.27 +                   vpit->init_val);
    1.28 +            vpit->period = 1;
    1.29 +        }
    1.30          vpit->vector = ((p->u.data >> 16) & 0xFF);
    1.31          vpit->channel = ((p->u.data >> 24) & 0x3);
    1.32 +        vpit->first_injected = 0;
    1.33  
    1.34  	vpit->count_LSB_latched = 0;
    1.35  	vpit->count_MSB_latched = 0;
     2.1 --- a/xen/arch/x86/vmx_io.c	Fri Feb 25 00:37:10 2005 +0000
     2.2 +++ b/xen/arch/x86/vmx_io.c	Fri Feb 25 00:49:46 2005 +0000
     2.3 @@ -367,6 +367,12 @@ void vmx_intr_assist(struct exec_domain 
     2.4      else
     2.5          clear_highest_bit(d, highest_vector); 
     2.6  
     2.7 +    /* close the window between guest PIT initialization and sti */
     2.8 +    if (highest_vector == vpit->vector && !vpit->first_injected){
     2.9 +        vpit->first_injected = 1;
    2.10 +        vpit->pending_intr_nr = 0;
    2.11 +    }
    2.12 +
    2.13      intr_fields = (INTR_INFO_VALID_MASK | INTR_TYPE_EXT_INTR | highest_vector);
    2.14      __vmwrite(VM_ENTRY_INTR_INFO_FIELD, intr_fields);
    2.15  
     3.1 --- a/xen/include/asm-x86/vmx_virpit.h	Fri Feb 25 00:37:10 2005 +0000
     3.2 +++ b/xen/include/asm-x86/vmx_virpit.h	Fri Feb 25 00:49:46 2005 +0000
     3.3 @@ -1,4 +1,3 @@
     3.4 -
     3.5  #ifndef _VMX_VIRPIT_H
     3.6  #define _VMX_VIRPIT_H
     3.7  #include <xen/config.h>
     3.8 @@ -25,6 +24,7 @@ struct vmx_virpit_t {
     3.9      unsigned int pending_intr_nr;	/* the couner for pending timer interrupts */
    3.10      unsigned long long inject_point;	/* the time inject virt intr */
    3.11      struct ac_timer pit_timer;		/* periodic timer for mode 2*/
    3.12 +    int first_injected;                 /* flag to prevent shadow window */
    3.13  
    3.14      /* virtual PIT state for handle related I/O */
    3.15      int read_state;
    3.16 @@ -40,42 +40,3 @@ struct vmx_virpit_t {
    3.17  extern void vmx_hooks_assist(struct exec_domain *d);
    3.18  
    3.19  #endif /* _VMX_VIRPIT_H_ */
    3.20 -
    3.21 -#ifndef _VMX_VIRPIT_H
    3.22 -#define _VMX_VIRPIT_H
    3.23 -#include <xen/config.h>
    3.24 -#include <xen/init.h>
    3.25 -#include <xen/lib.h>
    3.26 -#include <xen/time.h>
    3.27 -#include <xen/errno.h>
    3.28 -#include <xen/ac_timer.h>
    3.29 -#include <asm/vmx_vmcs.h>
    3.30 -
    3.31 -#define PIT_FREQ 1193181
    3.32 -
    3.33 -#define LSByte 0
    3.34 -#define MSByte 1
    3.35 -#define LSByte_multiple 2
    3.36 -#define MSByte_multiple 3
    3.37 -
    3.38 -struct vmx_virpit_t {
    3.39 -    /* for simulation of counter 0 in mode 2*/
    3.40 -    int vector;				/* the pit irq vector */
    3.41 -    unsigned int period;		/* the frequency. e.g. 10ms*/
    3.42 -    unsigned int channel;		/* the pit channel, counter 0~2 */
    3.43 -    unsigned long *intr_bitmap;
    3.44 -    unsigned int pending_intr_nr;	/* the couner for pending timer interrupts */
    3.45 -    unsigned long long inject_point;	/* the time inject virt intr */
    3.46 -    struct ac_timer pit_timer;		/* periodic timer for mode 2*/
    3.47 -
    3.48 -    /* virtual PIT state for handle related I/O */
    3.49 -    int read_state;
    3.50 -    int count_LSB_latched;
    3.51 -    int count_MSB_latched;
    3.52 -
    3.53 -    unsigned int count;		/* the 16 bit channel count */
    3.54 -    unsigned int init_val;	/* the init value for the counter */
    3.55 -
    3.56 -} ;
    3.57 -
    3.58 -#endif /* _VMX_VIRPIT_H_ */
     4.1 --- a/xen/include/xen/lib.h	Fri Feb 25 00:37:10 2005 +0000
     4.2 +++ b/xen/include/xen/lib.h	Fri Feb 25 00:49:46 2005 +0000
     4.3 @@ -23,6 +23,8 @@
     4.4  #define SWAP(_a, _b) \
     4.5     do { typeof(_a) _t = (_a); (_a) = (_b); (_b) = _t; } while ( 0 )
     4.6  
     4.7 +#define DIV_ROUND(x, y) (((x) + (y) - 1) / (y))
     4.8 +
     4.9  #define reserve_bootmem(_p,_l) ((void)0)
    4.10  
    4.11  struct domain;