direct-io.hg

changeset 7413:551d099dae3a

Clean up some VMX IO handler code:
1. Clean up some definitions.
2. change d to v, if it means vcpu.
3. remove some tailing spaces.

TODO:
split current VMX IO handler list to 2, one for port IO,
and the other for MMIO.

Signed-off-by: Xin Li <xin.b.li@intel.com>
author kaf24@firebug.cl.cam.ac.uk
date Tue Oct 18 11:09:36 2005 +0100 (2005-10-18)
parents 7155eafc858a
children 7169e31606bd
files xen/arch/x86/vmx_intercept.c xen/arch/x86/vmx_io.c xen/arch/x86/vmx_vmcs.c xen/include/asm-x86/vmx_intercept.h xen/include/asm-x86/vmx_platform.h xen/include/asm-x86/vmx_virpit.h xen/include/asm-x86/vmx_vmcs.h
line diff
     1.1 --- a/xen/arch/x86/vmx_intercept.c	Tue Oct 18 11:07:55 2005 +0100
     1.2 +++ b/xen/arch/x86/vmx_intercept.c	Tue Oct 18 11:09:36 2005 +0100
     1.3 @@ -32,31 +32,36 @@
     1.4  
     1.5  #ifdef CONFIG_VMX
     1.6  
     1.7 -/* Check if the request is handled inside xen
     1.8 -   return value: 0 --not handled; 1 --handled */
     1.9 +/*
    1.10 + * Check if the request is handled inside xen
    1.11 + * return value: 0 --not handled; 1 --handled
    1.12 + */
    1.13  int vmx_io_intercept(ioreq_t *p, int type)
    1.14  {
    1.15 -    struct vcpu *d = current;
    1.16 -    struct vmx_handler_t *handler = &(d->domain->arch.vmx_platform.vmx_handler);
    1.17 +    struct vcpu *v = current;
    1.18 +    struct vmx_io_handler *handler =
    1.19 +                           &(v->domain->arch.vmx_platform.vmx_io_handler);
    1.20      int i;
    1.21 -    unsigned long addr, offset;
    1.22 +    unsigned long addr, size;
    1.23 +
    1.24      for (i = 0; i < handler->num_slot; i++) {
    1.25          if( type != handler->hdl_list[i].type)
    1.26              continue;
    1.27 -        addr   = handler->hdl_list[i].addr;
    1.28 -        offset = handler->hdl_list[i].offset;
    1.29 +        addr = handler->hdl_list[i].addr;
    1.30 +        size = handler->hdl_list[i].size;
    1.31          if (p->addr >= addr &&
    1.32 -            p->addr <  addr + offset)
    1.33 +            p->addr <  addr + size)
    1.34              return handler->hdl_list[i].action(p);
    1.35      }
    1.36      return 0;
    1.37  }
    1.38  
    1.39 -int register_io_handler(unsigned long addr, unsigned long offset, 
    1.40 +int register_io_handler(unsigned long addr, unsigned long size,
    1.41                          intercept_action_t action, int type)
    1.42  {
    1.43 -    struct vcpu *d = current;
    1.44 -    struct vmx_handler_t *handler = &(d->domain->arch.vmx_platform.vmx_handler);
    1.45 +    struct vcpu *v = current;
    1.46 +    struct vmx_io_handler *handler =
    1.47 +                             &(v->domain->arch.vmx_platform.vmx_io_handler);
    1.48      int num = handler->num_slot;
    1.49  
    1.50      if (num >= MAX_IO_HANDLER) {
    1.51 @@ -65,15 +70,15 @@ int register_io_handler(unsigned long ad
    1.52      }
    1.53  
    1.54      handler->hdl_list[num].addr = addr;
    1.55 -    handler->hdl_list[num].offset = offset;
    1.56 +    handler->hdl_list[num].size = size;
    1.57      handler->hdl_list[num].action = action;
    1.58      handler->hdl_list[num].type = type;
    1.59      handler->num_slot++;
    1.60 +
    1.61      return 1;
    1.62 -
    1.63  }
    1.64  
    1.65 -static void pit_cal_count(struct vmx_virpit_t *vpit)
    1.66 +static void pit_cal_count(struct vmx_virpit *vpit)
    1.67  {
    1.68      u64 nsec_delta = (unsigned int)((NOW() - vpit->inject_point));
    1.69      if (nsec_delta > vpit->period)
    1.70 @@ -81,7 +86,7 @@ static void pit_cal_count(struct vmx_vir
    1.71      vpit->count = vpit->init_val - ((nsec_delta * PIT_FREQ / 1000000000ULL) % vpit->init_val );
    1.72  }
    1.73  
    1.74 -static void pit_latch_io(struct vmx_virpit_t *vpit)
    1.75 +static void pit_latch_io(struct vmx_virpit *vpit)
    1.76  {
    1.77      pit_cal_count(vpit);
    1.78  
    1.79 @@ -103,11 +108,11 @@ static void pit_latch_io(struct vmx_virp
    1.80          vpit->count_MSB_latched=1;
    1.81          break;
    1.82      default:
    1.83 -        BUG();
    1.84 +        domain_crash_synchronous();
    1.85      }
    1.86  }
    1.87  
    1.88 -static int pit_read_io(struct vmx_virpit_t *vpit)
    1.89 +static int pit_read_io(struct vmx_virpit *vpit)
    1.90  {
    1.91      if(vpit->count_LSB_latched) {
    1.92          /* Read Least Significant Byte */
    1.93 @@ -168,8 +173,8 @@ static void resume_pit_io(ioreq_t *p)
    1.94  /* the intercept action for PIT DM retval:0--not handled; 1--handled */
    1.95  int intercept_pit_io(ioreq_t *p)
    1.96  {
    1.97 -    struct vcpu *d = current;
    1.98 -    struct vmx_virpit_t *vpit = &(d->domain->arch.vmx_platform.vmx_pit);
    1.99 +    struct vcpu *v = current;
   1.100 +    struct vmx_virpit *vpit = &(v->domain->arch.vmx_platform.vmx_pit);
   1.101  
   1.102      if (p->size != 1 ||
   1.103          p->pdata_valid ||
   1.104 @@ -197,7 +202,7 @@ int intercept_pit_io(ioreq_t *p)
   1.105  /* hooks function for the PIT initialization response iopacket */
   1.106  static void pit_timer_fn(void *data)
   1.107  {
   1.108 -    struct vmx_virpit_t *vpit = data;
   1.109 +    struct vmx_virpit *vpit = data;
   1.110      s_time_t   next;
   1.111      int        missed_ticks;
   1.112  
   1.113 @@ -221,18 +226,18 @@ static void pit_timer_fn(void *data)
   1.114  /* Only some PIT operations such as load init counter need a hypervisor hook.
   1.115   * leave all other operations in user space DM
   1.116   */
   1.117 -void vmx_hooks_assist(struct vcpu *d)
   1.118 +void vmx_hooks_assist(struct vcpu *v)
   1.119  {
   1.120 -    vcpu_iodata_t * vio = get_vio(d->domain, d->vcpu_id);
   1.121 +    vcpu_iodata_t *vio = get_vio(v->domain, v->vcpu_id);
   1.122      ioreq_t *p = &vio->vp_ioreq;
   1.123 -    shared_iopage_t *sp = get_sp(d->domain);
   1.124 +    shared_iopage_t *sp = get_sp(v->domain);
   1.125      u64 *intr = &(sp->sp_global.pic_intr[0]);
   1.126 -    struct vmx_virpit_t *vpit = &(d->domain->arch.vmx_platform.vmx_pit);
   1.127 +    struct vmx_virpit *vpit = &(v->domain->arch.vmx_platform.vmx_pit);
   1.128      int rw_mode, reinit = 0;
   1.129      int oldvec = 0;
   1.130  
   1.131      /* load init count*/
   1.132 -    if (p->state == STATE_IORESP_HOOK) { 
   1.133 +    if (p->state == STATE_IORESP_HOOK) {
   1.134          /* set up actimer, handle re-init */
   1.135          if ( active_ac_timer(&(vpit->pit_timer)) ) {
   1.136              VMX_DBG_LOG(DBG_LEVEL_1, "VMX_PIT: guest reset PIT with channel %lx!\n", (unsigned long) ((p->u.data >> 24) & 0x3) );
   1.137 @@ -241,12 +246,12 @@ void vmx_hooks_assist(struct vcpu *d)
   1.138              oldvec = vpit->vector;
   1.139          }
   1.140          else
   1.141 -            init_ac_timer(&vpit->pit_timer, pit_timer_fn, vpit, d->processor);
   1.142 +            init_ac_timer(&vpit->pit_timer, pit_timer_fn, vpit, v->processor);
   1.143  
   1.144          /* init count for this channel */
   1.145 -        vpit->init_val = (p->u.data & 0xFFFF) ; 
   1.146 +        vpit->init_val = (p->u.data & 0xFFFF) ;
   1.147          /* frequency(ns) of pit */
   1.148 -        vpit->period = DIV_ROUND(((vpit->init_val) * 1000000000ULL), PIT_FREQ); 
   1.149 +        vpit->period = DIV_ROUND(((vpit->init_val) * 1000000000ULL), PIT_FREQ);
   1.150          VMX_DBG_LOG(DBG_LEVEL_1,"VMX_PIT: guest set init pit freq:%u ns, initval:0x%x\n", vpit->period, vpit->init_val);
   1.151          if (vpit->period < 900000) { /* < 0.9 ms */
   1.152              printk("VMX_PIT: guest programmed too small an init_val: %x\n",
   1.153 @@ -283,7 +288,7 @@ void vmx_hooks_assist(struct vcpu *d)
   1.154          }
   1.155  
   1.156          vpit->intr_bitmap = intr;
   1.157 -        vpit->v = d;
   1.158 +        vpit->v = v;
   1.159  
   1.160          vpit->scheduled = NOW() + vpit->period;
   1.161          set_ac_timer(&vpit->pit_timer, vpit->scheduled);
     2.1 --- a/xen/arch/x86/vmx_io.c	Tue Oct 18 11:07:55 2005 +0100
     2.2 +++ b/xen/arch/x86/vmx_io.c	Tue Oct 18 11:09:36 2005 +0100
     2.3 @@ -848,7 +848,8 @@ static inline int find_highest_pending_i
     2.4  static inline void
     2.5  interrupt_post_injection(struct vcpu * v, int vector, int type)
     2.6  {
     2.7 -    struct vmx_virpit_t *vpit = &(v->domain->arch.vmx_platform.vmx_pit);
     2.8 +    struct vmx_virpit *vpit = &(v->domain->arch.vmx_platform.vmx_pit);
     2.9 +
    2.10      switch(type)
    2.11      {
    2.12      case VLAPIC_DELIV_MODE_EXT:
     3.1 --- a/xen/arch/x86/vmx_vmcs.c	Tue Oct 18 11:07:55 2005 +0100
     3.2 +++ b/xen/arch/x86/vmx_vmcs.c	Tue Oct 18 11:09:36 2005 +0100
     3.3 @@ -142,7 +142,7 @@ struct host_execution_env {
     3.4  #endif
     3.5  };
     3.6  
     3.7 -static void vmx_setup_platform(struct vcpu *v)
     3.8 +static void get_io_shared_page(struct vcpu *v)
     3.9  {
    3.10      int i;
    3.11      unsigned char e820_map_nr;
    3.12 @@ -151,6 +151,9 @@ static void vmx_setup_platform(struct vc
    3.13      unsigned long mpfn;
    3.14      unsigned long gpfn = 0;
    3.15  
    3.16 +    if (!(VMX_DOMAIN(v) && (v->vcpu_id == 0)))
    3.17 +        return;
    3.18 +
    3.19      local_flush_tlb_pge();
    3.20  
    3.21      mpfn = get_mfn_from_pfn(E820_MAP_PAGE >> PAGE_SHIFT);
    3.22 @@ -205,6 +208,12 @@ static void vmx_setup_platform(struct vc
    3.23                &v->domain->shared_info->evtchn_mask[0]);
    3.24  }
    3.25  
    3.26 +static void vmx_setup_platform(struct vcpu *v)
    3.27 +{
    3.28 +    if (v->vcpu_id == 0)
    3.29 +        get_io_shared_page(v);
    3.30 +}
    3.31 +
    3.32  static void vmx_set_host_env(struct vcpu *v)
    3.33  {
    3.34      unsigned int tr, cpu, error = 0;
     4.1 --- a/xen/include/asm-x86/vmx_intercept.h	Tue Oct 18 11:07:55 2005 +0100
     4.2 +++ b/xen/include/asm-x86/vmx_intercept.h	Tue Oct 18 11:09:36 2005 +0100
     4.3 @@ -8,49 +8,52 @@
     4.4  #include <xen/errno.h>
     4.5  #include <public/io/ioreq.h>
     4.6  
     4.7 -#define MAX_IO_HANDLER 10
     4.8 +#define MAX_IO_HANDLER              4
     4.9  
    4.10 -typedef int (*intercept_action_t)(ioreq_t*);
    4.11 +#define VMX_PORTIO                  0
    4.12 +#define VMX_MMIO                    1
    4.13  
    4.14 -enum {PORTIO, MMIO};
    4.15 +typedef int (*intercept_action_t)(ioreq_t *);
    4.16  
    4.17 -struct vmx_handler_t {
    4.18 -    int num_slot;
    4.19 -    struct {
    4.20 -        unsigned long       addr;
    4.21 -        int type;
    4.22 -        unsigned long       offset;
    4.23 -        intercept_action_t  action;
    4.24 -    } hdl_list[MAX_IO_HANDLER];
    4.25 +struct io_handler {
    4.26 +    int                 type;
    4.27 +    unsigned long       addr;
    4.28 +    unsigned long       size;
    4.29 +    intercept_action_t  action;
    4.30 +};
    4.31 +
    4.32 +struct vmx_io_handler {
    4.33 +    int     num_slot;
    4.34 +    struct  io_handler hdl_list[MAX_IO_HANDLER];
    4.35  };
    4.36  
    4.37  /* global io interception point in HV */
    4.38  extern int vmx_io_intercept(ioreq_t *p, int type);
    4.39 -extern int register_io_handler(unsigned long addr, unsigned long offset, 
    4.40 +extern int register_io_handler(unsigned long addr, unsigned long size,
    4.41                                 intercept_action_t action, int type);
    4.42  
    4.43  static inline int vmx_portio_intercept(ioreq_t *p)
    4.44  {
    4.45 -    return vmx_io_intercept(p, PORTIO);
    4.46 +    return vmx_io_intercept(p, VMX_PORTIO);
    4.47  }
    4.48  
    4.49  static inline int vmx_mmio_intercept(ioreq_t *p)
    4.50  {
    4.51 -    return vmx_io_intercept(p, MMIO);
    4.52 +    return vmx_io_intercept(p, VMX_MMIO);
    4.53  }
    4.54  
    4.55 -static inline int register_portio_handler(unsigned long addr, 
    4.56 -                                          unsigned long offset, 
    4.57 +static inline int register_portio_handler(unsigned long addr,
    4.58 +                                          unsigned long size,
    4.59                                            intercept_action_t action)
    4.60  {
    4.61 -    return register_io_handler(addr, offset, action, PORTIO);
    4.62 +    return register_io_handler(addr, size, action, VMX_PORTIO);
    4.63  }
    4.64  
    4.65 -static inline int register_mmio_handler(unsigned long addr, 
    4.66 -                                        unsigned long offset, 
    4.67 +static inline int register_mmio_handler(unsigned long addr,
    4.68 +                                        unsigned long size,
    4.69                                          intercept_action_t action)
    4.70  {
    4.71 -    return register_io_handler(addr, offset, action, MMIO);
    4.72 +    return register_io_handler(addr, size, action, VMX_MMIO);
    4.73  }
    4.74  
    4.75  #endif /* _VMX_INTERCEPT_H */
     5.1 --- a/xen/include/asm-x86/vmx_platform.h	Tue Oct 18 11:07:55 2005 +0100
     5.2 +++ b/xen/include/asm-x86/vmx_platform.h	Tue Oct 18 11:09:36 2005 +0100
     5.3 @@ -77,10 +77,9 @@ struct instruction {
     5.4  #define MAX_INST_LEN      32
     5.5  
     5.6  struct virtual_platform_def {
     5.7 -    unsigned long          *real_mode_data; /* E820, etc. */
     5.8      unsigned long          shared_page_va;
     5.9 -    struct vmx_virpit_t    vmx_pit;
    5.10 -    struct vmx_handler_t   vmx_handler;
    5.11 +    struct vmx_virpit      vmx_pit;
    5.12 +    struct vmx_io_handler  vmx_io_handler;
    5.13  };
    5.14  
    5.15  extern void handle_mmio(unsigned long, unsigned long);
     6.1 --- a/xen/include/asm-x86/vmx_virpit.h	Tue Oct 18 11:07:55 2005 +0100
     6.2 +++ b/xen/include/asm-x86/vmx_virpit.h	Tue Oct 18 11:09:36 2005 +0100
     6.3 @@ -16,7 +16,7 @@
     6.4  #define LSByte_multiple 2
     6.5  #define MSByte_multiple 3
     6.6  
     6.7 -struct vmx_virpit_t {
     6.8 +struct vmx_virpit {
     6.9      /* for simulation of counter 0 in mode 2*/
    6.10      int vector;    /* the pit irq vector */
    6.11      unsigned int period;  /* the frequency. e.g. 10ms*/
    6.12 @@ -39,6 +39,6 @@ struct vmx_virpit_t {
    6.13  };
    6.14  
    6.15  /* to hook the ioreq packet to get the PIT initializaiton info */
    6.16 -extern void vmx_hooks_assist(struct vcpu *d);
    6.17 +extern void vmx_hooks_assist(struct vcpu *v);
    6.18  
    6.19  #endif /* _VMX_VIRPIT_H_ */
     7.1 --- a/xen/include/asm-x86/vmx_vmcs.h	Tue Oct 18 11:07:55 2005 +0100
     7.2 +++ b/xen/include/asm-x86/vmx_vmcs.h	Tue Oct 18 11:09:36 2005 +0100
     7.3 @@ -29,7 +29,7 @@ extern void stop_vmx(void);
     7.4  
     7.5  #if defined (__x86_64__)
     7.6  extern void vmx_load_msrs(struct vcpu *n);
     7.7 -void vmx_restore_msrs(struct vcpu *d);
     7.8 +void vmx_restore_msrs(struct vcpu *v);
     7.9  #else
    7.10  #define vmx_load_msrs(_n)          ((void)0)
    7.11  #define vmx_restore_msrs(_v)       ((void)0)
    7.12 @@ -55,7 +55,7 @@ struct vmcs_struct {
    7.13  
    7.14  extern int vmcs_size;
    7.15  
    7.16 -enum { 
    7.17 +enum {
    7.18      VMX_INDEX_MSR_LSTAR = 0,
    7.19      VMX_INDEX_MSR_STAR,
    7.20      VMX_INDEX_MSR_CSTAR,
    7.21 @@ -79,7 +79,7 @@ struct mmio_op {
    7.22      struct cpu_user_regs   *inst_decoder_regs; /* current context */
    7.23  };
    7.24  
    7.25 -#define PC_DEBUG_PORT   0x80 
    7.26 +#define PC_DEBUG_PORT   0x80
    7.27  
    7.28  struct arch_vmx_struct {
    7.29      struct vmcs_struct      *vmcs;  /* VMCS pointer in virtual */
    7.30 @@ -98,7 +98,7 @@ struct arch_vmx_struct {
    7.31  #define vmx_schedule_tail(next)         \
    7.32      (next)->thread.arch_vmx.arch_vmx_schedule_tail((next))
    7.33  
    7.34 -#define VMX_DOMAIN(ed)   ((ed)->arch.arch_vmx.flags)
    7.35 +#define VMX_DOMAIN(v)   ((v)->arch.arch_vmx.flags)
    7.36  
    7.37  #define ARCH_VMX_VMCS_LOADED    0       /* VMCS has been loaded and active */
    7.38  #define ARCH_VMX_VMCS_LAUNCH    1       /* Needs VMCS launch */
    7.39 @@ -278,7 +278,8 @@ enum vmcs_field {
    7.40  extern unsigned int opt_vmx_debug_level;
    7.41  #define VMX_DBG_LOG(level, _f, _a...)           \
    7.42      if ((level) & opt_vmx_debug_level)          \
    7.43 -        printk("[VMX]" _f "\n", ## _a )
    7.44 +        printk("[VMX:%d.%d] " _f "\n",          \
    7.45 +                current->domain->domain_id, current->vcpu_id, ## _a)
    7.46  #else
    7.47  #define VMX_DBG_LOG(level, _f, _a...)
    7.48  #endif