ia64/xen-unstable

changeset 14750:40d4150764ad

Merge
author Tim Deegan <Tim.Deegan@xensource.com>
date Thu Apr 05 15:11:49 2007 +0100 (2007-04-05)
parents e518f2fbdd72 1a347b19142a
children e2fdfb0802bd 4d29476fc460
files
line diff
     1.1 --- a/.hgignore	Thu Apr 05 15:11:22 2007 +0100
     1.2 +++ b/.hgignore	Thu Apr 05 15:11:49 2007 +0100
     1.3 @@ -14,6 +14,7 @@
     1.4  .*\.orig$
     1.5  .*\.rej$
     1.6  .*/a\.out$
     1.7 +.*/Modules\.symvers$
     1.8  .*/cscope\..*$
     1.9  ^cscope.*$
    1.10  ^[^/]*\.bz2$
     2.1 --- a/docs/xen-api/xenapi-datamodel.tex	Thu Apr 05 15:11:22 2007 +0100
     2.2 +++ b/docs/xen-api/xenapi-datamodel.tex	Thu Apr 05 15:11:49 2007 +0100
     2.3 @@ -512,7 +512,6 @@ Quals & Field & Type & Description \\
     2.4  $\mathit{RO}_\mathit{run}$ &  {\tt progress} & int & if the task is still pending, this field contains the estimated percentage complete (0-100). If task has completed (successfully or unsuccessfully) this should be 100. \\
     2.5  $\mathit{RO}_\mathit{run}$ &  {\tt type} & string & if the task has completed successfully, this field contains the type of the encoded result (i.e. name of the class whose reference is in the result field). Undefined otherwise. \\
     2.6  $\mathit{RO}_\mathit{run}$ &  {\tt result} & string & if the task has completed successfully, this field contains the result value (either Void or an object reference). Undefined otherwise. \\
     2.7 -$\mathit{RO}_\mathit{run}$ &  {\tt error\_code} & int & if the task has failed, this field contains the error code. Undefined otherwise. \\
     2.8  $\mathit{RO}_\mathit{run}$ &  {\tt error\_info} & string Set & if the task has failed, this field contains the set of associated error strings. Undefined otherwise. \\
     2.9  $\mathit{RO}_\mathit{run}$ &  {\tt allowed\_operations} & (task\_allowed\_operations) Set & Operations allowed on this task \\
    2.10  \hline
    2.11 @@ -833,38 +832,6 @@ value of the field
    2.12  \vspace{0.3cm}
    2.13  \vspace{0.3cm}
    2.14  \vspace{0.3cm}
    2.15 -\subsubsection{RPC name:~get\_error\_code}
    2.16 -
    2.17 -{\bf Overview:} 
    2.18 -Get the error\_code field of the given task.
    2.19 -
    2.20 - \noindent {\bf Signature:} 
    2.21 -\begin{verbatim} int get_error_code (session_id s, task ref self)\end{verbatim}
    2.22 -
    2.23 -
    2.24 -\noindent{\bf Arguments:}
    2.25 -
    2.26 - 
    2.27 -\vspace{0.3cm}
    2.28 -\begin{tabular}{|c|c|p{7cm}|}
    2.29 - \hline
    2.30 -{\bf type} & {\bf name} & {\bf description} \\ \hline
    2.31 -{\tt task ref } & self & reference to the object \\ \hline 
    2.32 -
    2.33 -\end{tabular}
    2.34 -
    2.35 -\vspace{0.3cm}
    2.36 -
    2.37 - \noindent {\bf Return Type:} 
    2.38 -{\tt 
    2.39 -int
    2.40 -}
    2.41 -
    2.42 -
    2.43 -value of the field
    2.44 -\vspace{0.3cm}
    2.45 -\vspace{0.3cm}
    2.46 -\vspace{0.3cm}
    2.47  \subsubsection{RPC name:~get\_error\_info}
    2.48  
    2.49  {\bf Overview:} 
     3.1 --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S	Thu Apr 05 15:11:22 2007 +0100
     3.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S	Thu Apr 05 15:11:49 2007 +0100
     3.3 @@ -205,7 +205,6 @@ END(ret_from_fork)
     3.4   */
     3.5  	.macro _frame ref
     3.6  	CFI_STARTPROC simple
     3.7 -	CFI_SIGNAL_FRAME
     3.8  	CFI_DEF_CFA rsp,SS+8-\ref
     3.9  	/*CFI_REL_OFFSET ss,SS-\ref*/
    3.10  	CFI_REL_OFFSET rsp,RSP-\ref
    3.11 @@ -1198,7 +1197,7 @@ END(int3)
    3.12  
    3.13  ENTRY(overflow)
    3.14  	zeroentry do_overflow
    3.15 -END(debug)
    3.16 +END(overflow)
    3.17  
    3.18  ENTRY(bounds)
    3.19  	zeroentry do_bounds
     4.1 --- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c	Thu Apr 05 15:11:22 2007 +0100
     4.2 +++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c	Thu Apr 05 15:11:49 2007 +0100
     4.3 @@ -306,14 +306,6 @@ static int decrease_reservation(unsigned
     4.4  		balloon_append(pfn_to_page(pfn));
     4.5  	}
     4.6  
     4.7 -#ifndef CONFIG_XEN
     4.8 -	/* XXX Temporary hack. */
     4.9 -	{
    4.10 -		extern void xen_invalidate_foreign_mappings(void);
    4.11 -		xen_invalidate_foreign_mappings(); 
    4.12 -	}
    4.13 -#endif
    4.14 -
    4.15  	set_xen_guest_handle(reservation.extent_start, frame_list);
    4.16  	reservation.nr_extents   = nr_pages;
    4.17  	ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, &reservation);
     5.1 --- a/tools/ioemu/hw/xen_platform.c	Thu Apr 05 15:11:22 2007 +0100
     5.2 +++ b/tools/ioemu/hw/xen_platform.c	Thu Apr 05 15:11:49 2007 +0100
     5.3 @@ -29,16 +29,10 @@
     5.4  
     5.5  extern FILE *logfile;
     5.6  
     5.7 -static void platform_ioport_write(void *opaque, uint32_t addr, uint32_t val)
     5.8 -{
     5.9 -    if (val == 0)
    5.10 -        qemu_invalidate_map_cache();
    5.11 -}
    5.12 -
    5.13  static void platform_ioport_map(PCIDevice *pci_dev, int region_num,
    5.14                                  uint32_t addr, uint32_t size, int type)
    5.15  {
    5.16 -    register_ioport_write(addr, 1, 1, platform_ioport_write, NULL);
    5.17 +    /* nothing yet */
    5.18  }
    5.19  
    5.20  static uint32_t platform_mmio_read(void *opaque, target_phys_addr_t addr)
     6.1 --- a/tools/ioemu/target-i386-dm/helper2.c	Thu Apr 05 15:11:22 2007 +0100
     6.2 +++ b/tools/ioemu/target-i386-dm/helper2.c	Thu Apr 05 15:11:49 2007 +0100
     6.3 @@ -506,8 +506,11 @@ void __handle_ioreq(CPUState *env, ioreq
     6.4          cpu_ioreq_xchg(env, req);
     6.5          break;
     6.6      case IOREQ_TYPE_TIMEOFFSET:
     6.7 -	cpu_ioreq_timeoffset(env, req);
     6.8 -	break;
     6.9 +        cpu_ioreq_timeoffset(env, req);
    6.10 +        break;
    6.11 +    case IOREQ_TYPE_INVALIDATE:
    6.12 +        qemu_invalidate_map_cache();
    6.13 +        break;
    6.14      default:
    6.15          hw_error("Invalid ioreq type 0x%x\n", req->type);
    6.16      }
     7.1 --- a/tools/python/xen/xend/XendAPI.py	Thu Apr 05 15:11:22 2007 +0100
     7.2 +++ b/tools/python/xen/xend/XendAPI.py	Thu Apr 05 15:11:49 2007 +0100
     7.3 @@ -789,7 +789,6 @@ class XendAPI(object):
     7.4                      'progress',
     7.5                      'type',
     7.6                      'result',
     7.7 -                    'error_code',
     7.8                      'error_info',
     7.9                      'allowed_operations',
    7.10                      'session'
    7.11 @@ -824,10 +823,6 @@ class XendAPI(object):
    7.12          task = XendTaskManager.get_task(task_ref)
    7.13          return xen_api_success(task.result)
    7.14  
    7.15 -    def task_get_error_code(self, session, task_ref):
    7.16 -        task = XendTaskManager.get_task(task_ref)
    7.17 -        return xen_api_success(task.error_code)
    7.18 -
    7.19      def task_get_error_info(self, session, task_ref):
    7.20          task = XendTaskManager.get_task(task_ref)
    7.21          return xen_api_success(task.error_info)
     8.1 --- a/tools/python/xen/xend/XendTask.py	Thu Apr 05 15:11:22 2007 +0100
     8.2 +++ b/tools/python/xen/xend/XendTask.py	Thu Apr 05 15:11:49 2007 +0100
     8.3 @@ -24,7 +24,7 @@ class XendTask(threading.Thread):
     8.4      """Represents a Asynchronous Task used by Xen API.
     8.5  
     8.6      Basically proxies the callable object in a thread and returns the
     8.7 -    results via self.{type,result,error_code,error_info}.
     8.8 +    results via self.{type,result,error_info}.
     8.9  
    8.10      @cvar task_progress: Thread local storage for progress tracking.
    8.11                           It is a dict indexed by thread_id. Note that the
    8.12 @@ -71,7 +71,6 @@ class XendTask(threading.Thread):
    8.13          self.uuid = uuid
    8.14          
    8.15          self.result = None
    8.16 -        self.error_code = ''
    8.17          self.error_info = []
    8.18          
    8.19          self.name_label = label or func.__name__
    8.20 @@ -118,13 +117,11 @@ class XendTask(threading.Thread):
    8.21                  self.result = result['Value']
    8.22                  self.set_status(XEN_API_TASK_STATUS_TYPE[1])
    8.23              else:
    8.24 -                self.error_code = result['ErrorDescription'][0]
    8.25 -                self.error_info = result['ErrorDescription'][1:]
    8.26 +                self.error_info = result['ErrorDescription']
    8.27                  self.set_status(XEN_API_TASK_STATUS_TYPE[2])                
    8.28          except Exception, e:
    8.29              log.exception('Error running Async Task')
    8.30 -            self.error_code = 'INTERNAL ERROR'
    8.31 -            self.error_info = [str(e)]
    8.32 +            self.error_info = ['INTERNAL ERROR', str(e)]
    8.33              self.set_status(XEN_API_TASK_STATUS_TYPE[2])
    8.34  
    8.35          self.task_progress_lock.acquire()
    8.36 @@ -144,7 +141,6 @@ class XendTask(threading.Thread):
    8.37              'progress': self.get_progress(),
    8.38              'type': self.type,
    8.39              'result': self.result,
    8.40 -            'error_code': self.error_code,
    8.41              'error_info': self.error_info,
    8.42              'allowed_operations': {},
    8.43              'session': self.session,
     9.1 --- a/unmodified_drivers/linux-2.6/overrides.mk	Thu Apr 05 15:11:22 2007 +0100
     9.2 +++ b/unmodified_drivers/linux-2.6/overrides.mk	Thu Apr 05 15:11:49 2007 +0100
     9.3 @@ -4,7 +4,8 @@
     9.4  #
     9.5  # (i.e. we need the native config for things like -mregparm, but
     9.6  # a Xen kernel to find the right headers)
     9.7 -EXTRA_CFLAGS += -D__XEN_INTERFACE_VERSION__=0x00030202
     9.8 +EXTRA_CFLAGS += -D__XEN_INTERFACE_VERSION__=0x00030205
     9.9 +EXTRA_CFLAGS += -DCONFIG_XEN_COMPAT=0xffffff
    9.10  EXTRA_CFLAGS += -I$(M)/include -I$(M)/compat-include -DHAVE_XEN_PLATFORM_COMPAT_H
    9.11  ifeq ($(ARCH),ia64)
    9.12    EXTRA_CFLAGS += -DCONFIG_VMX_GUEST
    10.1 --- a/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c	Thu Apr 05 15:11:22 2007 +0100
    10.2 +++ b/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c	Thu Apr 05 15:11:49 2007 +0100
    10.3 @@ -208,14 +208,6 @@ static uint64_t get_callback_via(struct 
    10.4  		((uint64_t)(pin - 1) & 3));
    10.5  }
    10.6  
    10.7 -/* Invalidate foreign mappings (e.g., in qemu-based device model). */
    10.8 -static uint16_t invlmap_port;
    10.9 -void xen_invalidate_foreign_mappings(void)
   10.10 -{
   10.11 -	outb(0, invlmap_port);
   10.12 -}
   10.13 -EXPORT_SYMBOL(xen_invalidate_foreign_mappings);
   10.14 -
   10.15  static int __devinit platform_pci_init(struct pci_dev *pdev,
   10.16  				       const struct pci_device_id *ent)
   10.17  {
   10.18 @@ -240,8 +232,6 @@ static int __devinit platform_pci_init(s
   10.19  		return -ENOENT;
   10.20  	}
   10.21  
   10.22 -	invlmap_port = ioaddr;
   10.23 -
   10.24  	if (request_mem_region(mmio_addr, mmio_len, DRV_NAME) == NULL)
   10.25  	{
   10.26  		printk(KERN_ERR ":MEM I/O resource 0x%lx @ 0x%lx busy\n",
    11.1 --- a/xen/arch/x86/hvm/hvm.c	Thu Apr 05 15:11:22 2007 +0100
    11.2 +++ b/xen/arch/x86/hvm/hvm.c	Thu Apr 05 15:11:49 2007 +0100
    11.3 @@ -521,32 +521,19 @@ static hvm_hypercall_t *hvm_hypercall_ta
    11.4      HYPERCALL(hvm_op)
    11.5  };
    11.6  
    11.7 -int hvm_do_hypercall(struct cpu_user_regs *pregs)
    11.8 +static void __hvm_do_hypercall(struct cpu_user_regs *pregs)
    11.9  {
   11.10 -    if ( unlikely(ring_3(pregs)) )
   11.11 -    {
   11.12 -        pregs->eax = -EPERM;
   11.13 -        return 0;
   11.14 -    }
   11.15 -
   11.16      if ( (pregs->eax >= NR_hypercalls) || !hvm_hypercall_table[pregs->eax] )
   11.17      {
   11.18          if ( pregs->eax != __HYPERVISOR_grant_table_op )
   11.19              gdprintk(XENLOG_WARNING, "HVM vcpu %d:%d bad hypercall %d.\n",
   11.20                       current->domain->domain_id, current->vcpu_id, pregs->eax);
   11.21          pregs->eax = -ENOSYS;
   11.22 -        return 0;
   11.23 +        return;
   11.24      }
   11.25  
   11.26 -    /* Check for preemption: EIP will be modified from this dummy value. */
   11.27 -    pregs->eip = 0xF0F0F0FF;
   11.28 -
   11.29      pregs->eax = hvm_hypercall_table[pregs->eax](
   11.30          pregs->ebx, pregs->ecx, pregs->edx, pregs->esi, pregs->edi);
   11.31 -
   11.32 -    /* XXX: put fake IO instr here to inform the emulator to flush mapcache */
   11.33 -
   11.34 -    return (pregs->eip != 0xF0F0F0FF); /* preempted? */
   11.35  }
   11.36  
   11.37  #else /* defined(__x86_64__) */
   11.38 @@ -606,14 +593,8 @@ static hvm_hypercall_t *hvm_hypercall32_
   11.39      HYPERCALL(event_channel_op)
   11.40  };
   11.41  
   11.42 -int hvm_do_hypercall(struct cpu_user_regs *pregs)
   11.43 +static void __hvm_do_hypercall(struct cpu_user_regs *pregs)
   11.44  {
   11.45 -    if ( unlikely(ring_3(pregs)) )
   11.46 -    {
   11.47 -        pregs->rax = -EPERM;
   11.48 -        return 0;
   11.49 -    }
   11.50 -
   11.51      pregs->rax = (uint32_t)pregs->eax; /* mask in case compat32 caller */
   11.52      if ( (pregs->rax >= NR_hypercalls) || !hvm_hypercall64_table[pregs->rax] )
   11.53      {
   11.54 @@ -621,12 +602,9 @@ int hvm_do_hypercall(struct cpu_user_reg
   11.55              gdprintk(XENLOG_WARNING, "HVM vcpu %d:%d bad hypercall %ld.\n",
   11.56                       current->domain->domain_id, current->vcpu_id, pregs->rax);
   11.57          pregs->rax = -ENOSYS;
   11.58 -        return 0;
   11.59 +        return;
   11.60      }
   11.61  
   11.62 -    /* Check for preemption: RIP will be modified from this dummy value. */
   11.63 -    pregs->rip = 0xF0F0F0FF;
   11.64 -
   11.65      if ( current->arch.paging.mode->guest_levels == 4 )
   11.66      {
   11.67          pregs->rax = hvm_hypercall64_table[pregs->rax](pregs->rdi,
   11.68 @@ -643,14 +621,41 @@ int hvm_do_hypercall(struct cpu_user_reg
   11.69                                                         (uint32_t)pregs->esi,
   11.70                                                         (uint32_t)pregs->edi);
   11.71      }
   11.72 -
   11.73 -    /* XXX: put fake IO instr here to inform the emulator to flush mapcache */
   11.74 -
   11.75 -    return (pregs->rip != 0xF0F0F0FF); /* preempted? */
   11.76  }
   11.77  
   11.78  #endif /* defined(__x86_64__) */
   11.79  
   11.80 +int hvm_do_hypercall(struct cpu_user_regs *pregs)
   11.81 +{
   11.82 +    int flush, preempted;
   11.83 +    unsigned long old_eip;
   11.84 +
   11.85 +    if ( unlikely(ring_3(pregs)) )
   11.86 +    {
   11.87 +        pregs->eax = -EPERM;
   11.88 +        return 0;
   11.89 +    }
   11.90 +
   11.91 +    /*
   11.92 +     * NB. In future flush only on decrease_reservation.
   11.93 +     * For now we also need to flush when pages are added, as qemu-dm is not
   11.94 +     * yet capable of faulting pages into an existing valid mapcache bucket.
   11.95 +     */
   11.96 +    flush = ((uint32_t)pregs->eax == __HYPERVISOR_memory_op);
   11.97 +
   11.98 +    /* Check for preemption: RIP will be modified from this dummy value. */
   11.99 +    old_eip = pregs->eip;
  11.100 +    pregs->eip = 0xF0F0F0FF;
  11.101 +
  11.102 +    __hvm_do_hypercall(pregs);
  11.103 +
  11.104 +    preempted = (pregs->eip != 0xF0F0F0FF);
  11.105 +    pregs->eip = old_eip;
  11.106 +
  11.107 +    return (preempted ? HVM_HCALL_preempted :
  11.108 +            flush ? HVM_HCALL_invalidate : HVM_HCALL_completed);
  11.109 +}
  11.110 +
  11.111  void hvm_update_guest_cr3(struct vcpu *v, unsigned long guest_cr3)
  11.112  {
  11.113      v->arch.hvm_vcpu.hw_cr3 = guest_cr3;
    12.1 --- a/xen/arch/x86/hvm/io.c	Thu Apr 05 15:11:22 2007 +0100
    12.2 +++ b/xen/arch/x86/hvm/io.c	Thu Apr 05 15:11:49 2007 +0100
    12.3 @@ -845,10 +845,17 @@ void hvm_io_assist(void)
    12.4  
    12.5      p->state = STATE_IOREQ_NONE;
    12.6  
    12.7 -    if ( p->type == IOREQ_TYPE_PIO )
    12.8 +    switch ( p->type )
    12.9 +    {
   12.10 +    case IOREQ_TYPE_INVALIDATE:
   12.11 +        goto out;
   12.12 +    case IOREQ_TYPE_PIO:
   12.13          hvm_pio_assist(regs, p, io_opp);
   12.14 -    else
   12.15 +        break;
   12.16 +    default:
   12.17          hvm_mmio_assist(regs, p, io_opp);
   12.18 +        break;
   12.19 +    }
   12.20  
   12.21      /* Copy register changes back into current guest state. */
   12.22      hvm_load_cpu_guest_regs(v, regs);
   12.23 @@ -861,6 +868,7 @@ void hvm_io_assist(void)
   12.24          mark_dirty(d, gmfn);
   12.25      }
   12.26  
   12.27 + out:
   12.28      vcpu_end_shutdown_deferral(v);
   12.29  }
   12.30  
    13.1 --- a/xen/arch/x86/hvm/platform.c	Thu Apr 05 15:11:22 2007 +0100
    13.2 +++ b/xen/arch/x86/hvm/platform.c	Thu Apr 05 15:11:49 2007 +0100
    13.3 @@ -941,6 +941,34 @@ void send_timeoffset_req(unsigned long t
    13.4          printk("Unsuccessful timeoffset update\n");
    13.5  }
    13.6  
    13.7 +/* Ask ioemu mapcache to invalidate mappings. */
    13.8 +void send_invalidate_req(void)
    13.9 +{
   13.10 +    struct vcpu *v = current;
   13.11 +    vcpu_iodata_t *vio;
   13.12 +    ioreq_t *p;
   13.13 +
   13.14 +    vio = get_vio(v->domain, v->vcpu_id);
   13.15 +    if ( vio == NULL )
   13.16 +    {
   13.17 +        printk("bad shared page: %lx\n", (unsigned long) vio);
   13.18 +        domain_crash_synchronous();
   13.19 +    }
   13.20 +
   13.21 +    p = &vio->vp_ioreq;
   13.22 +    if ( p->state != STATE_IOREQ_NONE )
   13.23 +        printk("WARNING: send invalidate req with something "
   13.24 +               "already pending (%d)?\n", p->state);
   13.25 +
   13.26 +    p->type = IOREQ_TYPE_INVALIDATE;
   13.27 +    p->size = 4;
   13.28 +    p->dir = IOREQ_WRITE;
   13.29 +    p->data = ~0UL; /* flush all */
   13.30 +    p->io_count++;
   13.31 +
   13.32 +    hvm_send_assist_req(v);
   13.33 +}
   13.34 +
   13.35  static void mmio_operands(int type, unsigned long gpa,
   13.36                            struct hvm_io_op *mmio_op,
   13.37                            unsigned char op_size)
    14.1 --- a/xen/arch/x86/hvm/svm/svm.c	Thu Apr 05 15:11:22 2007 +0100
    14.2 +++ b/xen/arch/x86/hvm/svm/svm.c	Thu Apr 05 15:11:49 2007 +0100
    14.3 @@ -2166,7 +2166,7 @@ asmlinkage void svm_vmexit_handler(struc
    14.4      unsigned long eip;
    14.5      struct vcpu *v = current;
    14.6      struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
    14.7 -    int inst_len;
    14.8 +    int inst_len, rc;
    14.9  
   14.10      exit_reason = vmcb->exitcode;
   14.11      save_svm_cpu_user_regs(v, regs);
   14.12 @@ -2275,8 +2275,13 @@ asmlinkage void svm_vmexit_handler(struc
   14.13          inst_len = __get_instruction_length(v, INSTR_VMCALL, NULL);
   14.14          ASSERT(inst_len > 0);
   14.15          HVMTRACE_1D(VMMCALL, v, regs->eax);
   14.16 -        if ( !hvm_do_hypercall(regs) )
   14.17 -            __update_guest_eip(vmcb, inst_len); /* not preempted */
   14.18 +        rc = hvm_do_hypercall(regs);
   14.19 +        if ( rc != HVM_HCALL_preempted )
   14.20 +        {
   14.21 +            __update_guest_eip(vmcb, inst_len);
   14.22 +            if ( rc == HVM_HCALL_invalidate )
   14.23 +                send_invalidate_req();
   14.24 +        }
   14.25          break;
   14.26  
   14.27      case VMEXIT_CR0_READ:
    15.1 --- a/xen/arch/x86/hvm/vmx/vmx.c	Thu Apr 05 15:11:22 2007 +0100
    15.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c	Thu Apr 05 15:11:49 2007 +0100
    15.3 @@ -2626,10 +2626,16 @@ asmlinkage void vmx_vmexit_handler(struc
    15.4      }
    15.5      case EXIT_REASON_VMCALL:
    15.6      {
    15.7 +        int rc;
    15.8          HVMTRACE_1D(VMMCALL, v, regs->eax);
    15.9          inst_len = __get_instruction_length(); /* Safe: VMCALL */
   15.10 -        if ( !hvm_do_hypercall(regs) )
   15.11 -            __update_guest_eip(inst_len); /* not preempted */
   15.12 +        rc = hvm_do_hypercall(regs);
   15.13 +        if ( rc != HVM_HCALL_preempted )
   15.14 +        {
   15.15 +            __update_guest_eip(inst_len);
   15.16 +            if ( rc == HVM_HCALL_invalidate )
   15.17 +                send_invalidate_req();
   15.18 +        }
   15.19          break;
   15.20      }
   15.21      case EXIT_REASON_CR_ACCESS:
    16.1 --- a/xen/include/asm-x86/hvm/io.h	Thu Apr 05 15:11:22 2007 +0100
    16.2 +++ b/xen/include/asm-x86/hvm/io.h	Thu Apr 05 15:11:49 2007 +0100
    16.3 @@ -147,6 +147,7 @@ static inline int irq_masked(unsigned lo
    16.4  extern void send_pio_req(unsigned long port, unsigned long count, int size,
    16.5                           paddr_t value, int dir, int df, int value_is_ptr);
    16.6  void send_timeoffset_req(unsigned long timeoff);
    16.7 +void send_invalidate_req(void);
    16.8  extern void handle_mmio(unsigned long gpa);
    16.9  extern void hvm_interrupt_post(struct vcpu *v, int vector, int type);
   16.10  extern void hvm_io_assist(void);
    17.1 --- a/xen/include/asm-x86/hvm/support.h	Thu Apr 05 15:11:22 2007 +0100
    17.2 +++ b/xen/include/asm-x86/hvm/support.h	Thu Apr 05 15:11:49 2007 +0100
    17.3 @@ -228,6 +228,9 @@ int hvm_copy_from_guest_virt(void *buf, 
    17.4  void hvm_print_line(struct vcpu *v, const char c);
    17.5  void hlt_timer_fn(void *data);
    17.6  
    17.7 +#define HVM_HCALL_completed  0 /* hypercall completed - no further action */
    17.8 +#define HVM_HCALL_preempted  1 /* hypercall preempted - re-execute VMCALL */
    17.9 +#define HVM_HCALL_invalidate 2 /* invalidate ioemu-dm memory cache        */
   17.10  int hvm_do_hypercall(struct cpu_user_regs *pregs);
   17.11  
   17.12  void hvm_hlt(unsigned long rflags);
    18.1 --- a/xen/include/public/hvm/ioreq.h	Thu Apr 05 15:11:22 2007 +0100
    18.2 +++ b/xen/include/public/hvm/ioreq.h	Thu Apr 05 15:11:49 2007 +0100
    18.3 @@ -40,6 +40,7 @@
    18.4  #define IOREQ_TYPE_XCHG         5
    18.5  #define IOREQ_TYPE_ADD          6
    18.6  #define IOREQ_TYPE_TIMEOFFSET   7
    18.7 +#define IOREQ_TYPE_INVALIDATE   8 /* mapcache */
    18.8  
    18.9  /*
   18.10   * VMExit dispatcher should cooperate with instruction decoder to