ia64/xen-unstable

changeset 5609:e5a99f9dc34d

bitkeeper revision 1.1774 (42c3a855yAuKBfmJfftjhiVDml26pg)

[PATCH] Extend the VMX intercept mechanism to include mmio as well as portio.

Extend the VMX intercept mechanism to include mmio as well as portio.

Signed-off-by: Yunhong Jiang <yunhong.jiang@intel.com>
Signed-off-by: Xiaofeng Ling <xiaofeng.ling@intel.com>
Signed-off-by: Arun Sharma <arun.sharma@intel.com>
author arun.sharma@intel.com[kaf24]
date Thu Jun 30 08:07:49 2005 +0000 (2005-06-30)
parents 6daf7357a9df
children cd86df78b879
files xen/arch/x86/vmx.c xen/arch/x86/vmx_intercept.c xen/arch/x86/vmx_platform.c xen/include/asm-x86/vmx_intercept.h xen/include/asm-x86/vmx_platform.h
line diff
     1.1 --- a/xen/arch/x86/vmx.c	Thu Jun 30 08:07:29 2005 +0000
     1.2 +++ b/xen/arch/x86/vmx.c	Thu Jun 30 08:07:49 2005 +0000
     1.3 @@ -135,17 +135,20 @@ static int vmx_do_page_fault(unsigned lo
     1.4      }
     1.5  #endif
     1.6  
     1.7 -    if (!vmx_paging_enabled(current))
     1.8 +    if (!vmx_paging_enabled(current)){
     1.9          handle_mmio(va, va);
    1.10 -
    1.11 +        return 1;
    1.12 +    }
    1.13      gpte = gva_to_gpte(va);
    1.14      if (!(l1e_get_flags(gpte) & _PAGE_PRESENT) )
    1.15              return 0;
    1.16      gpa = l1e_get_paddr(gpte) + (va & ~PAGE_MASK);
    1.17  
    1.18      /* Use 1:1 page table to identify MMIO address space */
    1.19 -    if (mmio_space(gpa))
    1.20 +    if (mmio_space(gpa)){
    1.21          handle_mmio(va, gpa);
    1.22 +        return 1;
    1.23 +    }
    1.24  
    1.25      result = shadow_fault(va, regs);
    1.26  
    1.27 @@ -451,10 +454,9 @@ static void vmx_io_instruction(struct cp
    1.28      p->port_mm = 0;
    1.29  
    1.30      /* Check if the packet needs to be intercepted */
    1.31 -    if (vmx_io_intercept(p)) {
    1.32 +    if (vmx_portio_intercept(p))
    1.33  	/* no blocking & no evtchn notification */
    1.34          return;
    1.35 -    } 
    1.36  
    1.37      set_bit(ARCH_VMX_IO_WAIT, &d->arch.arch_vmx.flags);
    1.38      p->state = STATE_IOREQ_READY;
     2.1 --- a/xen/arch/x86/vmx_intercept.c	Thu Jun 30 08:07:29 2005 +0000
     2.2 +++ b/xen/arch/x86/vmx_intercept.c	Thu Jun 30 08:07:49 2005 +0000
     2.3 @@ -31,14 +31,17 @@
     2.4  
     2.5  #ifdef CONFIG_VMX
     2.6  
     2.7 -/* for intercepting io request after vm_exit, return value: 0--not handle; 1--handled */
     2.8 -int vmx_io_intercept(ioreq_t *p)
     2.9 +/* Check if the request is handled inside xen
    2.10 +   return value: 0 --not handled; 1 --handled */
    2.11 +int vmx_io_intercept(ioreq_t *p, int type)
    2.12  {
    2.13      struct vcpu *d = current;
    2.14      struct vmx_handler_t *handler = &(d->domain->arch.vmx_platform.vmx_handler);
    2.15      int i;
    2.16      unsigned long addr, offset;
    2.17      for (i = 0; i < handler->num_slot; i++) {
    2.18 +        if( type != handler->hdl_list[i].type)
    2.19 +            continue;
    2.20          addr   = handler->hdl_list[i].addr;
    2.21          offset = handler->hdl_list[i].offset;
    2.22          if (p->addr >= addr &&
    2.23 @@ -48,7 +51,8 @@ int vmx_io_intercept(ioreq_t *p)
    2.24      return 0;
    2.25  }
    2.26  
    2.27 -int register_io_handler(unsigned long addr, unsigned long offset, intercept_action_t action)
    2.28 +int register_io_handler(unsigned long addr, unsigned long offset, 
    2.29 +                        intercept_action_t action, int type)
    2.30  {
    2.31      struct vcpu *d = current;
    2.32      struct vmx_handler_t *handler = &(d->domain->arch.vmx_platform.vmx_handler);
    2.33 @@ -62,6 +66,7 @@ int register_io_handler(unsigned long ad
    2.34      handler->hdl_list[num].addr = addr;
    2.35      handler->hdl_list[num].offset = offset;
    2.36      handler->hdl_list[num].action = action;
    2.37 +    handler->hdl_list[num].type = type;
    2.38      handler->num_slot++;
    2.39      return 1;
    2.40  
    2.41 @@ -262,7 +267,7 @@ void vmx_hooks_assist(struct vcpu *d)
    2.42          p->state = STATE_IORESP_READY;
    2.43  
    2.44  	/* register handler to intercept the PIT io when vm_exit */
    2.45 -	register_io_handler(0x40, 4, intercept_pit_io); 
    2.46 +	register_portio_handler(0x40, 4, intercept_pit_io); 
    2.47      }
    2.48  
    2.49  }
     3.1 --- a/xen/arch/x86/vmx_platform.c	Thu Jun 30 08:07:29 2005 +0000
     3.2 +++ b/xen/arch/x86/vmx_platform.c	Thu Jun 30 08:07:49 2005 +0000
     3.3 @@ -606,12 +606,11 @@ static void send_mmio_req(unsigned long 
     3.4      if ((pvalid) && vmx_paging_enabled(current))
     3.5          p->u.pdata = (void *) gva_to_gpa(p->u.data);
     3.6  
     3.7 -#if 0
     3.8 -    printf("send_mmio_req: eip 0x%lx:0x%lx, dir %d, pdata_valid %d, ",
     3.9 -	inst_decoder_regs->cs, inst_decoder_regs->eip, p->dir, p->pdata_valid);
    3.10 -    printf("port_mm %d, size %lld, addr 0x%llx, value 0x%lx, count %lld\n",
    3.11 -	p->port_mm, p->size, p->addr, value, p->count);
    3.12 -#endif
    3.13 +    if (vmx_mmio_intercept(p)){
    3.14 +        p->state = STATE_IORESP_READY;
    3.15 +        vmx_io_assist(d);
    3.16 +        return;
    3.17 +    }
    3.18  
    3.19      evtchn_send(iopacket_port(d->domain));
    3.20      vmx_wait_io();
    3.21 @@ -709,6 +708,7 @@ void handle_mmio(unsigned long va, unsig
    3.22              // Send the request and waiting for return value.
    3.23              mpci_p->mmio_target = mmio_inst.operand[1];
    3.24              send_mmio_req(gpa, &mmio_inst, value, IOREQ_READ, 0);
    3.25 +            return;
    3.26          } else {
    3.27              // Write to MMIO
    3.28              if (mmio_inst.operand[0] & IMMEDIATE) {
    3.29 @@ -728,6 +728,7 @@ void handle_mmio(unsigned long va, unsig
    3.30      if (!strncmp((char *)mmio_inst.i_name, "stos", 4)) {
    3.31          send_mmio_req(gpa, &mmio_inst,
    3.32              inst_decoder_regs->eax, IOREQ_WRITE, 0);
    3.33 +        return;
    3.34      }
    3.35  
    3.36      domain_crash_synchronous();
     4.1 --- a/xen/include/asm-x86/vmx_intercept.h	Thu Jun 30 08:07:29 2005 +0000
     4.2 +++ b/xen/include/asm-x86/vmx_intercept.h	Thu Jun 30 08:07:49 2005 +0000
     4.3 @@ -1,4 +1,3 @@
     4.4 -
     4.5  #ifndef _VMX_INTERCEPT_H
     4.6  #define _VMX_INTERCEPT_H
     4.7  
     4.8 @@ -13,18 +12,45 @@
     4.9  
    4.10  typedef int (*intercept_action_t)(ioreq_t*);
    4.11  
    4.12 +enum {PORTIO, MMIO};
    4.13 +
    4.14  struct vmx_handler_t {
    4.15      int num_slot;
    4.16      struct {
    4.17          unsigned long       addr;
    4.18 +        int type;
    4.19          unsigned long       offset;
    4.20          intercept_action_t  action;
    4.21      } hdl_list[MAX_IO_HANDLER];
    4.22  };
    4.23  
    4.24  /* global io interception point in HV */
    4.25 -extern int vmx_io_intercept(ioreq_t*);
    4.26 -extern int register_io_handler(unsigned long, unsigned long, intercept_action_t);
    4.27 +extern int vmx_io_intercept(ioreq_t *p, int type);
    4.28 +extern int register_io_handler(unsigned long addr, unsigned long offset, 
    4.29 +                               intercept_action_t action, int type);
    4.30 +
    4.31 +static inline int vmx_portio_intercept(ioreq_t *p)
    4.32 +{
    4.33 +    return vmx_io_intercept(p, PORTIO);
    4.34 +}
    4.35 +
    4.36 +static inline int vmx_mmio_intercept(ioreq_t *p)
    4.37 +{
    4.38 +    return vmx_io_intercept(p, MMIO);
    4.39 +}
    4.40  
    4.41 +static inline int register_portio_handler(unsigned long addr, 
    4.42 +                                          unsigned long offset, 
    4.43 +                                          intercept_action_t action)
    4.44 +{
    4.45 +    return register_io_handler(addr, offset, action, PORTIO);
    4.46 +}
    4.47 +
    4.48 +static inline int register_mmio_handler(unsigned long addr, 
    4.49 +                                        unsigned long offset, 
    4.50 +                                        intercept_action_t action)
    4.51 +{
    4.52 +    return register_io_handler(addr, offset, action, MMIO);
    4.53 +}
    4.54  
    4.55  #endif /* _VMX_INTERCEPT_H */
     5.1 --- a/xen/include/asm-x86/vmx_platform.h	Thu Jun 30 08:07:29 2005 +0000
     5.2 +++ b/xen/include/asm-x86/vmx_platform.h	Thu Jun 30 08:07:49 2005 +0000
     5.3 @@ -88,6 +88,7 @@ struct virtual_platform_def {
     5.4  extern void handle_mmio(unsigned long, unsigned long);
     5.5  extern void vmx_wait_io(void);
     5.6  extern int vmx_setup_platform(struct vcpu *, struct cpu_user_regs *);
     5.7 +extern void vmx_io_assist(struct vcpu *v);
     5.8  
     5.9  // XXX - think about this -- maybe use bit 30 of the mfn to signify an MMIO frame.
    5.10  #define mmio_space(gpa) (!VALID_MFN(phys_to_machine_mapping((gpa) >> PAGE_SHIFT)))