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 /xen/arch/x86/domctl.c | |
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 'xen/arch/x86/domctl.c')
-rw-r--r-- | xen/arch/x86/domctl.c | 36 |
1 files changed, 34 insertions, 2 deletions
diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c index 508c77c899..83daebb26a 100644 --- a/xen/arch/x86/domctl.c +++ b/xen/arch/x86/domctl.c @@ -209,12 +209,18 @@ long arch_do_domctl( for ( j = 0; j < k; j++ ) { unsigned long type = 0; + p2m_type_t t; - page = get_page_from_gfn(d, arr[j], NULL, P2M_ALLOC); + page = get_page_from_gfn(d, arr[j], &t, P2M_ALLOC); if ( unlikely(!page) || unlikely(is_xen_heap_page(page)) ) - type = XEN_DOMCTL_PFINFO_XTAB; + { + if ( p2m_is_broken(t) ) + type = XEN_DOMCTL_PFINFO_BROKEN; + else + type = XEN_DOMCTL_PFINFO_XTAB; + } else { switch( page->u.inuse.type_info & PGT_type_mask ) @@ -235,6 +241,9 @@ long arch_do_domctl( if ( page->u.inuse.type_info & PGT_pinned ) type |= XEN_DOMCTL_PFINFO_LPINTAB; + + if ( page->count_info & PGC_broken ) + type = XEN_DOMCTL_PFINFO_BROKEN; } if ( page ) @@ -1568,6 +1577,29 @@ long arch_do_domctl( } break; + case XEN_DOMCTL_set_broken_page_p2m: + { + struct domain *d; + + d = rcu_lock_domain_by_id(domctl->domain); + if ( d != NULL ) + { + p2m_type_t pt; + unsigned long pfn = domctl->u.set_broken_page_p2m.pfn; + mfn_t mfn = get_gfn_query(d, pfn, &pt); + + if ( unlikely(!mfn_valid(mfn_x(mfn)) || !p2m_is_ram(pt) || + (p2m_change_type(d, pfn, pt, p2m_ram_broken) != pt)) ) + ret = -EINVAL; + + put_gfn(d, pfn); + rcu_unlock_domain(d); + } + else + ret = -ESRCH; + } + break; + default: ret = iommu_do_domctl(domctl, u_domctl); break; |