diff options
author | Liu Jinsong <jinsong.liu@intel.com> | 2012-12-06 10:47:22 +0000 |
---|---|---|
committer | Liu Jinsong <jinsong.liu@intel.com> | 2012-12-06 10:47:22 +0000 |
commit | b7a98e60d4516b1a2a0d5cda0773bab960d208d4 (patch) | |
tree | c5f495bced25bbbf7c0fba3473c8cfa6a963c884 /tools | |
parent | d7942d1dbe5d98cef71c00c51f2826eefb9273d0 (diff) | |
download | xen-b7a98e60d4516b1a2a0d5cda0773bab960d208d4.tar.gz xen-b7a98e60d4516b1a2a0d5cda0773bab960d208d4.tar.bz2 xen-b7a98e60d4516b1a2a0d5cda0773bab960d208d4.zip |
X86/vMCE: handle broken page with regard to migration
At the sender
xc_domain_save has a key point: 'to query the types of all the pages
with xc_get_pfn_type_batch'
1) if broken page occur before the key point, migration will be fine
since proper pfn_type and pfn number will be transferred to the
target and then take appropriate action;
2) if broken page occur after the key point, whole system will crash
and no need care migration any more;
At the target
Target will populates pages for guest. As for the case of broken page,
we prefer to keep the type of the page for the sake of seamless migration.
Target will set p2m as p2m_ram_broken for broken page. If guest access
the broken page again it will kill itself as expected.
Suggested-by: George Dunlap <george.dunlap@eu.citrix.com>
Signed-off-by: Liu Jinsong <jinsong.liu@intel.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Tim Deegan <tim@xen.org>
Committed-by: Ian Campbell <ian.campbell@citrix.com>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/libxc/xc_domain.c | 16 | ||||
-rw-r--r-- | tools/libxc/xc_domain_restore.c | 21 | ||||
-rw-r--r-- | tools/libxc/xc_domain_save.c | 13 | ||||
-rw-r--r-- | tools/libxc/xenctrl.h | 11 |
4 files changed, 58 insertions, 3 deletions
diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c index d98e68bd6d..4b82884905 100644 --- a/tools/libxc/xc_domain.c +++ b/tools/libxc/xc_domain.c @@ -283,6 +283,22 @@ int xc_domain_getinfolist(xc_interface *xch, return ret; } +/* set broken page p2m */ +int xc_set_broken_page_p2m(xc_interface *xch, + uint32_t domid, + unsigned long pfn) +{ + int ret; + DECLARE_DOMCTL; + + domctl.cmd = XEN_DOMCTL_set_broken_page_p2m; + domctl.domain = (domid_t)domid; + domctl.u.set_broken_page_p2m.pfn = pfn; + ret = do_domctl(xch, &domctl); + + return ret ? -1 : 0; +} + /* get info from hvm guest for save */ int xc_domain_hvm_getcontext(xc_interface *xch, uint32_t domid, diff --git a/tools/libxc/xc_domain_restore.c b/tools/libxc/xc_domain_restore.c index 02bfa1c163..454d2cbd49 100644 --- a/tools/libxc/xc_domain_restore.c +++ b/tools/libxc/xc_domain_restore.c @@ -1023,9 +1023,15 @@ static int pagebuf_get_one(xc_interface *xch, struct restore_ctx *ctx, countpages = count; for (i = oldcount; i < buf->nr_pages; ++i) - if ((buf->pfn_types[i] & XEN_DOMCTL_PFINFO_LTAB_MASK) == XEN_DOMCTL_PFINFO_XTAB - ||(buf->pfn_types[i] & XEN_DOMCTL_PFINFO_LTAB_MASK) == XEN_DOMCTL_PFINFO_XALLOC) + { + unsigned long pagetype; + + pagetype = buf->pfn_types[i] & XEN_DOMCTL_PFINFO_LTAB_MASK; + if ( pagetype == XEN_DOMCTL_PFINFO_XTAB || + pagetype == XEN_DOMCTL_PFINFO_BROKEN || + pagetype == XEN_DOMCTL_PFINFO_XALLOC ) --countpages; + } if (!countpages) return count; @@ -1267,6 +1273,17 @@ static int apply_batch(xc_interface *xch, uint32_t dom, struct restore_ctx *ctx, /* a bogus/unmapped/allocate-only page: skip it */ continue; + if ( pagetype == XEN_DOMCTL_PFINFO_BROKEN ) + { + if ( xc_set_broken_page_p2m(xch, dom, pfn) ) + { + ERROR("Set p2m for broken page failed, " + "dom=%d, pfn=%lx\n", dom, pfn); + goto err_mapped; + } + continue; + } + if (pfn_err[i]) { ERROR("unexpected PFN mapping failure pfn %lx map_mfn %lx p2m_mfn %lx", diff --git a/tools/libxc/xc_domain_save.c b/tools/libxc/xc_domain_save.c index d48e9c0fb0..dad681a1d0 100644 --- a/tools/libxc/xc_domain_save.c +++ b/tools/libxc/xc_domain_save.c @@ -1277,6 +1277,13 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter if ( !hvm ) gmfn = pfn_to_mfn(gmfn); + if ( pfn_type[j] == XEN_DOMCTL_PFINFO_BROKEN ) + { + pfn_type[j] |= pfn_batch[j]; + ++run; + continue; + } + if ( pfn_err[j] ) { if ( pfn_type[j] == XEN_DOMCTL_PFINFO_XTAB ) @@ -1371,8 +1378,12 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter } } - /* skip pages that aren't present or are alloc-only */ + /* + * skip pages that aren't present, + * or are broken, or are alloc-only + */ if ( pagetype == XEN_DOMCTL_PFINFO_XTAB + || pagetype == XEN_DOMCTL_PFINFO_BROKEN || pagetype == XEN_DOMCTL_PFINFO_XALLOC ) continue; diff --git a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h index 7eb57430c3..1cd13c1b34 100644 --- a/tools/libxc/xenctrl.h +++ b/tools/libxc/xenctrl.h @@ -575,6 +575,17 @@ int xc_domain_getinfolist(xc_interface *xch, xc_domaininfo_t *info); /** + * This function set p2m for broken page + * &parm xch a handle to an open hypervisor interface + * @parm domid the domain id which broken page belong to + * @parm pfn the pfn number of the broken page + * @return 0 on success, -1 on failure + */ +int xc_set_broken_page_p2m(xc_interface *xch, + uint32_t domid, + unsigned long pfn); + +/** * 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 |