68 lines
3.0 KiB
Diff
68 lines
3.0 KiB
Diff
# HG changeset patch
|
|
# User Tim Deegan <Tim.Deegan@xensource.com>
|
|
# Date 1183643173 -3600
|
|
# Node ID 936aa542053d050c246825993b1213243ea2fb00
|
|
# Parent d54d47fc8c6cdea23437476407bec05d85742760
|
|
[HVM] Shadow: avoid xen crash if guest uses special memory for pagetables
|
|
(just crash the guest and don't do any more PTE propagations).
|
|
Signed-off-by: Tim Deegan <Tim.Deegan@xensource.com>
|
|
|
|
Index: xen-3.1-testing/xen/arch/x86/mm/shadow/common.c
|
|
===================================================================
|
|
--- xen-3.1-testing.orig/xen/arch/x86/mm/shadow/common.c
|
|
+++ xen-3.1-testing/xen/arch/x86/mm/shadow/common.c
|
|
@@ -474,7 +474,9 @@ void shadow_promote(struct vcpu *v, mfn_
|
|
ASSERT(mfn_valid(gmfn));
|
|
|
|
/* We should never try to promote a gmfn that has writeable mappings */
|
|
- ASSERT(sh_remove_write_access(v, gmfn, 0, 0) == 0);
|
|
+ ASSERT((page->u.inuse.type_info & PGT_type_mask) != PGT_writable_page
|
|
+ || (page->u.inuse.type_info & PGT_count_mask) == 0
|
|
+ || v->domain->is_shutting_down);
|
|
|
|
/* Is the page already shadowed? */
|
|
if ( !test_and_set_bit(_PGC_page_table, &page->count_info) )
|
|
@@ -1818,11 +1820,12 @@ int sh_remove_write_access(struct vcpu *
|
|
perfc_incr(shadow_writeable_bf);
|
|
hash_foreach(v, callback_mask, callbacks, gmfn);
|
|
|
|
- /* If that didn't catch the mapping, something is very wrong */
|
|
+ /* If that didn't catch the mapping, then there's some non-pagetable
|
|
+ * mapping -- ioreq page, grant mapping, &c. */
|
|
if ( (mfn_to_page(gmfn)->u.inuse.type_info & PGT_count_mask) != 0 )
|
|
{
|
|
- SHADOW_ERROR("can't find all writeable mappings of mfn %lx: "
|
|
- "%lu left\n", mfn_x(gmfn),
|
|
+ SHADOW_ERROR("can't remove write access to mfn %lx: guest has "
|
|
+ "%lu special-use mappings of it\n", mfn_x(gmfn),
|
|
(mfn_to_page(gmfn)->u.inuse.type_info&PGT_count_mask));
|
|
domain_crash(v->domain);
|
|
}
|
|
Index: xen-3.1-testing/xen/arch/x86/mm/shadow/multi.c
|
|
===================================================================
|
|
--- xen-3.1-testing.orig/xen/arch/x86/mm/shadow/multi.c
|
|
+++ xen-3.1-testing/xen/arch/x86/mm/shadow/multi.c
|
|
@@ -2719,10 +2719,21 @@ static int sh_page_fault(struct vcpu *v,
|
|
|
|
if ( guest_walk_tables(v, va, &gw, 1) != 0 )
|
|
{
|
|
- SHADOW_PRINTK("malformed guest pagetable!");
|
|
+ SHADOW_PRINTK("malformed guest pagetable\n");
|
|
print_gw(&gw);
|
|
}
|
|
|
|
+ /* It's possible that the guest has put pagetables in memory that it has
|
|
+ * already used for some special purpose (ioreq pages, or granted pages).
|
|
+ * If that happens we'll have killed the guest already but it's still not
|
|
+ * safe to propagate entries out of the guest PT so get out now. */
|
|
+ if ( unlikely(d->is_shutting_down) )
|
|
+ {
|
|
+ SHADOW_PRINTK("guest is shutting down\n");
|
|
+ shadow_unlock(d);
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
sh_audit_gw(v, &gw);
|
|
|
|
// We do not look at the gw->l1e, as that will not exist for superpages.
|