[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] Added unshadowing of L2s that contain entries which are both
ChangeSet 1.1236.32.9, 2005/03/16 01:17:37+00:00, mafetter@xxxxxxxxxxxxxxxx Added unshadowing of L2s that contain entries which are both not present and non-zero. This is a hack, but ought to work OK for linux domains. Signed-off-by: michael.fetterman@xxxxxxxxxxxx arch/x86/shadow.c | 24 +++++++++++++++++++----- include/asm-x86/shadow.h | 9 +++++---- include/xen/perfc_defn.h | 1 + 3 files changed, 25 insertions(+), 9 deletions(-) diff -Nru a/xen/arch/x86/shadow.c b/xen/arch/x86/shadow.c --- a/xen/arch/x86/shadow.c 2005-04-05 12:10:22 -04:00 +++ b/xen/arch/x86/shadow.c 2005-04-05 12:10:22 -04:00 @@ -299,8 +299,6 @@ static void inline free_shadow_l2_table(struct domain *d, unsigned long smfn) { - printk("free_shadow_l2_table(smfn=%p)\n", smfn); - unsigned long *pl2e = map_domain_mem(smfn << PAGE_SHIFT); int i, external = shadow_mode_external(d); @@ -1666,6 +1664,7 @@ unsigned long smfn; unsigned long *guest, *shadow, *snapshot; int need_flush = 0, external = shadow_mode_external(d); + int unshadow; ASSERT(spin_is_locked(&d->arch.shadow_lock)); @@ -1686,6 +1685,7 @@ guest = map_domain_mem(entry->gmfn << PAGE_SHIFT); snapshot = map_domain_mem(entry->snapshot_mfn << PAGE_SHIFT); shadow = map_domain_mem(smfn << PAGE_SHIFT); + unshadow = 0; switch ( stype ) { case PGT_l1_shadow: @@ -1719,6 +1719,16 @@ // // snapshot[i] = new_pde; } + + // XXX - This hack works for linux guests. + // Need a better solution long term. + if ( !(new_pde & _PAGE_PRESENT) && unlikely(new_pde != 0) && + (frame_table[smfn].u.inuse.type_info & PGT_pinned) && + !unshadow ) + { + perfc_incrc(unshadow_l2_count); + unshadow = 1; + } } break; default: @@ -1729,6 +1739,9 @@ unmap_domain_mem(shadow); unmap_domain_mem(snapshot); unmap_domain_mem(guest); + + if ( unlikely(unshadow) ) + shadow_unpin(smfn); } return need_flush; @@ -1919,7 +1932,7 @@ struct domain *d = ed->domain; unsigned long gmfn = pagetable_val(ed->arch.guest_table) >> PAGE_SHIFT; unsigned long gpfn = __mfn_to_gpfn(d, gmfn); - unsigned long smfn, hl2mfn; + unsigned long smfn, hl2mfn, old_smfn; int max_mode = ( shadow_mode_external(d) ? SHM_external : shadow_mode_translate(d) ? SHM_translate @@ -1946,9 +1959,10 @@ smfn = shadow_l2_table(d, gpfn, gmfn); if ( !get_shadow_ref(smfn) ) BUG(); - if ( pagetable_val(ed->arch.shadow_table) ) - put_shadow_ref(pagetable_val(ed->arch.shadow_table) >> PAGE_SHIFT); + old_smfn = pagetable_val(ed->arch.shadow_table) >> PAGE_SHIFT; ed->arch.shadow_table = mk_pagetable(smfn << PAGE_SHIFT); + if ( old_smfn ) + put_shadow_ref(old_smfn); SH_VVLOG("0: __update_pagetables(gmfn=%p, smfn=%p)", gmfn, smfn); diff -Nru a/xen/include/asm-x86/shadow.h b/xen/include/asm-x86/shadow.h --- a/xen/include/asm-x86/shadow.h 2005-04-05 12:10:22 -04:00 +++ b/xen/include/asm-x86/shadow.h 2005-04-05 12:10:22 -04:00 @@ -651,7 +651,7 @@ static int inline validate_pde_change( struct domain *d, - unsigned long new_pde, + unsigned long new_gpde, unsigned long *shadow_pde_p) { unsigned long old_spde, new_spde; @@ -659,11 +659,12 @@ perfc_incrc(validate_pde_calls); old_spde = *shadow_pde_p; - l2pde_propagate_from_guest(d, &new_pde, &new_spde); + l2pde_propagate_from_guest(d, &new_gpde, &new_spde); - // XXX Shouldn't we supposed to propagate the new_pde to the guest? + // XXX Shouldn't we propagate the new_gpde to the guest? + // And then mark the guest's L2 page as dirty? - // only do the ref counting if something important changed. + // Only do the ref counting if something important changed. // if ( ((old_spde | new_spde) & _PAGE_PRESENT) && ((old_spde ^ new_spde) & (PAGE_MASK | _PAGE_PRESENT)) ) diff -Nru a/xen/include/xen/perfc_defn.h b/xen/include/xen/perfc_defn.h --- a/xen/include/xen/perfc_defn.h 2005-04-05 12:10:22 -04:00 +++ b/xen/include/xen/perfc_defn.h 2005-04-05 12:10:22 -04:00 @@ -30,6 +30,7 @@ PERFCOUNTER_CPU( shadow_set_l1e_unlinked, "shadow_set_l1e found unlinked l1" ) PERFCOUNTER_CPU( shadow_set_l1e_fail, "shadow_set_l1e failed (no sl1)" ) PERFCOUNTER_CPU( shadow_invlpg_faults, "shadow_invlpg's get_user faulted") +PERFCOUNTER_CPU( unshadow_l2_count, "unpinned L2 count") /* STATUS counters do not reset when 'P' is hit */ _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |