xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 4/5] Xen/MCE: Abort live migration when vMCE occur
@ 2012-09-18 13:16 Liu, Jinsong
  2012-09-18 15:29 ` Christoph Egger
  2012-10-10  9:10 ` Ian Campbell
  0 siblings, 2 replies; 20+ messages in thread
From: Liu, Jinsong @ 2012-09-18 13:16 UTC (permalink / raw)
  To: Jan Beulich, xen-devel@lists.xensource.com
  Cc: keir@xen.org, Ian.Campbell@citrix.com

[-- Attachment #1: Type: text/plain, Size: 7958 bytes --]

Xen/MCE: Abort live migration when vMCE occur

This patch monitor the critical area of live migration (from vMCE point of view,
the copypages stage of migration is the critical area while other areas are not).

If a vMCE occur at the critical area of live migration, abort and try migration later.

Signed-off-by: Liu, Jinsong <jinsong.liu@intel.com>

diff -r f843ac6f93c9 tools/libxc/xc_domain.c
--- a/tools/libxc/xc_domain.c	Wed Sep 19 01:21:18 2012 +0800
+++ b/tools/libxc/xc_domain.c	Wed Sep 19 03:31:30 2012 +0800
@@ -283,6 +283,37 @@
     return ret;
 }
 
+/* Start vmce monitor */
+int xc_domain_vmce_monitor_strat(xc_interface *xch,
+                                 uint32_t domid)
+{
+    int ret;
+    DECLARE_DOMCTL;
+
+    domctl.cmd = XEN_DOMCTL_vmce_monitor_start;
+    domctl.domain = (domid_t)domid;
+    ret = do_domctl(xch, &domctl);
+
+    return ret ? -1 : 0;
+}
+
+/* End vmce monitor */
+int xc_domain_vmce_monitor_end(xc_interface *xch,
+                               uint32_t domid,
+                               signed char *vmce_while_monitor)
+{
+    int ret;
+    DECLARE_DOMCTL;
+
+    domctl.cmd = XEN_DOMCTL_vmce_monitor_end;
+    domctl.domain = (domid_t)domid;
+    ret = do_domctl(xch, &domctl);
+    if ( !ret )
+        *vmce_while_monitor = domctl.u.vmce_monitor.vmce_while_monitor;
+
+    return ret ? -1 : 0;
+}
+
 /* get info from hvm guest for save */
 int xc_domain_hvm_getcontext(xc_interface *xch,
                              uint32_t domid,
diff -r f843ac6f93c9 tools/libxc/xc_domain_save.c
--- a/tools/libxc/xc_domain_save.c	Wed Sep 19 01:21:18 2012 +0800
+++ b/tools/libxc/xc_domain_save.c	Wed Sep 19 03:31:30 2012 +0800
@@ -895,6 +895,8 @@
      */
     int compressing = 0;
 
+    signed char vmce_while_monitor = 0;
+
     int completed = 0;
 
     if ( hvm && !callbacks->switch_qemu_logdirty )
@@ -1109,6 +1111,12 @@
         goto out;
     }
 
+    if ( xc_domain_vmce_monitor_strat(xch, dom) )
+    {
+        PERROR("Error when start vmce monitor\n");
+        goto out;
+    }
+
   copypages:
 #define wrexact(fd, buf, len) write_buffer(xch, last_iter, ob, (fd), (buf), (len))
 #define wruncached(fd, live, buf, len) write_uncached(xch, last_iter, ob, (fd), (buf), (len))
@@ -1571,6 +1579,17 @@
 
     DPRINTF("All memory is saved\n");
 
+    if ( xc_domain_vmce_monitor_end(xch, dom, &vmce_while_monitor) )
+    {
+        PERROR("Error when end vmce monitor\n");
+        goto out;
+    }
+    else if ( vmce_while_monitor == -1 )
+    {
+        fprintf(stderr, "vMCE occurred, abort this time and try later.\n");
+        goto out;
+    }
+
     /* After last_iter, buffer the rest of pagebuf & tailbuf data into a
      * separate output buffer and flush it after the compressed page chunks.
      */
diff -r f843ac6f93c9 tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h	Wed Sep 19 01:21:18 2012 +0800
+++ b/tools/libxc/xenctrl.h	Wed Sep 19 03:31:30 2012 +0800
@@ -571,6 +571,26 @@
                           xc_domaininfo_t *info);
 
 /**
+ * This function start monitor vmce event.
+ * @parm xch a handle to an open hypervisor interface
+ * @parm domid the domain id monitored
+ * @return 0 on success, -1 on failure
+ */
+int xc_domain_vmce_monitor_strat(xc_interface *xch,
+                                 uint32_t domid);
+
+/**
+ * This function end monitor vmce event
+ * @parm xch a handle to an open hypervisor interface
+ * @parm domid the domain id monitored
+ * @parm vmce_while_migrate a pointer return whether vMCE occur when migrate 
+ * @return 0 on success, -1 on failure
+ */
+int xc_domain_vmce_monitor_end(xc_interface *xch,
+                               uint32_t domid,
+                               signed char *vmce_while_monitor);
+
+/**
  * This function returns information about the context of a hvm domain
  * @parm xch a handle to an open hypervisor interface
  * @parm domid the domain to get information from
diff -r f843ac6f93c9 xen/arch/x86/cpu/mcheck/mce_intel.c
--- a/xen/arch/x86/cpu/mcheck/mce_intel.c	Wed Sep 19 01:21:18 2012 +0800
+++ b/xen/arch/x86/cpu/mcheck/mce_intel.c	Wed Sep 19 03:31:30 2012 +0800
@@ -596,6 +596,12 @@
                     goto vmce_failed;
                 }
 
+                if ( unlikely(d->arch.vmce_monitor) )
+                {
+                    /* vMCE occur when guest migration */
+                    d->arch.vmce_monitor = -1;
+                }
+
                 /* We will inject vMCE to DOMU*/
                 if ( inject_vmce(d) < 0 )
                 {
diff -r f843ac6f93c9 xen/arch/x86/domctl.c
--- a/xen/arch/x86/domctl.c	Wed Sep 19 01:21:18 2012 +0800
+++ b/xen/arch/x86/domctl.c	Wed Sep 19 03:31:30 2012 +0800
@@ -1514,6 +1514,40 @@
     }
     break;
 
+    case XEN_DOMCTL_vmce_monitor_start:
+    {
+        struct domain *d;
+
+        d = rcu_lock_domain_by_id(domctl->domain);
+        if ( d != NULL )
+        {
+            d->arch.vmce_monitor = 1;
+            rcu_unlock_domain(d);
+        }
+        else
+            ret = -ESRCH;
+    }
+    break;
+
+    case XEN_DOMCTL_vmce_monitor_end:
+    {
+        struct domain *d;
+
+        d = rcu_lock_domain_by_id(domctl->domain);
+        if ( d != NULL)
+        {
+            domctl->u.vmce_monitor.vmce_while_monitor =
+                                      d->arch.vmce_monitor;
+            d->arch.vmce_monitor = 0;
+            rcu_unlock_domain(d);
+            if ( copy_to_guest(u_domctl, domctl, 1) )
+                ret = -EFAULT;
+        }
+        else
+            ret = -ESRCH;
+    }
+    break;
+
     default:
         ret = iommu_do_domctl(domctl, u_domctl);
         break;
diff -r f843ac6f93c9 xen/include/asm-x86/domain.h
--- a/xen/include/asm-x86/domain.h	Wed Sep 19 01:21:18 2012 +0800
+++ b/xen/include/asm-x86/domain.h	Wed Sep 19 03:31:30 2012 +0800
@@ -279,6 +279,11 @@
     bool_t has_32bit_shinfo;
     /* Domain cannot handle spurious page faults? */
     bool_t suppress_spurious_page_faults;
+    /* Monitoring guest memory copy of migration
+     * = 0 - not monitoring
+     * > 0 - monitoring
+     * < 0 - vMCE occurred while monitoring */
+    s8 vmce_monitor;
 
     /* Continuable domain_relinquish_resources(). */
     enum {
diff -r f843ac6f93c9 xen/include/public/domctl.h
--- a/xen/include/public/domctl.h	Wed Sep 19 01:21:18 2012 +0800
+++ b/xen/include/public/domctl.h	Wed Sep 19 03:31:30 2012 +0800
@@ -828,6 +828,12 @@
 typedef struct xen_domctl_set_access_required xen_domctl_set_access_required_t;
 DEFINE_XEN_GUEST_HANDLE(xen_domctl_set_access_required_t);
 
+struct xen_domctl_vmce_monitor {
+    signed char vmce_while_monitor;
+};
+typedef struct xen_domctl_vmce_monitor xen_domctl_vmce_monitor_t;
+DEFINE_XEN_GUEST_HANDLE(xen_domctl_vmce_monitor_t);
+
 struct xen_domctl {
     uint32_t cmd;
 #define XEN_DOMCTL_createdomain                   1
@@ -893,6 +899,8 @@
 #define XEN_DOMCTL_set_access_required           64
 #define XEN_DOMCTL_audit_p2m                     65
 #define XEN_DOMCTL_set_virq_handler              66
+#define XEN_DOMCTL_vmce_monitor_start            67
+#define XEN_DOMCTL_vmce_monitor_end              68
 #define XEN_DOMCTL_gdbsx_guestmemio            1000
 #define XEN_DOMCTL_gdbsx_pausevcpu             1001
 #define XEN_DOMCTL_gdbsx_unpausevcpu           1002
@@ -947,6 +955,7 @@
         struct xen_domctl_set_access_required access_required;
         struct xen_domctl_audit_p2m         audit_p2m;
         struct xen_domctl_set_virq_handler  set_virq_handler;
+        struct xen_domctl_vmce_monitor      vmce_monitor;
         struct xen_domctl_gdbsx_memio       gdbsx_guest_memio;
         struct xen_domctl_gdbsx_pauseunp_vcpu gdbsx_pauseunp_vcpu;
         struct xen_domctl_gdbsx_domstatus   gdbsx_domstatus;

[-- Attachment #2: 4_vmce_when_migrate.patch --]
[-- Type: application/octet-stream, Size: 7729 bytes --]

Xen/MCE: Abort live migration when vMCE occur

This patch monitor the critical area of live migration (from vMCE point of view,
the copypages stage of migration is the critical area while other areas are not).

If a vMCE occur at the critical area of live migration, abort and try migration later.

Signed-off-by: Liu, Jinsong <jinsong.liu@intel.com>

diff -r f843ac6f93c9 tools/libxc/xc_domain.c
--- a/tools/libxc/xc_domain.c	Wed Sep 19 01:21:18 2012 +0800
+++ b/tools/libxc/xc_domain.c	Wed Sep 19 03:31:30 2012 +0800
@@ -283,6 +283,37 @@
     return ret;
 }
 
+/* Start vmce monitor */
+int xc_domain_vmce_monitor_strat(xc_interface *xch,
+                                 uint32_t domid)
+{
+    int ret;
+    DECLARE_DOMCTL;
+
+    domctl.cmd = XEN_DOMCTL_vmce_monitor_start;
+    domctl.domain = (domid_t)domid;
+    ret = do_domctl(xch, &domctl);
+
+    return ret ? -1 : 0;
+}
+
+/* End vmce monitor */
+int xc_domain_vmce_monitor_end(xc_interface *xch,
+                               uint32_t domid,
+                               signed char *vmce_while_monitor)
+{
+    int ret;
+    DECLARE_DOMCTL;
+
+    domctl.cmd = XEN_DOMCTL_vmce_monitor_end;
+    domctl.domain = (domid_t)domid;
+    ret = do_domctl(xch, &domctl);
+    if ( !ret )
+        *vmce_while_monitor = domctl.u.vmce_monitor.vmce_while_monitor;
+
+    return ret ? -1 : 0;
+}
+
 /* get info from hvm guest for save */
 int xc_domain_hvm_getcontext(xc_interface *xch,
                              uint32_t domid,
diff -r f843ac6f93c9 tools/libxc/xc_domain_save.c
--- a/tools/libxc/xc_domain_save.c	Wed Sep 19 01:21:18 2012 +0800
+++ b/tools/libxc/xc_domain_save.c	Wed Sep 19 03:31:30 2012 +0800
@@ -895,6 +895,8 @@
      */
     int compressing = 0;
 
+    signed char vmce_while_monitor = 0;
+
     int completed = 0;
 
     if ( hvm && !callbacks->switch_qemu_logdirty )
@@ -1109,6 +1111,12 @@
         goto out;
     }
 
+    if ( xc_domain_vmce_monitor_strat(xch, dom) )
+    {
+        PERROR("Error when start vmce monitor\n");
+        goto out;
+    }
+
   copypages:
 #define wrexact(fd, buf, len) write_buffer(xch, last_iter, ob, (fd), (buf), (len))
 #define wruncached(fd, live, buf, len) write_uncached(xch, last_iter, ob, (fd), (buf), (len))
@@ -1571,6 +1579,17 @@
 
     DPRINTF("All memory is saved\n");
 
+    if ( xc_domain_vmce_monitor_end(xch, dom, &vmce_while_monitor) )
+    {
+        PERROR("Error when end vmce monitor\n");
+        goto out;
+    }
+    else if ( vmce_while_monitor == -1 )
+    {
+        fprintf(stderr, "vMCE occurred, abort this time and try later.\n");
+        goto out;
+    }
+
     /* After last_iter, buffer the rest of pagebuf & tailbuf data into a
      * separate output buffer and flush it after the compressed page chunks.
      */
diff -r f843ac6f93c9 tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h	Wed Sep 19 01:21:18 2012 +0800
+++ b/tools/libxc/xenctrl.h	Wed Sep 19 03:31:30 2012 +0800
@@ -571,6 +571,26 @@
                           xc_domaininfo_t *info);
 
 /**
+ * This function start monitor vmce event.
+ * @parm xch a handle to an open hypervisor interface
+ * @parm domid the domain id monitored
+ * @return 0 on success, -1 on failure
+ */
+int xc_domain_vmce_monitor_strat(xc_interface *xch,
+                                 uint32_t domid);
+
+/**
+ * This function end monitor vmce event
+ * @parm xch a handle to an open hypervisor interface
+ * @parm domid the domain id monitored
+ * @parm vmce_while_migrate a pointer return whether vMCE occur when migrate 
+ * @return 0 on success, -1 on failure
+ */
+int xc_domain_vmce_monitor_end(xc_interface *xch,
+                               uint32_t domid,
+                               signed char *vmce_while_monitor);
+
+/**
  * This function returns information about the context of a hvm domain
  * @parm xch a handle to an open hypervisor interface
  * @parm domid the domain to get information from
diff -r f843ac6f93c9 xen/arch/x86/cpu/mcheck/mce_intel.c
--- a/xen/arch/x86/cpu/mcheck/mce_intel.c	Wed Sep 19 01:21:18 2012 +0800
+++ b/xen/arch/x86/cpu/mcheck/mce_intel.c	Wed Sep 19 03:31:30 2012 +0800
@@ -596,6 +596,12 @@
                     goto vmce_failed;
                 }
 
+                if ( unlikely(d->arch.vmce_monitor) )
+                {
+                    /* vMCE occur when guest migration */
+                    d->arch.vmce_monitor = -1;
+                }
+
                 /* We will inject vMCE to DOMU*/
                 if ( inject_vmce(d) < 0 )
                 {
diff -r f843ac6f93c9 xen/arch/x86/domctl.c
--- a/xen/arch/x86/domctl.c	Wed Sep 19 01:21:18 2012 +0800
+++ b/xen/arch/x86/domctl.c	Wed Sep 19 03:31:30 2012 +0800
@@ -1514,6 +1514,40 @@
     }
     break;
 
+    case XEN_DOMCTL_vmce_monitor_start:
+    {
+        struct domain *d;
+
+        d = rcu_lock_domain_by_id(domctl->domain);
+        if ( d != NULL )
+        {
+            d->arch.vmce_monitor = 1;
+            rcu_unlock_domain(d);
+        }
+        else
+            ret = -ESRCH;
+    }
+    break;
+
+    case XEN_DOMCTL_vmce_monitor_end:
+    {
+        struct domain *d;
+
+        d = rcu_lock_domain_by_id(domctl->domain);
+        if ( d != NULL)
+        {
+            domctl->u.vmce_monitor.vmce_while_monitor =
+                                      d->arch.vmce_monitor;
+            d->arch.vmce_monitor = 0;
+            rcu_unlock_domain(d);
+            if ( copy_to_guest(u_domctl, domctl, 1) )
+                ret = -EFAULT;
+        }
+        else
+            ret = -ESRCH;
+    }
+    break;
+
     default:
         ret = iommu_do_domctl(domctl, u_domctl);
         break;
diff -r f843ac6f93c9 xen/include/asm-x86/domain.h
--- a/xen/include/asm-x86/domain.h	Wed Sep 19 01:21:18 2012 +0800
+++ b/xen/include/asm-x86/domain.h	Wed Sep 19 03:31:30 2012 +0800
@@ -279,6 +279,11 @@
     bool_t has_32bit_shinfo;
     /* Domain cannot handle spurious page faults? */
     bool_t suppress_spurious_page_faults;
+    /* Monitoring guest memory copy of migration
+     * = 0 - not monitoring
+     * > 0 - monitoring
+     * < 0 - vMCE occurred while monitoring */
+    s8 vmce_monitor;
 
     /* Continuable domain_relinquish_resources(). */
     enum {
diff -r f843ac6f93c9 xen/include/public/domctl.h
--- a/xen/include/public/domctl.h	Wed Sep 19 01:21:18 2012 +0800
+++ b/xen/include/public/domctl.h	Wed Sep 19 03:31:30 2012 +0800
@@ -828,6 +828,12 @@
 typedef struct xen_domctl_set_access_required xen_domctl_set_access_required_t;
 DEFINE_XEN_GUEST_HANDLE(xen_domctl_set_access_required_t);
 
+struct xen_domctl_vmce_monitor {
+    signed char vmce_while_monitor;
+};
+typedef struct xen_domctl_vmce_monitor xen_domctl_vmce_monitor_t;
+DEFINE_XEN_GUEST_HANDLE(xen_domctl_vmce_monitor_t);
+
 struct xen_domctl {
     uint32_t cmd;
 #define XEN_DOMCTL_createdomain                   1
@@ -893,6 +899,8 @@
 #define XEN_DOMCTL_set_access_required           64
 #define XEN_DOMCTL_audit_p2m                     65
 #define XEN_DOMCTL_set_virq_handler              66
+#define XEN_DOMCTL_vmce_monitor_start            67
+#define XEN_DOMCTL_vmce_monitor_end              68
 #define XEN_DOMCTL_gdbsx_guestmemio            1000
 #define XEN_DOMCTL_gdbsx_pausevcpu             1001
 #define XEN_DOMCTL_gdbsx_unpausevcpu           1002
@@ -947,6 +955,7 @@
         struct xen_domctl_set_access_required access_required;
         struct xen_domctl_audit_p2m         audit_p2m;
         struct xen_domctl_set_virq_handler  set_virq_handler;
+        struct xen_domctl_vmce_monitor      vmce_monitor;
         struct xen_domctl_gdbsx_memio       gdbsx_guest_memio;
         struct xen_domctl_gdbsx_pauseunp_vcpu gdbsx_pauseunp_vcpu;
         struct xen_domctl_gdbsx_domstatus   gdbsx_domstatus;

[-- Attachment #3: Type: text/plain, Size: 126 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 4/5] Xen/MCE: Abort live migration when vMCE occur
  2012-09-18 13:16 [PATCH 4/5] Xen/MCE: Abort live migration when vMCE occur Liu, Jinsong
@ 2012-09-18 15:29 ` Christoph Egger
  2012-09-19  7:52   ` Liu, Jinsong
  2012-10-10  9:10 ` Ian Campbell
  1 sibling, 1 reply; 20+ messages in thread
From: Christoph Egger @ 2012-09-18 15:29 UTC (permalink / raw)
  To: Liu, Jinsong
  Cc: xen-devel@lists.xensource.com, keir@xen.org,
	Ian.Campbell@citrix.com, Jan Beulich


Does this patch still apply after c/s 25919:62de66cec48a?

Christoph


On 09/18/12 15:16, Liu, Jinsong wrote:

> Xen/MCE: Abort live migration when vMCE occur
> 
> This patch monitor the critical area of live migration (from vMCE point of view,
> the copypages stage of migration is the critical area while other areas are not).
> 
> If a vMCE occur at the critical area of live migration, abort and try migration later.
> 
> Signed-off-by: Liu, Jinsong <jinsong.liu@intel.com>
> 
> diff -r f843ac6f93c9 tools/libxc/xc_domain.c
> --- a/tools/libxc/xc_domain.c	Wed Sep 19 01:21:18 2012 +0800
> +++ b/tools/libxc/xc_domain.c	Wed Sep 19 03:31:30 2012 +0800
> @@ -283,6 +283,37 @@
>      return ret;
>  }
>  
> +/* Start vmce monitor */
> +int xc_domain_vmce_monitor_strat(xc_interface *xch,
> +                                 uint32_t domid)
> +{
> +    int ret;
> +    DECLARE_DOMCTL;
> +
> +    domctl.cmd = XEN_DOMCTL_vmce_monitor_start;
> +    domctl.domain = (domid_t)domid;
> +    ret = do_domctl(xch, &domctl);
> +
> +    return ret ? -1 : 0;
> +}
> +
> +/* End vmce monitor */
> +int xc_domain_vmce_monitor_end(xc_interface *xch,
> +                               uint32_t domid,
> +                               signed char *vmce_while_monitor)
> +{
> +    int ret;
> +    DECLARE_DOMCTL;
> +
> +    domctl.cmd = XEN_DOMCTL_vmce_monitor_end;
> +    domctl.domain = (domid_t)domid;
> +    ret = do_domctl(xch, &domctl);
> +    if ( !ret )
> +        *vmce_while_monitor = domctl.u.vmce_monitor.vmce_while_monitor;
> +
> +    return ret ? -1 : 0;
> +}
> +
>  /* get info from hvm guest for save */
>  int xc_domain_hvm_getcontext(xc_interface *xch,
>                               uint32_t domid,
> diff -r f843ac6f93c9 tools/libxc/xc_domain_save.c
> --- a/tools/libxc/xc_domain_save.c	Wed Sep 19 01:21:18 2012 +0800
> +++ b/tools/libxc/xc_domain_save.c	Wed Sep 19 03:31:30 2012 +0800
> @@ -895,6 +895,8 @@
>       */
>      int compressing = 0;
>  
> +    signed char vmce_while_monitor = 0;
> +
>      int completed = 0;
>  
>      if ( hvm && !callbacks->switch_qemu_logdirty )
> @@ -1109,6 +1111,12 @@
>          goto out;
>      }
>  
> +    if ( xc_domain_vmce_monitor_strat(xch, dom) )
> +    {
> +        PERROR("Error when start vmce monitor\n");
> +        goto out;
> +    }
> +
>    copypages:
>  #define wrexact(fd, buf, len) write_buffer(xch, last_iter, ob, (fd), (buf), (len))
>  #define wruncached(fd, live, buf, len) write_uncached(xch, last_iter, ob, (fd), (buf), (len))
> @@ -1571,6 +1579,17 @@
>  
>      DPRINTF("All memory is saved\n");
>  
> +    if ( xc_domain_vmce_monitor_end(xch, dom, &vmce_while_monitor) )
> +    {
> +        PERROR("Error when end vmce monitor\n");
> +        goto out;
> +    }
> +    else if ( vmce_while_monitor == -1 )
> +    {
> +        fprintf(stderr, "vMCE occurred, abort this time and try later.\n");
> +        goto out;
> +    }
> +
>      /* After last_iter, buffer the rest of pagebuf & tailbuf data into a
>       * separate output buffer and flush it after the compressed page chunks.
>       */
> diff -r f843ac6f93c9 tools/libxc/xenctrl.h
> --- a/tools/libxc/xenctrl.h	Wed Sep 19 01:21:18 2012 +0800
> +++ b/tools/libxc/xenctrl.h	Wed Sep 19 03:31:30 2012 +0800
> @@ -571,6 +571,26 @@
>                            xc_domaininfo_t *info);
>  
>  /**
> + * This function start monitor vmce event.
> + * @parm xch a handle to an open hypervisor interface
> + * @parm domid the domain id monitored
> + * @return 0 on success, -1 on failure
> + */
> +int xc_domain_vmce_monitor_strat(xc_interface *xch,
> +                                 uint32_t domid);
> +
> +/**
> + * This function end monitor vmce event
> + * @parm xch a handle to an open hypervisor interface
> + * @parm domid the domain id monitored
> + * @parm vmce_while_migrate a pointer return whether vMCE occur when migrate 
> + * @return 0 on success, -1 on failure
> + */
> +int xc_domain_vmce_monitor_end(xc_interface *xch,
> +                               uint32_t domid,
> +                               signed char *vmce_while_monitor);
> +
> +/**
>   * This function returns information about the context of a hvm domain
>   * @parm xch a handle to an open hypervisor interface
>   * @parm domid the domain to get information from
> diff -r f843ac6f93c9 xen/arch/x86/cpu/mcheck/mce_intel.c
> --- a/xen/arch/x86/cpu/mcheck/mce_intel.c	Wed Sep 19 01:21:18 2012 +0800
> +++ b/xen/arch/x86/cpu/mcheck/mce_intel.c	Wed Sep 19 03:31:30 2012 +0800
> @@ -596,6 +596,12 @@
>                      goto vmce_failed;
>                  }
>  
> +                if ( unlikely(d->arch.vmce_monitor) )
> +                {
> +                    /* vMCE occur when guest migration */
> +                    d->arch.vmce_monitor = -1;
> +                }
> +
>                  /* We will inject vMCE to DOMU*/
>                  if ( inject_vmce(d) < 0 )
>                  {
> diff -r f843ac6f93c9 xen/arch/x86/domctl.c
> --- a/xen/arch/x86/domctl.c	Wed Sep 19 01:21:18 2012 +0800
> +++ b/xen/arch/x86/domctl.c	Wed Sep 19 03:31:30 2012 +0800
> @@ -1514,6 +1514,40 @@
>      }
>      break;
>  
> +    case XEN_DOMCTL_vmce_monitor_start:
> +    {
> +        struct domain *d;
> +
> +        d = rcu_lock_domain_by_id(domctl->domain);
> +        if ( d != NULL )
> +        {
> +            d->arch.vmce_monitor = 1;
> +            rcu_unlock_domain(d);
> +        }
> +        else
> +            ret = -ESRCH;
> +    }
> +    break;
> +
> +    case XEN_DOMCTL_vmce_monitor_end:
> +    {
> +        struct domain *d;
> +
> +        d = rcu_lock_domain_by_id(domctl->domain);
> +        if ( d != NULL)
> +        {
> +            domctl->u.vmce_monitor.vmce_while_monitor =
> +                                      d->arch.vmce_monitor;
> +            d->arch.vmce_monitor = 0;
> +            rcu_unlock_domain(d);
> +            if ( copy_to_guest(u_domctl, domctl, 1) )
> +                ret = -EFAULT;
> +        }
> +        else
> +            ret = -ESRCH;
> +    }
> +    break;
> +
>      default:
>          ret = iommu_do_domctl(domctl, u_domctl);
>          break;
> diff -r f843ac6f93c9 xen/include/asm-x86/domain.h
> --- a/xen/include/asm-x86/domain.h	Wed Sep 19 01:21:18 2012 +0800
> +++ b/xen/include/asm-x86/domain.h	Wed Sep 19 03:31:30 2012 +0800
> @@ -279,6 +279,11 @@
>      bool_t has_32bit_shinfo;
>      /* Domain cannot handle spurious page faults? */
>      bool_t suppress_spurious_page_faults;
> +    /* Monitoring guest memory copy of migration
> +     * = 0 - not monitoring
> +     * > 0 - monitoring
> +     * < 0 - vMCE occurred while monitoring */
> +    s8 vmce_monitor;
>  
>      /* Continuable domain_relinquish_resources(). */
>      enum {
> diff -r f843ac6f93c9 xen/include/public/domctl.h
> --- a/xen/include/public/domctl.h	Wed Sep 19 01:21:18 2012 +0800
> +++ b/xen/include/public/domctl.h	Wed Sep 19 03:31:30 2012 +0800
> @@ -828,6 +828,12 @@
>  typedef struct xen_domctl_set_access_required xen_domctl_set_access_required_t;
>  DEFINE_XEN_GUEST_HANDLE(xen_domctl_set_access_required_t);
>  
> +struct xen_domctl_vmce_monitor {
> +    signed char vmce_while_monitor;
> +};
> +typedef struct xen_domctl_vmce_monitor xen_domctl_vmce_monitor_t;
> +DEFINE_XEN_GUEST_HANDLE(xen_domctl_vmce_monitor_t);
> +
>  struct xen_domctl {
>      uint32_t cmd;
>  #define XEN_DOMCTL_createdomain                   1
> @@ -893,6 +899,8 @@
>  #define XEN_DOMCTL_set_access_required           64
>  #define XEN_DOMCTL_audit_p2m                     65
>  #define XEN_DOMCTL_set_virq_handler              66
> +#define XEN_DOMCTL_vmce_monitor_start            67
> +#define XEN_DOMCTL_vmce_monitor_end              68
>  #define XEN_DOMCTL_gdbsx_guestmemio            1000
>  #define XEN_DOMCTL_gdbsx_pausevcpu             1001
>  #define XEN_DOMCTL_gdbsx_unpausevcpu           1002
> @@ -947,6 +955,7 @@
>          struct xen_domctl_set_access_required access_required;
>          struct xen_domctl_audit_p2m         audit_p2m;
>          struct xen_domctl_set_virq_handler  set_virq_handler;
> +        struct xen_domctl_vmce_monitor      vmce_monitor;
>          struct xen_domctl_gdbsx_memio       gdbsx_guest_memio;
>          struct xen_domctl_gdbsx_pauseunp_vcpu gdbsx_pauseunp_vcpu;
>          struct xen_domctl_gdbsx_domstatus   gdbsx_domstatus;



-- 
---to satisfy European Law for business letters:
Advanced Micro Devices GmbH
Einsteinring 24, 85689 Dornach b. Muenchen
Geschaeftsfuehrer: Alberto Bozzo
Sitz: Dornach, Gemeinde Aschheim, Landkreis Muenchen
Registergericht Muenchen, HRB Nr. 43632

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 4/5] Xen/MCE: Abort live migration when vMCE occur
  2012-09-18 15:29 ` Christoph Egger
@ 2012-09-19  7:52   ` Liu, Jinsong
  0 siblings, 0 replies; 20+ messages in thread
From: Liu, Jinsong @ 2012-09-19  7:52 UTC (permalink / raw)
  To: Christoph Egger
  Cc: xen-devel@lists.xensource.com, keir@xen.org,
	Ian.Campbell@citrix.com, Jan Beulich

Hmm, it conflict with c/s 25919.
I have rebased again, will send out later, thanks for remind!

Regards,
Jinsong

Christoph Egger wrote:
> Does this patch still apply after c/s 25919:62de66cec48a?
> 
> Christoph
> 
> 
> On 09/18/12 15:16, Liu, Jinsong wrote:
> 
>> Xen/MCE: Abort live migration when vMCE occur
>> 
>> This patch monitor the critical area of live migration (from vMCE
>> point of view, 
>> the copypages stage of migration is the critical area while other
>> areas are not). 
>> 
>> If a vMCE occur at the critical area of live migration, abort and
>> try migration later. 
>> 
>> Signed-off-by: Liu, Jinsong <jinsong.liu@intel.com>
>> 
>> diff -r f843ac6f93c9 tools/libxc/xc_domain.c
>> --- a/tools/libxc/xc_domain.c	Wed Sep 19 01:21:18 2012 +0800
>> +++ b/tools/libxc/xc_domain.c	Wed Sep 19 03:31:30 2012 +0800 @@
>>      -283,6 +283,37 @@ return ret;
>>  }
>> 
>> +/* Start vmce monitor */
>> +int xc_domain_vmce_monitor_strat(xc_interface *xch,
>> +                                 uint32_t domid)
>> +{
>> +    int ret;
>> +    DECLARE_DOMCTL;
>> +
>> +    domctl.cmd = XEN_DOMCTL_vmce_monitor_start;
>> +    domctl.domain = (domid_t)domid;
>> +    ret = do_domctl(xch, &domctl);
>> +
>> +    return ret ? -1 : 0;
>> +}
>> +
>> +/* End vmce monitor */
>> +int xc_domain_vmce_monitor_end(xc_interface *xch,
>> +                               uint32_t domid,
>> +                               signed char *vmce_while_monitor) +{
>> +    int ret;
>> +    DECLARE_DOMCTL;
>> +
>> +    domctl.cmd = XEN_DOMCTL_vmce_monitor_end;
>> +    domctl.domain = (domid_t)domid;
>> +    ret = do_domctl(xch, &domctl);
>> +    if ( !ret )
>> +        *vmce_while_monitor =
>> domctl.u.vmce_monitor.vmce_while_monitor; + +    return ret ? -1 : 0;
>> +}
>> +
>>  /* get info from hvm guest for save */
>>  int xc_domain_hvm_getcontext(xc_interface *xch,
>>                               uint32_t domid,
>> diff -r f843ac6f93c9 tools/libxc/xc_domain_save.c
>> --- a/tools/libxc/xc_domain_save.c	Wed Sep 19 01:21:18 2012 +0800
>> +++ b/tools/libxc/xc_domain_save.c	Wed Sep 19 03:31:30 2012 +0800 @@
>>       -895,6 +895,8 @@ */
>>      int compressing = 0;
>> 
>> +    signed char vmce_while_monitor = 0;
>> +
>>      int completed = 0;
>> 
>>      if ( hvm && !callbacks->switch_qemu_logdirty ) @@ -1109,6
>>          +1111,12 @@ goto out;
>>      }
>> 
>> +    if ( xc_domain_vmce_monitor_strat(xch, dom) )
>> +    {
>> +        PERROR("Error when start vmce monitor\n"); +        goto
>> out; +    }
>> +
>>    copypages:
>>  #define wrexact(fd, buf, len) write_buffer(xch, last_iter, ob,
>>  (fd), (buf), (len)) #define wruncached(fd, live, buf, len)
>> write_uncached(xch, last_iter, ob, (fd), (buf), (len)) @@ -1571,6
>> +1579,17 @@  
>> 
>>      DPRINTF("All memory is saved\n");
>> 
>> +    if ( xc_domain_vmce_monitor_end(xch, dom, &vmce_while_monitor)
>> ) +    { +        PERROR("Error when end vmce monitor\n");
>> +        goto out;
>> +    }
>> +    else if ( vmce_while_monitor == -1 )
>> +    {
>> +        fprintf(stderr, "vMCE occurred, abort this time and try
>> later.\n"); +        goto out; +    }
>> +
>>      /* After last_iter, buffer the rest of pagebuf & tailbuf data
>>       into a * separate output buffer and flush it after the
>> compressed page chunks.       */ 
>> diff -r f843ac6f93c9 tools/libxc/xenctrl.h
>> --- a/tools/libxc/xenctrl.h	Wed Sep 19 01:21:18 2012 +0800
>> +++ b/tools/libxc/xenctrl.h	Wed Sep 19 03:31:30 2012 +0800 @@ -571,6
>>                            +571,26 @@ xc_domaininfo_t *info);
>> 
>>  /**
>> + * This function start monitor vmce event.
>> + * @parm xch a handle to an open hypervisor interface
>> + * @parm domid the domain id monitored
>> + * @return 0 on success, -1 on failure
>> + */
>> +int xc_domain_vmce_monitor_strat(xc_interface *xch,
>> +                                 uint32_t domid);
>> +
>> +/**
>> + * This function end monitor vmce event
>> + * @parm xch a handle to an open hypervisor interface
>> + * @parm domid the domain id monitored
>> + * @parm vmce_while_migrate a pointer return whether vMCE occur
>> when migrate + * @return 0 on success, -1 on failure
>> + */
>> +int xc_domain_vmce_monitor_end(xc_interface *xch,
>> +                               uint32_t domid,
>> +                               signed char *vmce_while_monitor); +
>> +/**
>>   * This function returns information about the context of a hvm
>> domain 
>>   * @parm xch a handle to an open hypervisor interface
>>   * @parm domid the domain to get information from
>> diff -r f843ac6f93c9 xen/arch/x86/cpu/mcheck/mce_intel.c
>> --- a/xen/arch/x86/cpu/mcheck/mce_intel.c	Wed Sep 19 01:21:18 2012
>> +0800 +++ b/xen/arch/x86/cpu/mcheck/mce_intel.c	Wed Sep 19 03:31:30
>>                      2012 +0800 @@ -596,6 +596,12 @@ goto
>>                  vmce_failed; }
>> 
>> +                if ( unlikely(d->arch.vmce_monitor) ) +            
>> { +                    /* vMCE occur when guest migration */
>> +                    d->arch.vmce_monitor = -1;
>> +                }
>> +
>>                  /* We will inject vMCE to DOMU*/
>>                  if ( inject_vmce(d) < 0 )
>>                  {
>> diff -r f843ac6f93c9 xen/arch/x86/domctl.c
>> --- a/xen/arch/x86/domctl.c	Wed Sep 19 01:21:18 2012 +0800
>> +++ b/xen/arch/x86/domctl.c	Wed Sep 19 03:31:30 2012 +0800 @@
>>      -1514,6 +1514,40 @@ }
>>      break;
>> 
>> +    case XEN_DOMCTL_vmce_monitor_start:
>> +    {
>> +        struct domain *d;
>> +
>> +        d = rcu_lock_domain_by_id(domctl->domain); +        if ( d
>> != NULL ) +        {
>> +            d->arch.vmce_monitor = 1;
>> +            rcu_unlock_domain(d);
>> +        }
>> +        else
>> +            ret = -ESRCH;
>> +    }
>> +    break;
>> +
>> +    case XEN_DOMCTL_vmce_monitor_end:
>> +    {
>> +        struct domain *d;
>> +
>> +        d = rcu_lock_domain_by_id(domctl->domain); +        if ( d
>> != NULL) +        {
>> +            domctl->u.vmce_monitor.vmce_while_monitor =
>> +                                      d->arch.vmce_monitor;
>> +            d->arch.vmce_monitor = 0;
>> +            rcu_unlock_domain(d);
>> +            if ( copy_to_guest(u_domctl, domctl, 1) )
>> +                ret = -EFAULT;
>> +        }
>> +        else
>> +            ret = -ESRCH;
>> +    }
>> +    break;
>> +
>>      default:
>>          ret = iommu_do_domctl(domctl, u_domctl);
>>          break;
>> diff -r f843ac6f93c9 xen/include/asm-x86/domain.h
>> --- a/xen/include/asm-x86/domain.h	Wed Sep 19 01:21:18 2012 +0800
>> +++ b/xen/include/asm-x86/domain.h	Wed Sep 19 03:31:30 2012 +0800 @@
>>      -279,6 +279,11 @@ bool_t has_32bit_shinfo;
>>      /* Domain cannot handle spurious page faults? */
>>      bool_t suppress_spurious_page_faults;
>> +    /* Monitoring guest memory copy of migration
>> +     * = 0 - not monitoring
>> +     * > 0 - monitoring
>> +     * < 0 - vMCE occurred while monitoring */
>> +    s8 vmce_monitor;
>> 
>>      /* Continuable domain_relinquish_resources(). */      enum {
>> diff -r f843ac6f93c9 xen/include/public/domctl.h
>> --- a/xen/include/public/domctl.h	Wed Sep 19 01:21:18 2012 +0800
>> +++ b/xen/include/public/domctl.h	Wed Sep 19 03:31:30 2012 +0800 @@
>>  -828,6 +828,12 @@ typedef struct xen_domctl_set_access_required
>>  xen_domctl_set_access_required_t;
>> DEFINE_XEN_GUEST_HANDLE(xen_domctl_set_access_required_t); 
>> 
>> +struct xen_domctl_vmce_monitor {
>> +    signed char vmce_while_monitor;
>> +};
>> +typedef struct xen_domctl_vmce_monitor xen_domctl_vmce_monitor_t;
>> +DEFINE_XEN_GUEST_HANDLE(xen_domctl_vmce_monitor_t); +
>>  struct xen_domctl {
>>      uint32_t cmd;
>>  #define XEN_DOMCTL_createdomain                   1 @@ -893,6
>>  +899,8 @@ #define XEN_DOMCTL_set_access_required           64
>>  #define XEN_DOMCTL_audit_p2m                     65
>>  #define XEN_DOMCTL_set_virq_handler              66
>> +#define XEN_DOMCTL_vmce_monitor_start            67
>> +#define XEN_DOMCTL_vmce_monitor_end              68
>>  #define XEN_DOMCTL_gdbsx_guestmemio            1000
>>  #define XEN_DOMCTL_gdbsx_pausevcpu             1001
>>  #define XEN_DOMCTL_gdbsx_unpausevcpu           1002 @@ -947,6
>>          +955,7 @@ struct xen_domctl_set_access_required
>>          access_required; struct xen_domctl_audit_p2m        
>>          audit_p2m; struct xen_domctl_set_virq_handler 
>> set_virq_handler; +        struct xen_domctl_vmce_monitor     
>>          vmce_monitor; struct xen_domctl_gdbsx_memio      
>>          gdbsx_guest_memio; struct xen_domctl_gdbsx_pauseunp_vcpu
>>          gdbsx_pauseunp_vcpu; struct xen_domctl_gdbsx_domstatus  
>> gdbsx_domstatus; 

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 4/5] Xen/MCE: Abort live migration when vMCE occur
@ 2012-09-19  8:14 Liu, Jinsong
  0 siblings, 0 replies; 20+ messages in thread
From: Liu, Jinsong @ 2012-09-19  8:14 UTC (permalink / raw)
  To: Jan Beulich, xen-devel@lists.xensource.com
  Cc: Christoph Egger, keir@xen.org, Ian.Campbell@citrix.com

[-- Attachment #1: Type: text/plain, Size: 7958 bytes --]

Xen/MCE: Abort live migration when vMCE occur

This patch monitor the critical area of live migration (from vMCE point of view,
the copypages stage of migration is the critical area while other areas are not).

If a vMCE occur at the critical area of live migration, abort and try migration later.

Signed-off-by: Liu, Jinsong <jinsong.liu@intel.com>

diff -r e71c4bdcc05a tools/libxc/xc_domain.c
--- a/tools/libxc/xc_domain.c	Wed Sep 19 23:27:40 2012 +0800
+++ b/tools/libxc/xc_domain.c	Thu Sep 20 00:00:17 2012 +0800
@@ -283,6 +283,37 @@
     return ret;
 }
 
+/* Start vmce monitor */
+int xc_domain_vmce_monitor_start(xc_interface *xch,
+                                 uint32_t domid)
+{
+    int ret;
+    DECLARE_DOMCTL;
+
+    domctl.cmd = XEN_DOMCTL_vmce_monitor_start;
+    domctl.domain = (domid_t)domid;
+    ret = do_domctl(xch, &domctl);
+
+    return ret ? -1 : 0;
+}
+
+/* End vmce monitor */
+int xc_domain_vmce_monitor_end(xc_interface *xch,
+                               uint32_t domid,
+                               signed char *vmce_while_monitor)
+{
+    int ret;
+    DECLARE_DOMCTL;
+
+    domctl.cmd = XEN_DOMCTL_vmce_monitor_end;
+    domctl.domain = (domid_t)domid;
+    ret = do_domctl(xch, &domctl);
+    if ( !ret )
+        *vmce_while_monitor = domctl.u.vmce_monitor.vmce_while_monitor;
+
+    return ret ? -1 : 0;
+}
+
 /* get info from hvm guest for save */
 int xc_domain_hvm_getcontext(xc_interface *xch,
                              uint32_t domid,
diff -r e71c4bdcc05a tools/libxc/xc_domain_save.c
--- a/tools/libxc/xc_domain_save.c	Wed Sep 19 23:27:40 2012 +0800
+++ b/tools/libxc/xc_domain_save.c	Thu Sep 20 00:00:17 2012 +0800
@@ -895,6 +895,8 @@
      */
     int compressing = 0;
 
+    signed char vmce_while_monitor = 0;
+
     int completed = 0;
 
     if ( hvm && !callbacks->switch_qemu_logdirty )
@@ -1109,6 +1111,12 @@
         goto out;
     }
 
+    if ( xc_domain_vmce_monitor_start(xch, dom) )
+    {
+        PERROR("Error when start vmce monitor\n");
+        goto out;
+    }
+
   copypages:
 #define wrexact(fd, buf, len) write_buffer(xch, last_iter, ob, (fd), (buf), (len))
 #define wruncached(fd, live, buf, len) write_uncached(xch, last_iter, ob, (fd), (buf), (len))
@@ -1571,6 +1579,17 @@
 
     DPRINTF("All memory is saved\n");
 
+    if ( xc_domain_vmce_monitor_end(xch, dom, &vmce_while_monitor) )
+    {
+        PERROR("Error when end vmce monitor\n");
+        goto out;
+    }
+    else if ( vmce_while_monitor == -1 )
+    {
+        fprintf(stderr, "vMCE occurred, abort this time and try later.\n");
+        goto out;
+    }
+
     /* After last_iter, buffer the rest of pagebuf & tailbuf data into a
      * separate output buffer and flush it after the compressed page chunks.
      */
diff -r e71c4bdcc05a tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h	Wed Sep 19 23:27:40 2012 +0800
+++ b/tools/libxc/xenctrl.h	Thu Sep 20 00:00:17 2012 +0800
@@ -575,6 +575,26 @@
                           xc_domaininfo_t *info);
 
 /**
+ * This function start monitor vmce event.
+ * @parm xch a handle to an open hypervisor interface
+ * @parm domid the domain id monitored
+ * @return 0 on success, -1 on failure
+ */
+int xc_domain_vmce_monitor_start(xc_interface *xch,
+                                 uint32_t domid);
+
+/**
+ * This function end monitor vmce event
+ * @parm xch a handle to an open hypervisor interface
+ * @parm domid the domain id monitored
+ * @parm vmce_while_migrate a pointer return whether vMCE occur when migrate 
+ * @return 0 on success, -1 on failure
+ */
+int xc_domain_vmce_monitor_end(xc_interface *xch,
+                               uint32_t domid,
+                               signed char *vmce_while_monitor);
+
+/**
  * This function returns information about the context of a hvm domain
  * @parm xch a handle to an open hypervisor interface
  * @parm domid the domain to get information from
diff -r e71c4bdcc05a xen/arch/x86/cpu/mcheck/mce_intel.c
--- a/xen/arch/x86/cpu/mcheck/mce_intel.c	Wed Sep 19 23:27:40 2012 +0800
+++ b/xen/arch/x86/cpu/mcheck/mce_intel.c	Thu Sep 20 00:00:17 2012 +0800
@@ -358,6 +358,12 @@
                     goto vmce_failed;
                 }
 
+                if ( unlikely(d->arch.vmce_monitor) )
+                {
+                    /* vMCE occur when guest migration */
+                    d->arch.vmce_monitor = -1;
+                }
+
                 /* We will inject vMCE to DOMU*/
                 if ( inject_vmce(d) < 0 )
                 {
diff -r e71c4bdcc05a xen/arch/x86/domctl.c
--- a/xen/arch/x86/domctl.c	Wed Sep 19 23:27:40 2012 +0800
+++ b/xen/arch/x86/domctl.c	Thu Sep 20 00:00:17 2012 +0800
@@ -1514,6 +1514,40 @@
     }
     break;
 
+    case XEN_DOMCTL_vmce_monitor_start:
+    {
+        struct domain *d;
+
+        d = rcu_lock_domain_by_id(domctl->domain);
+        if ( d != NULL )
+        {
+            d->arch.vmce_monitor = 1;
+            rcu_unlock_domain(d);
+        }
+        else
+            ret = -ESRCH;
+    }
+    break;
+
+    case XEN_DOMCTL_vmce_monitor_end:
+    {
+        struct domain *d;
+
+        d = rcu_lock_domain_by_id(domctl->domain);
+        if ( d != NULL)
+        {
+            domctl->u.vmce_monitor.vmce_while_monitor =
+                                      d->arch.vmce_monitor;
+            d->arch.vmce_monitor = 0;
+            rcu_unlock_domain(d);
+            if ( copy_to_guest(u_domctl, domctl, 1) )
+                ret = -EFAULT;
+        }
+        else
+            ret = -ESRCH;
+    }
+    break;
+
     default:
         ret = iommu_do_domctl(domctl, u_domctl);
         break;
diff -r e71c4bdcc05a xen/include/asm-x86/domain.h
--- a/xen/include/asm-x86/domain.h	Wed Sep 19 23:27:40 2012 +0800
+++ b/xen/include/asm-x86/domain.h	Thu Sep 20 00:00:17 2012 +0800
@@ -279,6 +279,11 @@
     bool_t has_32bit_shinfo;
     /* Domain cannot handle spurious page faults? */
     bool_t suppress_spurious_page_faults;
+    /* Monitoring guest memory copy of migration
+     * = 0 - not monitoring
+     * > 0 - monitoring
+     * < 0 - vMCE occurred while monitoring */
+    s8 vmce_monitor;
 
     /* Continuable domain_relinquish_resources(). */
     enum {
diff -r e71c4bdcc05a xen/include/public/domctl.h
--- a/xen/include/public/domctl.h	Wed Sep 19 23:27:40 2012 +0800
+++ b/xen/include/public/domctl.h	Thu Sep 20 00:00:17 2012 +0800
@@ -828,6 +828,12 @@
 typedef struct xen_domctl_set_access_required xen_domctl_set_access_required_t;
 DEFINE_XEN_GUEST_HANDLE(xen_domctl_set_access_required_t);
 
+struct xen_domctl_vmce_monitor {
+    signed char vmce_while_monitor;
+};
+typedef struct xen_domctl_vmce_monitor xen_domctl_vmce_monitor_t;
+DEFINE_XEN_GUEST_HANDLE(xen_domctl_vmce_monitor_t);
+
 struct xen_domctl {
     uint32_t cmd;
 #define XEN_DOMCTL_createdomain                   1
@@ -893,6 +899,8 @@
 #define XEN_DOMCTL_set_access_required           64
 #define XEN_DOMCTL_audit_p2m                     65
 #define XEN_DOMCTL_set_virq_handler              66
+#define XEN_DOMCTL_vmce_monitor_start            67
+#define XEN_DOMCTL_vmce_monitor_end              68
 #define XEN_DOMCTL_gdbsx_guestmemio            1000
 #define XEN_DOMCTL_gdbsx_pausevcpu             1001
 #define XEN_DOMCTL_gdbsx_unpausevcpu           1002
@@ -947,6 +955,7 @@
         struct xen_domctl_set_access_required access_required;
         struct xen_domctl_audit_p2m         audit_p2m;
         struct xen_domctl_set_virq_handler  set_virq_handler;
+        struct xen_domctl_vmce_monitor      vmce_monitor;
         struct xen_domctl_gdbsx_memio       gdbsx_guest_memio;
         struct xen_domctl_gdbsx_pauseunp_vcpu gdbsx_pauseunp_vcpu;
         struct xen_domctl_gdbsx_domstatus   gdbsx_domstatus;

[-- Attachment #2: 4_vmce_when_migrate.patch --]
[-- Type: application/octet-stream, Size: 7729 bytes --]

Xen/MCE: Abort live migration when vMCE occur

This patch monitor the critical area of live migration (from vMCE point of view,
the copypages stage of migration is the critical area while other areas are not).

If a vMCE occur at the critical area of live migration, abort and try migration later.

Signed-off-by: Liu, Jinsong <jinsong.liu@intel.com>

diff -r e71c4bdcc05a tools/libxc/xc_domain.c
--- a/tools/libxc/xc_domain.c	Wed Sep 19 23:27:40 2012 +0800
+++ b/tools/libxc/xc_domain.c	Thu Sep 20 00:00:17 2012 +0800
@@ -283,6 +283,37 @@
     return ret;
 }
 
+/* Start vmce monitor */
+int xc_domain_vmce_monitor_start(xc_interface *xch,
+                                 uint32_t domid)
+{
+    int ret;
+    DECLARE_DOMCTL;
+
+    domctl.cmd = XEN_DOMCTL_vmce_monitor_start;
+    domctl.domain = (domid_t)domid;
+    ret = do_domctl(xch, &domctl);
+
+    return ret ? -1 : 0;
+}
+
+/* End vmce monitor */
+int xc_domain_vmce_monitor_end(xc_interface *xch,
+                               uint32_t domid,
+                               signed char *vmce_while_monitor)
+{
+    int ret;
+    DECLARE_DOMCTL;
+
+    domctl.cmd = XEN_DOMCTL_vmce_monitor_end;
+    domctl.domain = (domid_t)domid;
+    ret = do_domctl(xch, &domctl);
+    if ( !ret )
+        *vmce_while_monitor = domctl.u.vmce_monitor.vmce_while_monitor;
+
+    return ret ? -1 : 0;
+}
+
 /* get info from hvm guest for save */
 int xc_domain_hvm_getcontext(xc_interface *xch,
                              uint32_t domid,
diff -r e71c4bdcc05a tools/libxc/xc_domain_save.c
--- a/tools/libxc/xc_domain_save.c	Wed Sep 19 23:27:40 2012 +0800
+++ b/tools/libxc/xc_domain_save.c	Thu Sep 20 00:00:17 2012 +0800
@@ -895,6 +895,8 @@
      */
     int compressing = 0;
 
+    signed char vmce_while_monitor = 0;
+
     int completed = 0;
 
     if ( hvm && !callbacks->switch_qemu_logdirty )
@@ -1109,6 +1111,12 @@
         goto out;
     }
 
+    if ( xc_domain_vmce_monitor_start(xch, dom) )
+    {
+        PERROR("Error when start vmce monitor\n");
+        goto out;
+    }
+
   copypages:
 #define wrexact(fd, buf, len) write_buffer(xch, last_iter, ob, (fd), (buf), (len))
 #define wruncached(fd, live, buf, len) write_uncached(xch, last_iter, ob, (fd), (buf), (len))
@@ -1571,6 +1579,17 @@
 
     DPRINTF("All memory is saved\n");
 
+    if ( xc_domain_vmce_monitor_end(xch, dom, &vmce_while_monitor) )
+    {
+        PERROR("Error when end vmce monitor\n");
+        goto out;
+    }
+    else if ( vmce_while_monitor == -1 )
+    {
+        fprintf(stderr, "vMCE occurred, abort this time and try later.\n");
+        goto out;
+    }
+
     /* After last_iter, buffer the rest of pagebuf & tailbuf data into a
      * separate output buffer and flush it after the compressed page chunks.
      */
diff -r e71c4bdcc05a tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h	Wed Sep 19 23:27:40 2012 +0800
+++ b/tools/libxc/xenctrl.h	Thu Sep 20 00:00:17 2012 +0800
@@ -575,6 +575,26 @@
                           xc_domaininfo_t *info);
 
 /**
+ * This function start monitor vmce event.
+ * @parm xch a handle to an open hypervisor interface
+ * @parm domid the domain id monitored
+ * @return 0 on success, -1 on failure
+ */
+int xc_domain_vmce_monitor_start(xc_interface *xch,
+                                 uint32_t domid);
+
+/**
+ * This function end monitor vmce event
+ * @parm xch a handle to an open hypervisor interface
+ * @parm domid the domain id monitored
+ * @parm vmce_while_migrate a pointer return whether vMCE occur when migrate 
+ * @return 0 on success, -1 on failure
+ */
+int xc_domain_vmce_monitor_end(xc_interface *xch,
+                               uint32_t domid,
+                               signed char *vmce_while_monitor);
+
+/**
  * This function returns information about the context of a hvm domain
  * @parm xch a handle to an open hypervisor interface
  * @parm domid the domain to get information from
diff -r e71c4bdcc05a xen/arch/x86/cpu/mcheck/mce_intel.c
--- a/xen/arch/x86/cpu/mcheck/mce_intel.c	Wed Sep 19 23:27:40 2012 +0800
+++ b/xen/arch/x86/cpu/mcheck/mce_intel.c	Thu Sep 20 00:00:17 2012 +0800
@@ -358,6 +358,12 @@
                     goto vmce_failed;
                 }
 
+                if ( unlikely(d->arch.vmce_monitor) )
+                {
+                    /* vMCE occur when guest migration */
+                    d->arch.vmce_monitor = -1;
+                }
+
                 /* We will inject vMCE to DOMU*/
                 if ( inject_vmce(d) < 0 )
                 {
diff -r e71c4bdcc05a xen/arch/x86/domctl.c
--- a/xen/arch/x86/domctl.c	Wed Sep 19 23:27:40 2012 +0800
+++ b/xen/arch/x86/domctl.c	Thu Sep 20 00:00:17 2012 +0800
@@ -1514,6 +1514,40 @@
     }
     break;
 
+    case XEN_DOMCTL_vmce_monitor_start:
+    {
+        struct domain *d;
+
+        d = rcu_lock_domain_by_id(domctl->domain);
+        if ( d != NULL )
+        {
+            d->arch.vmce_monitor = 1;
+            rcu_unlock_domain(d);
+        }
+        else
+            ret = -ESRCH;
+    }
+    break;
+
+    case XEN_DOMCTL_vmce_monitor_end:
+    {
+        struct domain *d;
+
+        d = rcu_lock_domain_by_id(domctl->domain);
+        if ( d != NULL)
+        {
+            domctl->u.vmce_monitor.vmce_while_monitor =
+                                      d->arch.vmce_monitor;
+            d->arch.vmce_monitor = 0;
+            rcu_unlock_domain(d);
+            if ( copy_to_guest(u_domctl, domctl, 1) )
+                ret = -EFAULT;
+        }
+        else
+            ret = -ESRCH;
+    }
+    break;
+
     default:
         ret = iommu_do_domctl(domctl, u_domctl);
         break;
diff -r e71c4bdcc05a xen/include/asm-x86/domain.h
--- a/xen/include/asm-x86/domain.h	Wed Sep 19 23:27:40 2012 +0800
+++ b/xen/include/asm-x86/domain.h	Thu Sep 20 00:00:17 2012 +0800
@@ -279,6 +279,11 @@
     bool_t has_32bit_shinfo;
     /* Domain cannot handle spurious page faults? */
     bool_t suppress_spurious_page_faults;
+    /* Monitoring guest memory copy of migration
+     * = 0 - not monitoring
+     * > 0 - monitoring
+     * < 0 - vMCE occurred while monitoring */
+    s8 vmce_monitor;
 
     /* Continuable domain_relinquish_resources(). */
     enum {
diff -r e71c4bdcc05a xen/include/public/domctl.h
--- a/xen/include/public/domctl.h	Wed Sep 19 23:27:40 2012 +0800
+++ b/xen/include/public/domctl.h	Thu Sep 20 00:00:17 2012 +0800
@@ -828,6 +828,12 @@
 typedef struct xen_domctl_set_access_required xen_domctl_set_access_required_t;
 DEFINE_XEN_GUEST_HANDLE(xen_domctl_set_access_required_t);
 
+struct xen_domctl_vmce_monitor {
+    signed char vmce_while_monitor;
+};
+typedef struct xen_domctl_vmce_monitor xen_domctl_vmce_monitor_t;
+DEFINE_XEN_GUEST_HANDLE(xen_domctl_vmce_monitor_t);
+
 struct xen_domctl {
     uint32_t cmd;
 #define XEN_DOMCTL_createdomain                   1
@@ -893,6 +899,8 @@
 #define XEN_DOMCTL_set_access_required           64
 #define XEN_DOMCTL_audit_p2m                     65
 #define XEN_DOMCTL_set_virq_handler              66
+#define XEN_DOMCTL_vmce_monitor_start            67
+#define XEN_DOMCTL_vmce_monitor_end              68
 #define XEN_DOMCTL_gdbsx_guestmemio            1000
 #define XEN_DOMCTL_gdbsx_pausevcpu             1001
 #define XEN_DOMCTL_gdbsx_unpausevcpu           1002
@@ -947,6 +955,7 @@
         struct xen_domctl_set_access_required access_required;
         struct xen_domctl_audit_p2m         audit_p2m;
         struct xen_domctl_set_virq_handler  set_virq_handler;
+        struct xen_domctl_vmce_monitor      vmce_monitor;
         struct xen_domctl_gdbsx_memio       gdbsx_guest_memio;
         struct xen_domctl_gdbsx_pauseunp_vcpu gdbsx_pauseunp_vcpu;
         struct xen_domctl_gdbsx_domstatus   gdbsx_domstatus;

[-- Attachment #3: Type: text/plain, Size: 126 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 4/5] Xen/MCE: Abort live migration when vMCE occur
  2012-09-18 13:16 [PATCH 4/5] Xen/MCE: Abort live migration when vMCE occur Liu, Jinsong
  2012-09-18 15:29 ` Christoph Egger
@ 2012-10-10  9:10 ` Ian Campbell
  2012-10-10 14:14   ` Liu, Jinsong
  1 sibling, 1 reply; 20+ messages in thread
From: Ian Campbell @ 2012-10-10  9:10 UTC (permalink / raw)
  To: Liu, Jinsong; +Cc: xen-devel@lists.xensource.com, Keir (Xen.org), Jan Beulich

On Tue, 2012-09-18 at 14:16 +0100, Liu, Jinsong wrote:
> Xen/MCE: Abort live migration when vMCE occur
> 
> This patch monitor the critical area of live migration (from vMCE point of view,
> the copypages stage of migration is the critical area while other areas are not).
> 
> If a vMCE occur at the critical area of live migration, abort and try migration later.

Can you elaborate a little on why it is necessary to abort and try
again?

> Signed-off-by: Liu, Jinsong <jinsong.liu@intel.com>
> 
> diff -r f843ac6f93c9 tools/libxc/xc_domain.c
> --- a/tools/libxc/xc_domain.c	Wed Sep 19 01:21:18 2012 +0800
> +++ b/tools/libxc/xc_domain.c	Wed Sep 19 03:31:30 2012 +0800
> @@ -283,6 +283,37 @@
>      return ret;
>  }
>  
> +/* Start vmce monitor */
> +int xc_domain_vmce_monitor_strat(xc_interface *xch,

strat?

> +                                 uint32_t domid)
> +{
> +    int ret;
> +    DECLARE_DOMCTL;
> +
> +    domctl.cmd = XEN_DOMCTL_vmce_monitor_start;
> +    domctl.domain = (domid_t)domid;
> +    ret = do_domctl(xch, &domctl);
> +
> +    return ret ? -1 : 0;
> +}
> +
> +/* End vmce monitor */
> +int xc_domain_vmce_monitor_end(xc_interface *xch,
> +                               uint32_t domid,
> +                               signed char *vmce_while_monitor)
> +{
> +    int ret;
> +    DECLARE_DOMCTL;
> +
> +    domctl.cmd = XEN_DOMCTL_vmce_monitor_end;
> +    domctl.domain = (domid_t)domid;
> +    ret = do_domctl(xch, &domctl);
> +    if ( !ret )
> +        *vmce_while_monitor = domctl.u.vmce_monitor.vmce_while_monitor;

Any reason this is a char rather than an int?

> +    return ret ? -1 : 0;
> +}
> +
>  /* get info from hvm guest for save */
>  int xc_domain_hvm_getcontext(xc_interface *xch,
>                               uint32_t domid,
> [...]
> diff -r f843ac6f93c9 tools/libxc/xenctrl.h
> --- a/tools/libxc/xenctrl.h	Wed Sep 19 01:21:18 2012 +0800
> +++ b/tools/libxc/xenctrl.h	Wed Sep 19 03:31:30 2012 +0800
> @@ -571,6 +571,26 @@
>                            xc_domaininfo_t *info);
>  
>  /**
> + * This function start monitor vmce event.
> + * @parm xch a handle to an open hypervisor interface
> + * @parm domid the domain id monitored
> + * @return 0 on success, -1 on failure
> + */
> +int xc_domain_vmce_monitor_strat(xc_interface *xch,
> +                                 uint32_t domid);
> +
> +/**
> + * This function end monitor vmce event
> + * @parm xch a handle to an open hypervisor interface
> + * @parm domid the domain id monitored
> + * @parm vmce_while_migrate a pointer return whether vMCE occur when migrate 

This function isn't actually specific to migration (even if that happens
to be the only user currently), it just tracks whether a vMCE occurs
while monitoring was in progress AFAICT.

> + * @return 0 on success, -1 on failure
> + */
> +int xc_domain_vmce_monitor_end(xc_interface *xch,
> +                               uint32_t domid,
> +                               signed char *vmce_while_monitor);
> +
> +/**
>   * This function returns information about the context of a hvm domain
>   * @parm xch a handle to an open hypervisor interface
>   * @parm domid the domain to get information from
> diff -r f843ac6f93c9 xen/include/asm-x86/domain.h
> --- a/xen/include/asm-x86/domain.h	Wed Sep 19 01:21:18 2012 +0800
> +++ b/xen/include/asm-x86/domain.h	Wed Sep 19 03:31:30 2012 +0800
> @@ -279,6 +279,11 @@
>      bool_t has_32bit_shinfo;
>      /* Domain cannot handle spurious page faults? */
>      bool_t suppress_spurious_page_faults;
> +    /* Monitoring guest memory copy of migration
> +     * = 0 - not monitoring
> +     * > 0 - monitoring
> +     * < 0 - vMCE occurred while monitoring */
> +    s8 vmce_monitor;
>  
>      /* Continuable domain_relinquish_resources(). */
>      enum {
> diff -r f843ac6f93c9 xen/include/public/domctl.h
> --- a/xen/include/public/domctl.h	Wed Sep 19 01:21:18 2012 +0800
> +++ b/xen/include/public/domctl.h	Wed Sep 19 03:31:30 2012 +0800
> @@ -828,6 +828,12 @@
>  typedef struct xen_domctl_set_access_required xen_domctl_set_access_required_t;
>  DEFINE_XEN_GUEST_HANDLE(xen_domctl_set_access_required_t);
>  
> +struct xen_domctl_vmce_monitor {
> +    signed char vmce_while_monitor;

You leak the semantics of the internal flag into this variable which
makes it rather clumsy to use (e.g. you have to check for <0). This
should just be a bool I think.

Calling vmce_monitor_end without a preceding monitor start should be an
error (-EINVAL?) and this value would be undefined in that case.

Do you actually need struct xen_domctl_vmce_monitor could the flag not
be part of the return value of XEN_DOMCTL_vmce_monitor_end? e.g. -ERRNO
on error, 0 if no vmce, 1 if vmce occurred?

Also calling vmce_monitor_start while monitoring is already in progress
should result in -EBUSY, otherwise multiple agents who try to monitor
will get unexpected/inconsistent results.

> +};
> +typedef struct xen_domctl_vmce_monitor xen_domctl_vmce_monitor_t;
> +DEFINE_XEN_GUEST_HANDLE(xen_domctl_vmce_monitor_t);
> +
>  struct xen_domctl {
>      uint32_t cmd;
>  #define XEN_DOMCTL_createdomain                   1
> @@ -893,6 +899,8 @@
>  #define XEN_DOMCTL_set_access_required           64
>  #define XEN_DOMCTL_audit_p2m                     65
>  #define XEN_DOMCTL_set_virq_handler              66
> +#define XEN_DOMCTL_vmce_monitor_start            67
> +#define XEN_DOMCTL_vmce_monitor_end              68
>  #define XEN_DOMCTL_gdbsx_guestmemio            1000
>  #define XEN_DOMCTL_gdbsx_pausevcpu             1001
>  #define XEN_DOMCTL_gdbsx_unpausevcpu           1002
> @@ -947,6 +955,7 @@
>          struct xen_domctl_set_access_required access_required;
>          struct xen_domctl_audit_p2m         audit_p2m;
>          struct xen_domctl_set_virq_handler  set_virq_handler;
> +        struct xen_domctl_vmce_monitor      vmce_monitor;
>          struct xen_domctl_gdbsx_memio       gdbsx_guest_memio;
>          struct xen_domctl_gdbsx_pauseunp_vcpu gdbsx_pauseunp_vcpu;
>          struct xen_domctl_gdbsx_domstatus   gdbsx_domstatus;

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 4/5] Xen/MCE: Abort live migration when vMCE occur
  2012-10-10  9:10 ` Ian Campbell
@ 2012-10-10 14:14   ` Liu, Jinsong
  0 siblings, 0 replies; 20+ messages in thread
From: Liu, Jinsong @ 2012-10-10 14:14 UTC (permalink / raw)
  To: Ian Campbell; +Cc: xen-devel@lists.xensource.com, Keir (Xen.org), Jan Beulich

Updated, thanks! Will send out later.

Ian Campbell wrote:
> On Tue, 2012-09-18 at 14:16 +0100, Liu, Jinsong wrote:
>> Xen/MCE: Abort live migration when vMCE occur
>> 
>> This patch monitor the critical area of live migration (from vMCE
>> point of view, 
>> the copypages stage of migration is the critical area while other
>> areas are not). 
>> 
>> If a vMCE occur at the critical area of live migration, abort and
>> try migration later. 
> 
> Can you elaborate a little on why it is necessary to abort and try
> again?
> 
>> Signed-off-by: Liu, Jinsong <jinsong.liu@intel.com>
>> 
>> diff -r f843ac6f93c9 tools/libxc/xc_domain.c
>> --- a/tools/libxc/xc_domain.c	Wed Sep 19 01:21:18 2012 +0800
>> +++ b/tools/libxc/xc_domain.c	Wed Sep 19 03:31:30 2012 +0800 @@
>>      -283,6 +283,37 @@ return ret;
>>  }
>> 
>> +/* Start vmce monitor */
>> +int xc_domain_vmce_monitor_strat(xc_interface *xch,
> 
> strat?
> 
>> +                                 uint32_t domid)
>> +{
>> +    int ret;
>> +    DECLARE_DOMCTL;
>> +
>> +    domctl.cmd = XEN_DOMCTL_vmce_monitor_start;
>> +    domctl.domain = (domid_t)domid;
>> +    ret = do_domctl(xch, &domctl);
>> +
>> +    return ret ? -1 : 0;
>> +}
>> +
>> +/* End vmce monitor */
>> +int xc_domain_vmce_monitor_end(xc_interface *xch,
>> +                               uint32_t domid,
>> +                               signed char *vmce_while_monitor) +{
>> +    int ret;
>> +    DECLARE_DOMCTL;
>> +
>> +    domctl.cmd = XEN_DOMCTL_vmce_monitor_end;
>> +    domctl.domain = (domid_t)domid;
>> +    ret = do_domctl(xch, &domctl);
>> +    if ( !ret )
>> +        *vmce_while_monitor =
>> domctl.u.vmce_monitor.vmce_while_monitor; 
> 
> Any reason this is a char rather than an int?
> 
>> +    return ret ? -1 : 0;
>> +}
>> +
>>  /* get info from hvm guest for save */
>>  int xc_domain_hvm_getcontext(xc_interface *xch,
>>                               uint32_t domid,
>> [...]
>> diff -r f843ac6f93c9 tools/libxc/xenctrl.h
>> --- a/tools/libxc/xenctrl.h	Wed Sep 19 01:21:18 2012 +0800
>> +++ b/tools/libxc/xenctrl.h	Wed Sep 19 03:31:30 2012 +0800 @@ -571,6
>>                            +571,26 @@ xc_domaininfo_t *info);
>> 
>>  /**
>> + * This function start monitor vmce event.
>> + * @parm xch a handle to an open hypervisor interface
>> + * @parm domid the domain id monitored
>> + * @return 0 on success, -1 on failure
>> + */
>> +int xc_domain_vmce_monitor_strat(xc_interface *xch,
>> +                                 uint32_t domid);
>> +
>> +/**
>> + * This function end monitor vmce event
>> + * @parm xch a handle to an open hypervisor interface
>> + * @parm domid the domain id monitored
>> + * @parm vmce_while_migrate a pointer return whether vMCE occur
>> when migrate 
> 
> This function isn't actually specific to migration (even if that
> happens to be the only user currently), it just tracks whether a vMCE
> occurs while monitoring was in progress AFAICT.
> 
>> + * @return 0 on success, -1 on failure
>> + */
>> +int xc_domain_vmce_monitor_end(xc_interface *xch,
>> +                               uint32_t domid,
>> +                               signed char *vmce_while_monitor); +
>> +/**
>>   * This function returns information about the context of a hvm
>> domain 
>>   * @parm xch a handle to an open hypervisor interface
>>   * @parm domid the domain to get information from
>> diff -r f843ac6f93c9 xen/include/asm-x86/domain.h
>> --- a/xen/include/asm-x86/domain.h	Wed Sep 19 01:21:18 2012 +0800
>> +++ b/xen/include/asm-x86/domain.h	Wed Sep 19 03:31:30 2012 +0800 @@
>>      -279,6 +279,11 @@ bool_t has_32bit_shinfo;
>>      /* Domain cannot handle spurious page faults? */
>>      bool_t suppress_spurious_page_faults;
>> +    /* Monitoring guest memory copy of migration
>> +     * = 0 - not monitoring
>> +     * > 0 - monitoring
>> +     * < 0 - vMCE occurred while monitoring */
>> +    s8 vmce_monitor;
>> 
>>      /* Continuable domain_relinquish_resources(). */      enum {
>> diff -r f843ac6f93c9 xen/include/public/domctl.h
>> --- a/xen/include/public/domctl.h	Wed Sep 19 01:21:18 2012 +0800
>> +++ b/xen/include/public/domctl.h	Wed Sep 19 03:31:30 2012 +0800 @@
>>  -828,6 +828,12 @@ typedef struct xen_domctl_set_access_required
>>  xen_domctl_set_access_required_t;
>> DEFINE_XEN_GUEST_HANDLE(xen_domctl_set_access_required_t); 
>> 
>> +struct xen_domctl_vmce_monitor {
>> +    signed char vmce_while_monitor;
> 
> You leak the semantics of the internal flag into this variable which
> makes it rather clumsy to use (e.g. you have to check for <0). This
> should just be a bool I think.
> 
> Calling vmce_monitor_end without a preceding monitor start should be
> an error (-EINVAL?) and this value would be undefined in that case.
> 
> Do you actually need struct xen_domctl_vmce_monitor could the flag not
> be part of the return value of XEN_DOMCTL_vmce_monitor_end? e.g.
> -ERRNO on error, 0 if no vmce, 1 if vmce occurred?
> 
> Also calling vmce_monitor_start while monitoring is already in
> progress should result in -EBUSY, otherwise multiple agents who try
> to monitor will get unexpected/inconsistent results.
> 
>> +};
>> +typedef struct xen_domctl_vmce_monitor xen_domctl_vmce_monitor_t;
>> +DEFINE_XEN_GUEST_HANDLE(xen_domctl_vmce_monitor_t); +
>>  struct xen_domctl {
>>      uint32_t cmd;
>>  #define XEN_DOMCTL_createdomain                   1 @@ -893,6
>>  +899,8 @@ #define XEN_DOMCTL_set_access_required           64
>>  #define XEN_DOMCTL_audit_p2m                     65
>>  #define XEN_DOMCTL_set_virq_handler              66
>> +#define XEN_DOMCTL_vmce_monitor_start            67
>> +#define XEN_DOMCTL_vmce_monitor_end              68
>>  #define XEN_DOMCTL_gdbsx_guestmemio            1000
>>  #define XEN_DOMCTL_gdbsx_pausevcpu             1001
>>  #define XEN_DOMCTL_gdbsx_unpausevcpu           1002 @@ -947,6
>>          +955,7 @@ struct xen_domctl_set_access_required
>>          access_required; struct xen_domctl_audit_p2m        
>>          audit_p2m; struct xen_domctl_set_virq_handler 
>> set_virq_handler; +        struct xen_domctl_vmce_monitor     
>>          vmce_monitor; struct xen_domctl_gdbsx_memio      
>>          gdbsx_guest_memio; struct xen_domctl_gdbsx_pauseunp_vcpu
>>          gdbsx_pauseunp_vcpu; struct xen_domctl_gdbsx_domstatus  
>> gdbsx_domstatus; 

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 4/5] Xen/MCE: Abort live migration when vMCE occur
@ 2012-10-10 14:46 Liu, Jinsong
  2012-10-16 10:42 ` Liu, Jinsong
                   ` (2 more replies)
  0 siblings, 3 replies; 20+ messages in thread
From: Liu, Jinsong @ 2012-10-10 14:46 UTC (permalink / raw)
  To: Ian Campbell, xen-devel@lists.xensource.com
  Cc: Ian Jackson, Christoph Egger, Keir (Xen.org), Jan Beulich

[-- Attachment #1: Type: text/plain, Size: 7061 bytes --]

Xen/MCE: Abort live migration when vMCE occur

This patch monitor the critical area of live migration (from vMCE point of view,
the copypages stage of migration is the critical area while other areas are not).

If a vMCE occur at the critical area of live migration, there is risk that error
data may be copied to the target. Currently we don't have convenient way to handle
this case, so for the sake of safe, we abort it and try migration later (at that
time broken page would not be mapped and copied to the target).

Signed-off-by: Liu, Jinsong <jinsong.liu@intel.com>

diff -r e27a6d53ac15 tools/libxc/xc_domain.c
--- a/tools/libxc/xc_domain.c	Thu Oct 11 01:52:33 2012 +0800
+++ b/tools/libxc/xc_domain.c	Thu Oct 11 05:12:48 2012 +0800
@@ -283,6 +283,30 @@
     return ret;
 }
 
+/* Start vmce monitor */
+int xc_domain_vmce_monitor_start(xc_interface *xch,
+                                 uint32_t domid)
+{
+    DECLARE_DOMCTL;
+
+    domctl.cmd = XEN_DOMCTL_vmce_monitor_start;
+    domctl.domain = (domid_t)domid;
+
+    return do_domctl(xch, &domctl);
+}
+
+/* End vmce monitor */
+int xc_domain_vmce_monitor_end(xc_interface *xch,
+                               uint32_t domid)
+{
+    DECLARE_DOMCTL;
+
+    domctl.cmd = XEN_DOMCTL_vmce_monitor_end;
+    domctl.domain = (domid_t)domid;
+
+    return do_domctl(xch, &domctl);
+}
+
 /* get info from hvm guest for save */
 int xc_domain_hvm_getcontext(xc_interface *xch,
                              uint32_t domid,
diff -r e27a6d53ac15 tools/libxc/xc_domain_save.c
--- a/tools/libxc/xc_domain_save.c	Thu Oct 11 01:52:33 2012 +0800
+++ b/tools/libxc/xc_domain_save.c	Thu Oct 11 05:12:48 2012 +0800
@@ -895,6 +895,8 @@
      */
     int compressing = 0;
 
+    int vmce_while_monitor = 0;
+
     int completed = 0;
 
     if ( hvm && !callbacks->switch_qemu_logdirty )
@@ -1109,6 +1111,12 @@
         goto out;
     }
 
+    if ( xc_domain_vmce_monitor_start(xch, dom) )
+    {
+        PERROR("Error when start vmce monitor\n");
+        goto out;
+    }
+
   copypages:
 #define wrexact(fd, buf, len) write_buffer(xch, last_iter, ob, (fd), (buf), (len))
 #define wruncached(fd, live, buf, len) write_uncached(xch, last_iter, ob, (fd), (buf), (len))
@@ -1571,6 +1579,18 @@
 
     DPRINTF("All memory is saved\n");
 
+    vmce_while_monitor = xc_domain_vmce_monitor_end(xch, dom);
+    if ( vmce_while_monitor < 0 )
+    {
+        PERROR("Error when end vmce monitor\n");
+        goto out;
+    }
+    else if ( vmce_while_monitor > 0 )
+    {
+        fprintf(stderr, "vMCE occurred, abort this time and try later.\n");
+        goto out;
+    }
+
     /* After last_iter, buffer the rest of pagebuf & tailbuf data into a
      * separate output buffer and flush it after the compressed page chunks.
      */
diff -r e27a6d53ac15 tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h	Thu Oct 11 01:52:33 2012 +0800
+++ b/tools/libxc/xenctrl.h	Thu Oct 11 05:12:48 2012 +0800
@@ -575,6 +575,26 @@
                           xc_domaininfo_t *info);
 
 /**
+ * This function start monitor vmce event.
+ * @parm xch a handle to an open hypervisor interface
+ * @parm domid the domain id monitored
+ * @return <0 on failure, 0 on success
+ */
+int xc_domain_vmce_monitor_start(xc_interface *xch,
+                                 uint32_t domid);
+
+/**
+ * This function end monitor vmce event
+ * @parm xch a handle to an open hypervisor interface
+ * @parm domid the domain id monitored
+ * @return < 0 on failure, >= 0 on success while
+ *   = 0 on no vmce occurred
+ *   > 0 on vmce occurred
+ */
+int xc_domain_vmce_monitor_end(xc_interface *xch,
+                               uint32_t domid);
+
+/**
  * This function returns information about the context of a hvm domain
  * @parm xch a handle to an open hypervisor interface
  * @parm domid the domain to get information from
diff -r e27a6d53ac15 xen/arch/x86/cpu/mcheck/mce_intel.c
--- a/xen/arch/x86/cpu/mcheck/mce_intel.c	Thu Oct 11 01:52:33 2012 +0800
+++ b/xen/arch/x86/cpu/mcheck/mce_intel.c	Thu Oct 11 05:12:48 2012 +0800
@@ -359,6 +359,12 @@
                     goto vmce_failed;
                 }
 
+                if ( unlikely(d->arch.vmce_monitor) )
+                {
+                    /* vMCE occur when guest migration */
+                    d->arch.vmce_monitor = 1;
+                }
+
                 /* We will inject vMCE to DOMU*/
                 if ( inject_vmce(d, VMCE_INJECT_BROADCAST) < 0 )
                 {
diff -r e27a6d53ac15 xen/arch/x86/domctl.c
--- a/xen/arch/x86/domctl.c	Thu Oct 11 01:52:33 2012 +0800
+++ b/xen/arch/x86/domctl.c	Thu Oct 11 05:12:48 2012 +0800
@@ -1568,6 +1568,47 @@
     }
     break;
 
+    case XEN_DOMCTL_vmce_monitor_start:
+    {
+        struct domain *d;
+
+        d = rcu_lock_domain_by_id(domctl->domain);
+        if ( d != NULL )
+        {
+            if ( d->arch.vmce_monitor )
+                ret = -EBUSY;
+            else
+                d->arch.vmce_monitor = -1;
+
+            rcu_unlock_domain(d);
+        }
+        else
+            ret = -ESRCH;
+    }
+    break;
+
+    case XEN_DOMCTL_vmce_monitor_end:
+    {
+        struct domain *d;
+
+        d = rcu_lock_domain_by_id(domctl->domain);
+        if ( d != NULL)
+        {
+            if ( !d->arch.vmce_monitor )
+                ret = -EINVAL;
+            else
+            {
+                ret = d->arch.vmce_monitor > 0 ? 1 : 0;
+                d->arch.vmce_monitor = 0;
+            }
+
+            rcu_unlock_domain(d);
+        }
+        else
+            ret = -ESRCH;
+    }
+    break;
+
     default:
         ret = iommu_do_domctl(domctl, u_domctl);
         break;
diff -r e27a6d53ac15 xen/include/asm-x86/domain.h
--- a/xen/include/asm-x86/domain.h	Thu Oct 11 01:52:33 2012 +0800
+++ b/xen/include/asm-x86/domain.h	Thu Oct 11 05:12:48 2012 +0800
@@ -279,6 +279,11 @@
     bool_t has_32bit_shinfo;
     /* Domain cannot handle spurious page faults? */
     bool_t suppress_spurious_page_faults;
+    /* Monitoring guest memory copy of migration
+     * = 0 - not monitoring
+     * < 0 - monitoring
+     * > 0 - vMCE occurred while monitoring */
+    s8 vmce_monitor;
 
     /* Continuable domain_relinquish_resources(). */
     enum {
diff -r e27a6d53ac15 xen/include/public/domctl.h
--- a/xen/include/public/domctl.h	Thu Oct 11 01:52:33 2012 +0800
+++ b/xen/include/public/domctl.h	Thu Oct 11 05:12:48 2012 +0800
@@ -900,6 +900,8 @@
 #define XEN_DOMCTL_set_access_required           64
 #define XEN_DOMCTL_audit_p2m                     65
 #define XEN_DOMCTL_set_virq_handler              66
+#define XEN_DOMCTL_vmce_monitor_start            67
+#define XEN_DOMCTL_vmce_monitor_end              68
 #define XEN_DOMCTL_gdbsx_guestmemio            1000
 #define XEN_DOMCTL_gdbsx_pausevcpu             1001
 #define XEN_DOMCTL_gdbsx_unpausevcpu           1002

[-- Attachment #2: 4_vmce_when_migrate.patch --]
[-- Type: application/octet-stream, Size: 6849 bytes --]

Xen/MCE: Abort live migration when vMCE occur

This patch monitor the critical area of live migration (from vMCE point of view,
the copypages stage of migration is the critical area while other areas are not).

If a vMCE occur at the critical area of live migration, there is risk that error
data may be copied to the target. Currently we don't have convenient way to handle
this case, so for the sake of safe, we abort it and try migration later (at that
time broken page would not be mapped and copied to the target).

Signed-off-by: Liu, Jinsong <jinsong.liu@intel.com>

diff -r e27a6d53ac15 tools/libxc/xc_domain.c
--- a/tools/libxc/xc_domain.c	Thu Oct 11 01:52:33 2012 +0800
+++ b/tools/libxc/xc_domain.c	Thu Oct 11 05:12:48 2012 +0800
@@ -283,6 +283,30 @@
     return ret;
 }
 
+/* Start vmce monitor */
+int xc_domain_vmce_monitor_start(xc_interface *xch,
+                                 uint32_t domid)
+{
+    DECLARE_DOMCTL;
+
+    domctl.cmd = XEN_DOMCTL_vmce_monitor_start;
+    domctl.domain = (domid_t)domid;
+
+    return do_domctl(xch, &domctl);
+}
+
+/* End vmce monitor */
+int xc_domain_vmce_monitor_end(xc_interface *xch,
+                               uint32_t domid)
+{
+    DECLARE_DOMCTL;
+
+    domctl.cmd = XEN_DOMCTL_vmce_monitor_end;
+    domctl.domain = (domid_t)domid;
+
+    return do_domctl(xch, &domctl);
+}
+
 /* get info from hvm guest for save */
 int xc_domain_hvm_getcontext(xc_interface *xch,
                              uint32_t domid,
diff -r e27a6d53ac15 tools/libxc/xc_domain_save.c
--- a/tools/libxc/xc_domain_save.c	Thu Oct 11 01:52:33 2012 +0800
+++ b/tools/libxc/xc_domain_save.c	Thu Oct 11 05:12:48 2012 +0800
@@ -895,6 +895,8 @@
      */
     int compressing = 0;
 
+    int vmce_while_monitor = 0;
+
     int completed = 0;
 
     if ( hvm && !callbacks->switch_qemu_logdirty )
@@ -1109,6 +1111,12 @@
         goto out;
     }
 
+    if ( xc_domain_vmce_monitor_start(xch, dom) )
+    {
+        PERROR("Error when start vmce monitor\n");
+        goto out;
+    }
+
   copypages:
 #define wrexact(fd, buf, len) write_buffer(xch, last_iter, ob, (fd), (buf), (len))
 #define wruncached(fd, live, buf, len) write_uncached(xch, last_iter, ob, (fd), (buf), (len))
@@ -1571,6 +1579,18 @@
 
     DPRINTF("All memory is saved\n");
 
+    vmce_while_monitor = xc_domain_vmce_monitor_end(xch, dom);
+    if ( vmce_while_monitor < 0 )
+    {
+        PERROR("Error when end vmce monitor\n");
+        goto out;
+    }
+    else if ( vmce_while_monitor > 0 )
+    {
+        fprintf(stderr, "vMCE occurred, abort this time and try later.\n");
+        goto out;
+    }
+
     /* After last_iter, buffer the rest of pagebuf & tailbuf data into a
      * separate output buffer and flush it after the compressed page chunks.
      */
diff -r e27a6d53ac15 tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h	Thu Oct 11 01:52:33 2012 +0800
+++ b/tools/libxc/xenctrl.h	Thu Oct 11 05:12:48 2012 +0800
@@ -575,6 +575,26 @@
                           xc_domaininfo_t *info);
 
 /**
+ * This function start monitor vmce event.
+ * @parm xch a handle to an open hypervisor interface
+ * @parm domid the domain id monitored
+ * @return <0 on failure, 0 on success
+ */
+int xc_domain_vmce_monitor_start(xc_interface *xch,
+                                 uint32_t domid);
+
+/**
+ * This function end monitor vmce event
+ * @parm xch a handle to an open hypervisor interface
+ * @parm domid the domain id monitored
+ * @return < 0 on failure, >= 0 on success while
+ *   = 0 on no vmce occurred
+ *   > 0 on vmce occurred
+ */
+int xc_domain_vmce_monitor_end(xc_interface *xch,
+                               uint32_t domid);
+
+/**
  * This function returns information about the context of a hvm domain
  * @parm xch a handle to an open hypervisor interface
  * @parm domid the domain to get information from
diff -r e27a6d53ac15 xen/arch/x86/cpu/mcheck/mce_intel.c
--- a/xen/arch/x86/cpu/mcheck/mce_intel.c	Thu Oct 11 01:52:33 2012 +0800
+++ b/xen/arch/x86/cpu/mcheck/mce_intel.c	Thu Oct 11 05:12:48 2012 +0800
@@ -359,6 +359,12 @@
                     goto vmce_failed;
                 }
 
+                if ( unlikely(d->arch.vmce_monitor) )
+                {
+                    /* vMCE occur when guest migration */
+                    d->arch.vmce_monitor = 1;
+                }
+
                 /* We will inject vMCE to DOMU*/
                 if ( inject_vmce(d, VMCE_INJECT_BROADCAST) < 0 )
                 {
diff -r e27a6d53ac15 xen/arch/x86/domctl.c
--- a/xen/arch/x86/domctl.c	Thu Oct 11 01:52:33 2012 +0800
+++ b/xen/arch/x86/domctl.c	Thu Oct 11 05:12:48 2012 +0800
@@ -1568,6 +1568,47 @@
     }
     break;
 
+    case XEN_DOMCTL_vmce_monitor_start:
+    {
+        struct domain *d;
+
+        d = rcu_lock_domain_by_id(domctl->domain);
+        if ( d != NULL )
+        {
+            if ( d->arch.vmce_monitor )
+                ret = -EBUSY;
+            else
+                d->arch.vmce_monitor = -1;
+
+            rcu_unlock_domain(d);
+        }
+        else
+            ret = -ESRCH;
+    }
+    break;
+
+    case XEN_DOMCTL_vmce_monitor_end:
+    {
+        struct domain *d;
+
+        d = rcu_lock_domain_by_id(domctl->domain);
+        if ( d != NULL)
+        {
+            if ( !d->arch.vmce_monitor )
+                ret = -EINVAL;
+            else
+            {
+                ret = d->arch.vmce_monitor > 0 ? 1 : 0;
+                d->arch.vmce_monitor = 0;
+            }
+
+            rcu_unlock_domain(d);
+        }
+        else
+            ret = -ESRCH;
+    }
+    break;
+
     default:
         ret = iommu_do_domctl(domctl, u_domctl);
         break;
diff -r e27a6d53ac15 xen/include/asm-x86/domain.h
--- a/xen/include/asm-x86/domain.h	Thu Oct 11 01:52:33 2012 +0800
+++ b/xen/include/asm-x86/domain.h	Thu Oct 11 05:12:48 2012 +0800
@@ -279,6 +279,11 @@
     bool_t has_32bit_shinfo;
     /* Domain cannot handle spurious page faults? */
     bool_t suppress_spurious_page_faults;
+    /* Monitoring guest memory copy of migration
+     * = 0 - not monitoring
+     * < 0 - monitoring
+     * > 0 - vMCE occurred while monitoring */
+    s8 vmce_monitor;
 
     /* Continuable domain_relinquish_resources(). */
     enum {
diff -r e27a6d53ac15 xen/include/public/domctl.h
--- a/xen/include/public/domctl.h	Thu Oct 11 01:52:33 2012 +0800
+++ b/xen/include/public/domctl.h	Thu Oct 11 05:12:48 2012 +0800
@@ -900,6 +900,8 @@
 #define XEN_DOMCTL_set_access_required           64
 #define XEN_DOMCTL_audit_p2m                     65
 #define XEN_DOMCTL_set_virq_handler              66
+#define XEN_DOMCTL_vmce_monitor_start            67
+#define XEN_DOMCTL_vmce_monitor_end              68
 #define XEN_DOMCTL_gdbsx_guestmemio            1000
 #define XEN_DOMCTL_gdbsx_pausevcpu             1001
 #define XEN_DOMCTL_gdbsx_unpausevcpu           1002

[-- Attachment #3: Type: text/plain, Size: 126 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 4/5] Xen/MCE: Abort live migration when vMCE occur
  2012-10-10 14:46 Liu, Jinsong
@ 2012-10-16 10:42 ` Liu, Jinsong
  2012-10-19 14:52 ` Ian Jackson
  2012-10-19 16:51 ` George Dunlap
  2 siblings, 0 replies; 20+ messages in thread
From: Liu, Jinsong @ 2012-10-16 10:42 UTC (permalink / raw)
  To: Ian Jackson, Ian Campbell, xen-devel@lists.xensource.com
  Cc: Christoph Egger, Keir (Xen.org), Jan Beulich

Hi, Campbell, Jackson

Any more comments?

Thanks,
Jinsong

Liu, Jinsong wrote:
> Xen/MCE: Abort live migration when vMCE occur
> 
> This patch monitor the critical area of live migration (from vMCE
> point of view, 
> the copypages stage of migration is the critical area while other
> areas are not). 
> 
> If a vMCE occur at the critical area of live migration, there is risk
> that error 
> data may be copied to the target. Currently we don't have convenient
> way to handle 
> this case, so for the sake of safe, we abort it and try migration
> later (at that 
> time broken page would not be mapped and copied to the target).
> 
> Signed-off-by: Liu, Jinsong <jinsong.liu@intel.com>
> 
> diff -r e27a6d53ac15 tools/libxc/xc_domain.c
> --- a/tools/libxc/xc_domain.c	Thu Oct 11 01:52:33 2012 +0800
> +++ b/tools/libxc/xc_domain.c	Thu Oct 11 05:12:48 2012 +0800
> @@ -283,6 +283,30 @@
>      return ret;
>  }
> 
> +/* Start vmce monitor */
> +int xc_domain_vmce_monitor_start(xc_interface *xch,
> +                                 uint32_t domid)
> +{
> +    DECLARE_DOMCTL;
> +
> +    domctl.cmd = XEN_DOMCTL_vmce_monitor_start;
> +    domctl.domain = (domid_t)domid;
> +
> +    return do_domctl(xch, &domctl);
> +}
> +
> +/* End vmce monitor */
> +int xc_domain_vmce_monitor_end(xc_interface *xch,
> +                               uint32_t domid)
> +{
> +    DECLARE_DOMCTL;
> +
> +    domctl.cmd = XEN_DOMCTL_vmce_monitor_end;
> +    domctl.domain = (domid_t)domid;
> +
> +    return do_domctl(xch, &domctl);
> +}
> +
>  /* get info from hvm guest for save */
>  int xc_domain_hvm_getcontext(xc_interface *xch,
>                               uint32_t domid,
> diff -r e27a6d53ac15 tools/libxc/xc_domain_save.c
> --- a/tools/libxc/xc_domain_save.c	Thu Oct 11 01:52:33 2012 +0800
> +++ b/tools/libxc/xc_domain_save.c	Thu Oct 11 05:12:48 2012 +0800
> @@ -895,6 +895,8 @@
>       */
>      int compressing = 0;
> 
> +    int vmce_while_monitor = 0;
> +
>      int completed = 0;
> 
>      if ( hvm && !callbacks->switch_qemu_logdirty )
> @@ -1109,6 +1111,12 @@
>          goto out;
>      }
> 
> +    if ( xc_domain_vmce_monitor_start(xch, dom) )
> +    {
> +        PERROR("Error when start vmce monitor\n");
> +        goto out;
> +    }
> +
>    copypages:
>  #define wrexact(fd, buf, len) write_buffer(xch, last_iter, ob, (fd),
>  (buf), (len)) #define wruncached(fd, live, buf, len)
> write_uncached(xch, last_iter, ob, (fd), (buf), (len)) @@ -1571,6
> +1579,18 @@ 
> 
>      DPRINTF("All memory is saved\n");
> 
> +    vmce_while_monitor = xc_domain_vmce_monitor_end(xch, dom);
> +    if ( vmce_while_monitor < 0 )
> +    {
> +        PERROR("Error when end vmce monitor\n");
> +        goto out;
> +    }
> +    else if ( vmce_while_monitor > 0 )
> +    {
> +        fprintf(stderr, "vMCE occurred, abort this time and try
> later.\n"); +        goto out;
> +    }
> +
>      /* After last_iter, buffer the rest of pagebuf & tailbuf data
> into a 
>       * separate output buffer and flush it after the compressed page
>       chunks. */
> diff -r e27a6d53ac15 tools/libxc/xenctrl.h
> --- a/tools/libxc/xenctrl.h	Thu Oct 11 01:52:33 2012 +0800
> +++ b/tools/libxc/xenctrl.h	Thu Oct 11 05:12:48 2012 +0800
> @@ -575,6 +575,26 @@
>                            xc_domaininfo_t *info);
> 
>  /**
> + * This function start monitor vmce event.
> + * @parm xch a handle to an open hypervisor interface
> + * @parm domid the domain id monitored
> + * @return <0 on failure, 0 on success
> + */
> +int xc_domain_vmce_monitor_start(xc_interface *xch,
> +                                 uint32_t domid);
> +
> +/**
> + * This function end monitor vmce event
> + * @parm xch a handle to an open hypervisor interface
> + * @parm domid the domain id monitored
> + * @return < 0 on failure, >= 0 on success while
> + *   = 0 on no vmce occurred
> + *   > 0 on vmce occurred
> + */
> +int xc_domain_vmce_monitor_end(xc_interface *xch,
> +                               uint32_t domid);
> +
> +/**
>   * This function returns information about the context of a hvm
> domain 
>   * @parm xch a handle to an open hypervisor interface
>   * @parm domid the domain to get information from
> diff -r e27a6d53ac15 xen/arch/x86/cpu/mcheck/mce_intel.c
> --- a/xen/arch/x86/cpu/mcheck/mce_intel.c	Thu Oct 11 01:52:33 2012
> +0800 +++ b/xen/arch/x86/cpu/mcheck/mce_intel.c	Thu Oct 11 05:12:48
> 2012 +0800 @@ -359,6 +359,12 @@
>                      goto vmce_failed;
>                  }
> 
> +                if ( unlikely(d->arch.vmce_monitor) )
> +                {
> +                    /* vMCE occur when guest migration */
> +                    d->arch.vmce_monitor = 1;
> +                }
> +
>                  /* We will inject vMCE to DOMU*/
>                  if ( inject_vmce(d, VMCE_INJECT_BROADCAST) < 0 )
>                  {
> diff -r e27a6d53ac15 xen/arch/x86/domctl.c
> --- a/xen/arch/x86/domctl.c	Thu Oct 11 01:52:33 2012 +0800
> +++ b/xen/arch/x86/domctl.c	Thu Oct 11 05:12:48 2012 +0800
> @@ -1568,6 +1568,47 @@
>      }
>      break;
> 
> +    case XEN_DOMCTL_vmce_monitor_start:
> +    {
> +        struct domain *d;
> +
> +        d = rcu_lock_domain_by_id(domctl->domain);
> +        if ( d != NULL )
> +        {
> +            if ( d->arch.vmce_monitor )
> +                ret = -EBUSY;
> +            else
> +                d->arch.vmce_monitor = -1;
> +
> +            rcu_unlock_domain(d);
> +        }
> +        else
> +            ret = -ESRCH;
> +    }
> +    break;
> +
> +    case XEN_DOMCTL_vmce_monitor_end:
> +    {
> +        struct domain *d;
> +
> +        d = rcu_lock_domain_by_id(domctl->domain);
> +        if ( d != NULL)
> +        {
> +            if ( !d->arch.vmce_monitor )
> +                ret = -EINVAL;
> +            else
> +            {
> +                ret = d->arch.vmce_monitor > 0 ? 1 : 0;
> +                d->arch.vmce_monitor = 0;
> +            }
> +
> +            rcu_unlock_domain(d);
> +        }
> +        else
> +            ret = -ESRCH;
> +    }
> +    break;
> +
>      default:
>          ret = iommu_do_domctl(domctl, u_domctl);
>          break;
> diff -r e27a6d53ac15 xen/include/asm-x86/domain.h
> --- a/xen/include/asm-x86/domain.h	Thu Oct 11 01:52:33 2012 +0800
> +++ b/xen/include/asm-x86/domain.h	Thu Oct 11 05:12:48 2012 +0800
> @@ -279,6 +279,11 @@
>      bool_t has_32bit_shinfo;
>      /* Domain cannot handle spurious page faults? */
>      bool_t suppress_spurious_page_faults;
> +    /* Monitoring guest memory copy of migration
> +     * = 0 - not monitoring
> +     * < 0 - monitoring
> +     * > 0 - vMCE occurred while monitoring */
> +    s8 vmce_monitor;
> 
>      /* Continuable domain_relinquish_resources(). */
>      enum {
> diff -r e27a6d53ac15 xen/include/public/domctl.h
> --- a/xen/include/public/domctl.h	Thu Oct 11 01:52:33 2012 +0800
> +++ b/xen/include/public/domctl.h	Thu Oct 11 05:12:48 2012 +0800
> @@ -900,6 +900,8 @@
>  #define XEN_DOMCTL_set_access_required           64
>  #define XEN_DOMCTL_audit_p2m                     65
>  #define XEN_DOMCTL_set_virq_handler              66
> +#define XEN_DOMCTL_vmce_monitor_start            67
> +#define XEN_DOMCTL_vmce_monitor_end              68
>  #define XEN_DOMCTL_gdbsx_guestmemio            1000
>  #define XEN_DOMCTL_gdbsx_pausevcpu             1001
>  #define XEN_DOMCTL_gdbsx_unpausevcpu           1002

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 4/5] Xen/MCE: Abort live migration when vMCE occur
  2012-10-10 14:46 Liu, Jinsong
  2012-10-16 10:42 ` Liu, Jinsong
@ 2012-10-19 14:52 ` Ian Jackson
  2012-10-19 20:13   ` Liu, Jinsong
  2012-10-19 16:51 ` George Dunlap
  2 siblings, 1 reply; 20+ messages in thread
From: Ian Jackson @ 2012-10-19 14:52 UTC (permalink / raw)
  To: Liu, Jinsong
  Cc: Christoph Egger, xen-devel@lists.xensource.com, Keir (Xen.org),
	Ian Campbell, Jan Beulich

Liu, Jinsong writes ("[Xen-devel] [PATCH 4/5] Xen/MCE: Abort live migration when vMCE occur"):
> This patch monitor the critical area of live migration (from vMCE
> point of view, the copypages stage of migration is the critical area
> while other areas are not).

Sorry for the delay reviewing this.

Just to be clear, can you explain what a vMCE is ?  I think I know but
I'm not entirely sure and it would be helpful if you'd confirm, as I
seem to have missed the background here.  I couldn't easily find the
0/5 posting of your series (in part because the tool you're using to
send your series doesn't link the messages together in the same
thread).

> If a vMCE occur at the critical area of live migration, there is
> risk that error data may be copied to the target. Currently we don't
> have convenient way to handle this case, so for the sake of safe, we
> abort it and try migration later (at that time broken page would not
> be mapped and copied to the target).

The "error data" that you refer to is erroneous page contents, or
something else ?

When you say "we abort it and try migration later", that's not
actually implemented in your patch, is it ?  What actually happens is
that the migration is aborted and the user is expected to retry later.

I think this situation deserves a specific error code at the very
least.  That specific error code should be plumbed up to libxl.

Wouldn't it be better to actually restart the migration somehow ?

I have some more minor comments about the implementation:

> @@ -1109,6 +1111,12 @@
>          goto out;
>      }
>  
> +    if ( xc_domain_vmce_monitor_start(xch, dom) )
> +    {
> +        PERROR("Error when start vmce monitor\n");

"Error starting vmc monitor" would be better English.  Messages sent
with PERROR should not have a \n.

> +    vmce_while_monitor = xc_domain_vmce_monitor_end(xch, dom);
> +    if ( vmce_while_monitor < 0 )
> +    {
> +        PERROR("Error when end vmce monitor\n");

Grammar and \n again.

> +    else if ( vmce_while_monitor > 0 )
> +    {
> +        fprintf(stderr, "vMCE occurred, abort this time and try later.\n");
> +        goto out;

This message should be sent with one of the logging macros, not
fprintf.  ERROR, probably.

Ian.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 4/5] Xen/MCE: Abort live migration when vMCE occur
  2012-10-10 14:46 Liu, Jinsong
  2012-10-16 10:42 ` Liu, Jinsong
  2012-10-19 14:52 ` Ian Jackson
@ 2012-10-19 16:51 ` George Dunlap
  2012-10-19 20:32   ` Liu, Jinsong
  2 siblings, 1 reply; 20+ messages in thread
From: George Dunlap @ 2012-10-19 16:51 UTC (permalink / raw)
  To: Liu, Jinsong
  Cc: Christoph Egger, xen-devel@lists.xensource.com, Keir (Xen.org),
	Ian Campbell, Ian Jackson, Jan Beulich

On Wed, Oct 10, 2012 at 3:46 PM, Liu, Jinsong <jinsong.liu@intel.com> wrote:
> Xen/MCE: Abort live migration when vMCE occur
>
> This patch monitor the critical area of live migration (from vMCE point of view,
> the copypages stage of migration is the critical area while other areas are not).
>
> If a vMCE occur at the critical area of live migration, there is risk that error
> data may be copied to the target. Currently we don't have convenient way to handle
> this case, so for the sake of safe, we abort it and try migration later (at that
> time broken page would not be mapped and copied to the target).
>
> Signed-off-by: Liu, Jinsong <jinsong.liu@intel.com>

I'm not sure exactly what this patch is meant to do -- it won't
actually stop the broken page from being read, and it won't stop the
migration in the middle; instead it will finish copying the memory
before deciding to quit.

Wouldn't your patch 5 be sufficient to deal with this case?  It seems
like the broken page would get marked as such, and then get marked
broken on the receiving side, wouldn't it?

 -George

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 4/5] Xen/MCE: Abort live migration when vMCE occur
  2012-10-19 14:52 ` Ian Jackson
@ 2012-10-19 20:13   ` Liu, Jinsong
  2012-10-22 11:32     ` Liu, Jinsong
  0 siblings, 1 reply; 20+ messages in thread
From: Liu, Jinsong @ 2012-10-19 20:13 UTC (permalink / raw)
  To: Ian Jackson
  Cc: Christoph Egger, xen-devel@lists.xensource.com, Keir (Xen.org),
	Ian Campbell, Jan Beulich

[-- Attachment #1: Type: text/plain, Size: 3809 bytes --]

Ian Jackson wrote:
> Liu, Jinsong writes ("[Xen-devel] [PATCH 4/5] Xen/MCE: Abort live
> migration when vMCE occur"): 
>> This patch monitor the critical area of live migration (from vMCE
>> point of view, the copypages stage of migration is the critical area
>> while other areas are not).
> 
> Sorry for the delay reviewing this.
> 
> Just to be clear, can you explain what a vMCE is ?  I think I know but
> I'm not entirely sure and it would be helpful if you'd confirm, as I
> seem to have missed the background here.  I couldn't easily find the
> 0/5 posting of your series (in part because the tool you're using to
> send your series doesn't link the messages together in the same
> thread).
> 

vMCE is a virtual MCE interface to guest. Its general purpose is to emulate a well defined interface to guest, so that when MCE occur in the range of guest, hypervisor can filter/expose necessary MCE error information to guest which would continue handle it.

These vMCE series patches is used to replace old xen vMCE implement, since old vMCE has some issues, including
1). old vMCE bound to host MCE, which would bring troubles like non-arch issue, save/restore issue, etc;
2). weird per-domain msr semantic
3). questionable vMCE injection method

I don't know if I have introduced it clear, but we have the Xen vMCE design doc as attached, including many vMCE details.

>> If a vMCE occur at the critical area of live migration, there is
>> risk that error data may be copied to the target. Currently we don't
>> have convenient way to handle this case, so for the sake of safe, we
>> abort it and try migration later (at that time broken page would not
>> be mapped and copied to the target).
> 
> The "error data" that you refer to is erroneous page contents, or
> something else ?

Yes, it's erroneous page contents.

> 
> When you say "we abort it and try migration later", that's not
> actually implemented in your patch, is it ?  What actually happens is
> that the migration is aborted and the user is expected to retry later.

Yes, and to make it more accurate how about update as "... we abort it. User can try migration later (at that time the broken page would not be mapped and copied to the target)"?

> 
> I think this situation deserves a specific error code at the very
> least.  That specific error code should be plumbed up to libxl.
> 
> Wouldn't it be better to actually restart the migration somehow ?

Seems libxl save/restore changed greatly recently, and I know almost nothing about the new save helper mechanism (I spend some time to study it but still not quite clear).
Maybe to achieve 'restart migration' is some overkilled/complicated for vMCE itself? after all mce during migration rarely occur in real life, and the main target of this patch is only for the sake of safe, so 'abort migration' is an acceptable option?

> 
> I have some more minor comments about the implementation:
> 
>> @@ -1109,6 +1111,12 @@
>>          goto out;
>>      }
>> 
>> +    if ( xc_domain_vmce_monitor_start(xch, dom) )
>> +    {
>> +        PERROR("Error when start vmce monitor\n");
> 
> "Error starting vmc monitor" would be better English.  Messages sent
> with PERROR should not have a \n.
> 
>> +    vmce_while_monitor = xc_domain_vmce_monitor_end(xch, dom);
>> +    if ( vmce_while_monitor < 0 )
>> +    {
>> +        PERROR("Error when end vmce monitor\n");
> 
> Grammar and \n again.
> 
>> +    else if ( vmce_while_monitor > 0 )
>> +    {
>> +        fprintf(stderr, "vMCE occurred, abort this time and try
>> later.\n"); +        goto out;
> 
> This message should be sent with one of the logging macros, not
> fprintf.  ERROR, probably.
> 
> Ian.

Will update accordingly.

Thanks,
Jinsong


[-- Attachment #2: xen vMCE design (v0 2).pdf --]
[-- Type: application/pdf, Size: 256622 bytes --]

[-- Attachment #3: Type: text/plain, Size: 126 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 4/5] Xen/MCE: Abort live migration when vMCE occur
  2012-10-19 16:51 ` George Dunlap
@ 2012-10-19 20:32   ` Liu, Jinsong
  2012-10-22 11:32     ` George Dunlap
  0 siblings, 1 reply; 20+ messages in thread
From: Liu, Jinsong @ 2012-10-19 20:32 UTC (permalink / raw)
  To: George Dunlap
  Cc: Christoph Egger, xen-devel@lists.xensource.com, Keir (Xen.org),
	Ian Campbell, Ian Jackson, Jan Beulich

George Dunlap wrote:
> On Wed, Oct 10, 2012 at 3:46 PM, Liu, Jinsong <jinsong.liu@intel.com>
> wrote: 
>> Xen/MCE: Abort live migration when vMCE occur
>> 
>> This patch monitor the critical area of live migration (from vMCE
>> point of view, the copypages stage of migration is the critical area
>> while other areas are not). 
>> 
>> If a vMCE occur at the critical area of live migration, there is
>> risk that error data may be copied to the target. Currently we don't
>> have convenient way to handle this case, so for the sake of safe, we
>> abort it and try migration later (at that time broken page would not
>> be mapped and copied to the target). 
>> 
>> Signed-off-by: Liu, Jinsong <jinsong.liu@intel.com>
> 
> I'm not sure exactly what this patch is meant to do -- it won't
> actually stop the broken page from being read, and it won't stop the
> migration in the middle; instead it will finish copying the memory
> before deciding to quit.
> 

Yes, because currently we don't have convenient way to make sure / handle whether error page copied to target or not.

> Wouldn't your patch 5 be sufficient to deal with this case?  It seems
> like the broken page would get marked as such, and then get marked
> broken on the receiving side, wouldn't it?
> 
>  -George

Seems no, patch 4 is to handle the case mce occur during migration --> under such case the broken page would mapped (at that time the page is a good page) and copy to target; While patch 5 is to handle the case mce occur beofre migration --> under such case the broken page would not mapped and so would not copy to target.

Thanks,
Jinsong

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 4/5] Xen/MCE: Abort live migration when vMCE occur
  2012-10-19 20:32   ` Liu, Jinsong
@ 2012-10-22 11:32     ` George Dunlap
  2012-10-24 14:30       ` Liu, Jinsong
  0 siblings, 1 reply; 20+ messages in thread
From: George Dunlap @ 2012-10-22 11:32 UTC (permalink / raw)
  To: Liu, Jinsong
  Cc: Christoph Egger, xen-devel@lists.xensource.com, Keir (Xen.org),
	Ian Campbell, Ian Jackson, Jan Beulich

On 19/10/12 21:32, Liu, Jinsong wrote:
>> Wouldn't your patch 5 be sufficient to deal with this case?  It seems
>> like the broken page would get marked as such, and then get marked
>> broken on the receiving side, wouldn't it?
>>
>>   -George
> Seems no, patch 4 is to handle the case mce occur during migration --> under such case the broken page would mapped (at that time the page is a good page) and copy to target; While patch 5 is to handle the case mce occur beofre migration --> under such case the broken page would not mapped and so would not copy to target.

In the "during migration", there are actually two cases to consider:
1. The page breaks before the domain save code maps it.
2. The page breaks after the domain save code has mapped it once

Patch 5 will detect a broken page when it tries to map it, and send it 
as type "broken", without data.

So in the case of #1, it will be taken care of by patch 5 without any 
changes.

In the case of #2, it seems like we could probably modify patch 5 to 
handle it.  If we mark a page dirty, then the domain save code will try 
to send it again.  When it tries to map it, it will discover that the 
page has been marked "broken", and will send it as a "broken" page, 
without data.  As long as the domain restore code marks the 
already-received page as "broken" when it receives this message, then 
everything should work as normal.

What do you think?

  -George

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 4/5] Xen/MCE: Abort live migration when vMCE occur
  2012-10-19 20:13   ` Liu, Jinsong
@ 2012-10-22 11:32     ` Liu, Jinsong
  2012-10-25 11:21       ` Ian Jackson
  0 siblings, 1 reply; 20+ messages in thread
From: Liu, Jinsong @ 2012-10-22 11:32 UTC (permalink / raw)
  To: Ian Jackson
  Cc: Liu, Jinsong, Christoph Egger, xen-devel@lists.xensource.com,
	Keir (Xen.org), Ian Campbell, Jan Beulich

[-- Attachment #1: Type: text/plain, Size: 7128 bytes --]

Update patch 4/5 as attached.

Thanks,
Jinsong

==============

Xen/MCE: Abort live migration when vMCE occur

This patch monitor the critical area of live migration (from vMCE point of view,
the copypages stage of migration is the critical area while other areas are not).

If a vMCE occur at the critical area of live migration, there is risk that error
data may be copied to the target. Currently we don't have convenient way to handle
this case, so for the sake of safe, we abort it. User can retry migration later (at
that time broken page would not be mapped and copied to the target).

Signed-off-by: Liu, Jinsong <jinsong.liu@intel.com>

diff -r e27a6d53ac15 tools/libxc/xc_domain.c
--- a/tools/libxc/xc_domain.c	Thu Oct 11 01:52:33 2012 +0800
+++ b/tools/libxc/xc_domain.c	Mon Oct 22 21:43:34 2012 +0800
@@ -283,6 +283,30 @@
     return ret;
 }
 
+/* Start vmce monitor */
+int xc_domain_vmce_monitor_start(xc_interface *xch,
+                                 uint32_t domid)
+{
+    DECLARE_DOMCTL;
+
+    domctl.cmd = XEN_DOMCTL_vmce_monitor_start;
+    domctl.domain = (domid_t)domid;
+
+    return do_domctl(xch, &domctl);
+}
+
+/* End vmce monitor */
+int xc_domain_vmce_monitor_end(xc_interface *xch,
+                               uint32_t domid)
+{
+    DECLARE_DOMCTL;
+
+    domctl.cmd = XEN_DOMCTL_vmce_monitor_end;
+    domctl.domain = (domid_t)domid;
+
+    return do_domctl(xch, &domctl);
+}
+
 /* get info from hvm guest for save */
 int xc_domain_hvm_getcontext(xc_interface *xch,
                              uint32_t domid,
diff -r e27a6d53ac15 tools/libxc/xc_domain_save.c
--- a/tools/libxc/xc_domain_save.c	Thu Oct 11 01:52:33 2012 +0800
+++ b/tools/libxc/xc_domain_save.c	Mon Oct 22 21:43:34 2012 +0800
@@ -895,6 +895,8 @@
      */
     int compressing = 0;
 
+    int vmce_while_monitor = 0;
+
     int completed = 0;
 
     if ( hvm && !callbacks->switch_qemu_logdirty )
@@ -1109,6 +1111,12 @@
         goto out;
     }
 
+    if ( xc_domain_vmce_monitor_start(xch, dom) )
+    {
+        PERROR("Error starting vmce monitor");
+        goto out;
+    }
+
   copypages:
 #define wrexact(fd, buf, len) write_buffer(xch, last_iter, ob, (fd), (buf), (len))
 #define wruncached(fd, live, buf, len) write_uncached(xch, last_iter, ob, (fd), (buf), (len))
@@ -1571,6 +1579,18 @@
 
     DPRINTF("All memory is saved\n");
 
+    vmce_while_monitor = xc_domain_vmce_monitor_end(xch, dom);
+    if ( vmce_while_monitor < 0 )
+    {
+        PERROR("Error ending vmce monitor");
+        goto out;
+    }
+    else if ( vmce_while_monitor > 0 )
+    {
+        ERROR("vMCE occurred, abort this time. User can retry later.");
+        goto out;
+    }
+
     /* After last_iter, buffer the rest of pagebuf & tailbuf data into a
      * separate output buffer and flush it after the compressed page chunks.
      */
diff -r e27a6d53ac15 tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h	Thu Oct 11 01:52:33 2012 +0800
+++ b/tools/libxc/xenctrl.h	Mon Oct 22 21:43:34 2012 +0800
@@ -575,6 +575,26 @@
                           xc_domaininfo_t *info);
 
 /**
+ * This function start monitor vmce event.
+ * @parm xch a handle to an open hypervisor interface
+ * @parm domid the domain id monitored
+ * @return <0 on failure, 0 on success
+ */
+int xc_domain_vmce_monitor_start(xc_interface *xch,
+                                 uint32_t domid);
+
+/**
+ * This function end monitor vmce event
+ * @parm xch a handle to an open hypervisor interface
+ * @parm domid the domain id monitored
+ * @return < 0 on failure, >= 0 on success while
+ *   = 0 on no vmce occurred
+ *   > 0 on vmce occurred
+ */
+int xc_domain_vmce_monitor_end(xc_interface *xch,
+                               uint32_t domid);
+
+/**
  * This function returns information about the context of a hvm domain
  * @parm xch a handle to an open hypervisor interface
  * @parm domid the domain to get information from
diff -r e27a6d53ac15 xen/arch/x86/cpu/mcheck/mce_intel.c
--- a/xen/arch/x86/cpu/mcheck/mce_intel.c	Thu Oct 11 01:52:33 2012 +0800
+++ b/xen/arch/x86/cpu/mcheck/mce_intel.c	Mon Oct 22 21:43:34 2012 +0800
@@ -359,6 +359,12 @@
                     goto vmce_failed;
                 }
 
+                if ( unlikely(d->arch.vmce_monitor) )
+                {
+                    /* vMCE occur when guest migration */
+                    d->arch.vmce_monitor = 1;
+                }
+
                 /* We will inject vMCE to DOMU*/
                 if ( inject_vmce(d, VMCE_INJECT_BROADCAST) < 0 )
                 {
diff -r e27a6d53ac15 xen/arch/x86/domctl.c
--- a/xen/arch/x86/domctl.c	Thu Oct 11 01:52:33 2012 +0800
+++ b/xen/arch/x86/domctl.c	Mon Oct 22 21:43:34 2012 +0800
@@ -1568,6 +1568,47 @@
     }
     break;
 
+    case XEN_DOMCTL_vmce_monitor_start:
+    {
+        struct domain *d;
+
+        d = rcu_lock_domain_by_id(domctl->domain);
+        if ( d != NULL )
+        {
+            if ( d->arch.vmce_monitor )
+                ret = -EBUSY;
+            else
+                d->arch.vmce_monitor = -1;
+
+            rcu_unlock_domain(d);
+        }
+        else
+            ret = -ESRCH;
+    }
+    break;
+
+    case XEN_DOMCTL_vmce_monitor_end:
+    {
+        struct domain *d;
+
+        d = rcu_lock_domain_by_id(domctl->domain);
+        if ( d != NULL)
+        {
+            if ( !d->arch.vmce_monitor )
+                ret = -EINVAL;
+            else
+            {
+                ret = d->arch.vmce_monitor > 0 ? 1 : 0;
+                d->arch.vmce_monitor = 0;
+            }
+
+            rcu_unlock_domain(d);
+        }
+        else
+            ret = -ESRCH;
+    }
+    break;
+
     default:
         ret = iommu_do_domctl(domctl, u_domctl);
         break;
diff -r e27a6d53ac15 xen/include/asm-x86/domain.h
--- a/xen/include/asm-x86/domain.h	Thu Oct 11 01:52:33 2012 +0800
+++ b/xen/include/asm-x86/domain.h	Mon Oct 22 21:43:34 2012 +0800
@@ -279,6 +279,11 @@
     bool_t has_32bit_shinfo;
     /* Domain cannot handle spurious page faults? */
     bool_t suppress_spurious_page_faults;
+    /* Monitoring guest memory copy of migration
+     * = 0 - not monitoring
+     * < 0 - monitoring
+     * > 0 - vMCE occurred while monitoring */
+    s8 vmce_monitor;
 
     /* Continuable domain_relinquish_resources(). */
     enum {
diff -r e27a6d53ac15 xen/include/public/domctl.h
--- a/xen/include/public/domctl.h	Thu Oct 11 01:52:33 2012 +0800
+++ b/xen/include/public/domctl.h	Mon Oct 22 21:43:34 2012 +0800
@@ -900,6 +900,8 @@
 #define XEN_DOMCTL_set_access_required           64
 #define XEN_DOMCTL_audit_p2m                     65
 #define XEN_DOMCTL_set_virq_handler              66
+#define XEN_DOMCTL_vmce_monitor_start            67
+#define XEN_DOMCTL_vmce_monitor_end              68
 #define XEN_DOMCTL_gdbsx_guestmemio            1000
 #define XEN_DOMCTL_gdbsx_pausevcpu             1001
 #define XEN_DOMCTL_gdbsx_unpausevcpu           1002

[-- Attachment #2: 4_vmce_when_migrate.patch --]
[-- Type: application/octet-stream, Size: 6845 bytes --]

Xen/MCE: Abort live migration when vMCE occur

This patch monitor the critical area of live migration (from vMCE point of view,
the copypages stage of migration is the critical area while other areas are not).

If a vMCE occur at the critical area of live migration, there is risk that error
data may be copied to the target. Currently we don't have convenient way to handle
this case, so for the sake of safe, we abort it. User can retry migration later (at
that time broken page would not be mapped and copied to the target).

Signed-off-by: Liu, Jinsong <jinsong.liu@intel.com>

diff -r e27a6d53ac15 tools/libxc/xc_domain.c
--- a/tools/libxc/xc_domain.c	Thu Oct 11 01:52:33 2012 +0800
+++ b/tools/libxc/xc_domain.c	Mon Oct 22 21:43:34 2012 +0800
@@ -283,6 +283,30 @@
     return ret;
 }
 
+/* Start vmce monitor */
+int xc_domain_vmce_monitor_start(xc_interface *xch,
+                                 uint32_t domid)
+{
+    DECLARE_DOMCTL;
+
+    domctl.cmd = XEN_DOMCTL_vmce_monitor_start;
+    domctl.domain = (domid_t)domid;
+
+    return do_domctl(xch, &domctl);
+}
+
+/* End vmce monitor */
+int xc_domain_vmce_monitor_end(xc_interface *xch,
+                               uint32_t domid)
+{
+    DECLARE_DOMCTL;
+
+    domctl.cmd = XEN_DOMCTL_vmce_monitor_end;
+    domctl.domain = (domid_t)domid;
+
+    return do_domctl(xch, &domctl);
+}
+
 /* get info from hvm guest for save */
 int xc_domain_hvm_getcontext(xc_interface *xch,
                              uint32_t domid,
diff -r e27a6d53ac15 tools/libxc/xc_domain_save.c
--- a/tools/libxc/xc_domain_save.c	Thu Oct 11 01:52:33 2012 +0800
+++ b/tools/libxc/xc_domain_save.c	Mon Oct 22 21:43:34 2012 +0800
@@ -895,6 +895,8 @@
      */
     int compressing = 0;
 
+    int vmce_while_monitor = 0;
+
     int completed = 0;
 
     if ( hvm && !callbacks->switch_qemu_logdirty )
@@ -1109,6 +1111,12 @@
         goto out;
     }
 
+    if ( xc_domain_vmce_monitor_start(xch, dom) )
+    {
+        PERROR("Error starting vmce monitor");
+        goto out;
+    }
+
   copypages:
 #define wrexact(fd, buf, len) write_buffer(xch, last_iter, ob, (fd), (buf), (len))
 #define wruncached(fd, live, buf, len) write_uncached(xch, last_iter, ob, (fd), (buf), (len))
@@ -1571,6 +1579,18 @@
 
     DPRINTF("All memory is saved\n");
 
+    vmce_while_monitor = xc_domain_vmce_monitor_end(xch, dom);
+    if ( vmce_while_monitor < 0 )
+    {
+        PERROR("Error ending vmce monitor");
+        goto out;
+    }
+    else if ( vmce_while_monitor > 0 )
+    {
+        ERROR("vMCE occurred, abort this time. User can retry later.");
+        goto out;
+    }
+
     /* After last_iter, buffer the rest of pagebuf & tailbuf data into a
      * separate output buffer and flush it after the compressed page chunks.
      */
diff -r e27a6d53ac15 tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h	Thu Oct 11 01:52:33 2012 +0800
+++ b/tools/libxc/xenctrl.h	Mon Oct 22 21:43:34 2012 +0800
@@ -575,6 +575,26 @@
                           xc_domaininfo_t *info);
 
 /**
+ * This function start monitor vmce event.
+ * @parm xch a handle to an open hypervisor interface
+ * @parm domid the domain id monitored
+ * @return <0 on failure, 0 on success
+ */
+int xc_domain_vmce_monitor_start(xc_interface *xch,
+                                 uint32_t domid);
+
+/**
+ * This function end monitor vmce event
+ * @parm xch a handle to an open hypervisor interface
+ * @parm domid the domain id monitored
+ * @return < 0 on failure, >= 0 on success while
+ *   = 0 on no vmce occurred
+ *   > 0 on vmce occurred
+ */
+int xc_domain_vmce_monitor_end(xc_interface *xch,
+                               uint32_t domid);
+
+/**
  * This function returns information about the context of a hvm domain
  * @parm xch a handle to an open hypervisor interface
  * @parm domid the domain to get information from
diff -r e27a6d53ac15 xen/arch/x86/cpu/mcheck/mce_intel.c
--- a/xen/arch/x86/cpu/mcheck/mce_intel.c	Thu Oct 11 01:52:33 2012 +0800
+++ b/xen/arch/x86/cpu/mcheck/mce_intel.c	Mon Oct 22 21:43:34 2012 +0800
@@ -359,6 +359,12 @@
                     goto vmce_failed;
                 }
 
+                if ( unlikely(d->arch.vmce_monitor) )
+                {
+                    /* vMCE occur when guest migration */
+                    d->arch.vmce_monitor = 1;
+                }
+
                 /* We will inject vMCE to DOMU*/
                 if ( inject_vmce(d, VMCE_INJECT_BROADCAST) < 0 )
                 {
diff -r e27a6d53ac15 xen/arch/x86/domctl.c
--- a/xen/arch/x86/domctl.c	Thu Oct 11 01:52:33 2012 +0800
+++ b/xen/arch/x86/domctl.c	Mon Oct 22 21:43:34 2012 +0800
@@ -1568,6 +1568,47 @@
     }
     break;
 
+    case XEN_DOMCTL_vmce_monitor_start:
+    {
+        struct domain *d;
+
+        d = rcu_lock_domain_by_id(domctl->domain);
+        if ( d != NULL )
+        {
+            if ( d->arch.vmce_monitor )
+                ret = -EBUSY;
+            else
+                d->arch.vmce_monitor = -1;
+
+            rcu_unlock_domain(d);
+        }
+        else
+            ret = -ESRCH;
+    }
+    break;
+
+    case XEN_DOMCTL_vmce_monitor_end:
+    {
+        struct domain *d;
+
+        d = rcu_lock_domain_by_id(domctl->domain);
+        if ( d != NULL)
+        {
+            if ( !d->arch.vmce_monitor )
+                ret = -EINVAL;
+            else
+            {
+                ret = d->arch.vmce_monitor > 0 ? 1 : 0;
+                d->arch.vmce_monitor = 0;
+            }
+
+            rcu_unlock_domain(d);
+        }
+        else
+            ret = -ESRCH;
+    }
+    break;
+
     default:
         ret = iommu_do_domctl(domctl, u_domctl);
         break;
diff -r e27a6d53ac15 xen/include/asm-x86/domain.h
--- a/xen/include/asm-x86/domain.h	Thu Oct 11 01:52:33 2012 +0800
+++ b/xen/include/asm-x86/domain.h	Mon Oct 22 21:43:34 2012 +0800
@@ -279,6 +279,11 @@
     bool_t has_32bit_shinfo;
     /* Domain cannot handle spurious page faults? */
     bool_t suppress_spurious_page_faults;
+    /* Monitoring guest memory copy of migration
+     * = 0 - not monitoring
+     * < 0 - monitoring
+     * > 0 - vMCE occurred while monitoring */
+    s8 vmce_monitor;
 
     /* Continuable domain_relinquish_resources(). */
     enum {
diff -r e27a6d53ac15 xen/include/public/domctl.h
--- a/xen/include/public/domctl.h	Thu Oct 11 01:52:33 2012 +0800
+++ b/xen/include/public/domctl.h	Mon Oct 22 21:43:34 2012 +0800
@@ -900,6 +900,8 @@
 #define XEN_DOMCTL_set_access_required           64
 #define XEN_DOMCTL_audit_p2m                     65
 #define XEN_DOMCTL_set_virq_handler              66
+#define XEN_DOMCTL_vmce_monitor_start            67
+#define XEN_DOMCTL_vmce_monitor_end              68
 #define XEN_DOMCTL_gdbsx_guestmemio            1000
 #define XEN_DOMCTL_gdbsx_pausevcpu             1001
 #define XEN_DOMCTL_gdbsx_unpausevcpu           1002

[-- Attachment #3: Type: text/plain, Size: 126 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 4/5] Xen/MCE: Abort live migration when vMCE occur
  2012-10-22 11:32     ` George Dunlap
@ 2012-10-24 14:30       ` Liu, Jinsong
  0 siblings, 0 replies; 20+ messages in thread
From: Liu, Jinsong @ 2012-10-24 14:30 UTC (permalink / raw)
  To: George Dunlap
  Cc: Christoph Egger, xen-devel@lists.xensource.com, Keir (Xen.org),
	Ian Campbell, Ian Jackson, Jan Beulich

George Dunlap wrote:
> On 19/10/12 21:32, Liu, Jinsong wrote:
>>> Wouldn't your patch 5 be sufficient to deal with this case?  It
>>> seems like the broken page would get marked as such, and then get
>>> marked broken on the receiving side, wouldn't it?
>>> 
>>>   -George
>> Seems no, patch 4 is to handle the case mce occur during migration
>> --> under such case the broken page would mapped (at that time the
>> page is a good page) and copy to target; While patch 5 is to handle
>> the case mce occur beofre migration --> under such case the broken
>> page would not mapped and so would not copy to target.    
> 
> In the "during migration", there are actually two cases to consider:
> 1. The page breaks before the domain save code maps it.
> 2. The page breaks after the domain save code has mapped it once
> 
> Patch 5 will detect a broken page when it tries to map it, and send it
> as type "broken", without data.
> 
> So in the case of #1, it will be taken care of by patch 5 without any
> changes.

Yes, exactly.

> 
> In the case of #2, it seems like we could probably modify patch 5 to
> handle it.  If we mark a page dirty, then the domain save code will
> try to send it again.  When it tries to map it, it will discover that
> the page has been marked "broken", and will send it as a "broken"
> page, without data.  As long as the domain restore code marks the
> already-received page as "broken" when it receives this message, then
> everything should work as normal.
> 
> What do you think?
> 
>   -George

Yep, sounds perfect! will update & test later.

Thanks,
Jinsong

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 4/5] Xen/MCE: Abort live migration when vMCE occur
  2012-10-22 11:32     ` Liu, Jinsong
@ 2012-10-25 11:21       ` Ian Jackson
  2012-10-25 12:32         ` Jan Beulich
  0 siblings, 1 reply; 20+ messages in thread
From: Ian Jackson @ 2012-10-25 11:21 UTC (permalink / raw)
  To: Liu, Jinsong
  Cc: Christoph Egger, xen-devel@lists.xensource.com, Keir (Xen.org),
	Ian Campbell, Jan Beulich

Liu, Jinsong writes ("Re: [Xen-devel] [PATCH 4/5] Xen/MCE: Abort live migration when	vMCE	occur"):
> Update patch 4/5 as attached.

Thanks.  As for the tools parts:

Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>

Ian.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 4/5] Xen/MCE: Abort live migration when vMCE occur
  2012-10-25 11:21       ` Ian Jackson
@ 2012-10-25 12:32         ` Jan Beulich
  2012-10-25 12:38           ` Ian Jackson
  2012-10-25 12:44           ` Liu, Jinsong
  0 siblings, 2 replies; 20+ messages in thread
From: Jan Beulich @ 2012-10-25 12:32 UTC (permalink / raw)
  To: George Dunlap, Ian Jackson, Jinsong Liu
  Cc: Christoph Egger, xen-devel@lists.xensource.com, Keir (Xen.org),
	IanCampbell

>>> On 25.10.12 at 13:21, Ian Jackson <Ian.Jackson@eu.citrix.com> wrote:
> Liu, Jinsong writes ("Re: [Xen-devel] [PATCH 4/5] Xen/MCE: Abort live 
> migration when	vMCE	occur"):
>> Update patch 4/5 as attached.
> 
> Thanks.  As for the tools parts:
> 
> Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>

Now I'm confused - wasn't the earlier discussion leading towards
this patch being unnecessary (patch alone 5 being sufficient)?

Anyway, I think there were resubmission plans for both of the
remaining patches anyway - Jinsong?

Jan

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 4/5] Xen/MCE: Abort live migration when vMCE occur
  2012-10-25 12:32         ` Jan Beulich
@ 2012-10-25 12:38           ` Ian Jackson
  2012-10-25 12:44           ` Liu, Jinsong
  1 sibling, 0 replies; 20+ messages in thread
From: Ian Jackson @ 2012-10-25 12:38 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Jinsong Liu, Christoph Egger, xen-devel@lists.xensource.com,
	Keir (Xen.org), Ian Campbell, George Dunlap

Jan Beulich writes ("Re: [Xen-devel] [PATCH 4/5] Xen/MCE: Abort live migration when	vMCE occur"):
> Now I'm confused - wasn't the earlier discussion leading towards
> this patch being unnecessary (patch alone 5 being sufficient)?

No.  4/5 is for MCEs which happen _during_ migration; 5/5 is for ones
which have happened previously.

> Anyway, I think there were resubmission plans for both of the
> remaining patches anyway - Jinsong?

This is the resubmitted version addressing my comments.  Unless there
are other changes needed in the hypervisor part ?

Ian.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 4/5] Xen/MCE: Abort live migration when vMCE occur
  2012-10-25 12:32         ` Jan Beulich
  2012-10-25 12:38           ` Ian Jackson
@ 2012-10-25 12:44           ` Liu, Jinsong
  2012-10-25 12:51             ` Ian Jackson
  1 sibling, 1 reply; 20+ messages in thread
From: Liu, Jinsong @ 2012-10-25 12:44 UTC (permalink / raw)
  To: Jan Beulich, George Dunlap, Ian Jackson
  Cc: Christoph Egger, xen-devel@lists.xensource.com, Keir (Xen.org),
	IanCampbell

Jan Beulich wrote:
>>>> On 25.10.12 at 13:21, Ian Jackson <Ian.Jackson@eu.citrix.com>
>>>> wrote: 
>> Liu, Jinsong writes ("Re: [Xen-devel] [PATCH 4/5] Xen/MCE: Abort live
>> migration when	vMCE	occur"):
>>> Update patch 4/5 as attached.
>> 
>> Thanks.  As for the tools parts:
>> 
>> Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
> 
> Now I'm confused - wasn't the earlier discussion leading towards
> this patch being unnecessary (patch alone 5 being sufficient)?
> 
> Anyway, I think there were resubmission plans for both of the
> remaining patches anyway - Jinsong?
> 
> Jan

A little bit confusing here.

I think IanJ acked for my updated patch according to his comments earlier. Later, George present an approach about how to handle the case 'vMCE occur during migration' (patch 4). IMO it's perfect. So please temporarily not check patch4/5 in, I will update later.

Thanks,
Jinsong

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 4/5] Xen/MCE: Abort live migration when vMCE occur
  2012-10-25 12:44           ` Liu, Jinsong
@ 2012-10-25 12:51             ` Ian Jackson
  0 siblings, 0 replies; 20+ messages in thread
From: Ian Jackson @ 2012-10-25 12:51 UTC (permalink / raw)
  To: Liu, Jinsong
  Cc: Christoph Egger, xen-devel@lists.xensource.com, Keir (Xen.org),
	Ian Campbell, George Dunlap, Ian Jackson, Jan Beulich

Liu, Jinsong writes ("RE: [Xen-devel] [PATCH 4/5] Xen/MCE: Abort live migration when	vMCE occur"):
> I think IanJ acked for my updated patch according to his comments earlier. Later, George present an approach about how to handle the case 'vMCE occur during migration' (patch 4). IMO it's perfect. So please temporarily not check patch4/5 in, I will update later.

Ah I missed George's comments, OK.

Thanks,
Ian.

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2012-10-25 12:51 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-09-18 13:16 [PATCH 4/5] Xen/MCE: Abort live migration when vMCE occur Liu, Jinsong
2012-09-18 15:29 ` Christoph Egger
2012-09-19  7:52   ` Liu, Jinsong
2012-10-10  9:10 ` Ian Campbell
2012-10-10 14:14   ` Liu, Jinsong
  -- strict thread matches above, loose matches on Subject: below --
2012-09-19  8:14 Liu, Jinsong
2012-10-10 14:46 Liu, Jinsong
2012-10-16 10:42 ` Liu, Jinsong
2012-10-19 14:52 ` Ian Jackson
2012-10-19 20:13   ` Liu, Jinsong
2012-10-22 11:32     ` Liu, Jinsong
2012-10-25 11:21       ` Ian Jackson
2012-10-25 12:32         ` Jan Beulich
2012-10-25 12:38           ` Ian Jackson
2012-10-25 12:44           ` Liu, Jinsong
2012-10-25 12:51             ` Ian Jackson
2012-10-19 16:51 ` George Dunlap
2012-10-19 20:32   ` Liu, Jinsong
2012-10-22 11:32     ` George Dunlap
2012-10-24 14:30       ` Liu, Jinsong

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).