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
|