ChangeSet 1.1385.1.7, 2005/05/09 14:22:13+01:00, mafetter@xxxxxxxxxxxxxxxx
Enabling light-weight shadows (especially shadow_mode_dirty).
Light-weight shadows leave all the page ref counts based on the guest
p.t. pages,
while heavy-weight shadows do all their ref counts based on the
shadow's p.t. pages.
shadow_mode_refcounts(dom) == 1 implies heavy-weight shadows.
arch/x86/audit.c | 171 ++++++---
arch/x86/domain.c | 21 -
arch/x86/domain_build.c | 4
arch/x86/mm.c | 338 +++++++++---------
arch/x86/shadow.c | 625 +++++++++++++++++++++++++----------
arch/x86/traps.c | 5
arch/x86/vmx.c | 4
include/asm-x86/mm.h | 27 -
include/asm-x86/page.h | 2
include/asm-x86/shadow.h | 400 +++++++++++++++-------
include/asm-x86/x86_32/domain_page.h | 47 ++
include/xen/lib.h | 2
include/xen/perfc_defn.h | 6
13 files changed, 1097 insertions(+), 555 deletions(-)
diff -Nru a/xen/arch/x86/audit.c b/xen/arch/x86/audit.c
--- a/xen/arch/x86/audit.c 2005-05-09 14:07:55 -04:00
+++ b/xen/arch/x86/audit.c 2005-05-09 14:07:55 -04:00
@@ -49,7 +49,8 @@
int audit_adjust_pgtables(struct domain *d, int dir, int noisy)
{
int errors = 0;
- int shadow_enabled = shadow_mode_enabled(d) ? 1 : 0;
+ int shadow_refcounts = !!shadow_mode_refcounts(d);
+ int shadow_enabled = !!shadow_mode_enabled(d);
int l2limit;
void _adjust(struct pfn_info *page, int adjtype ADJUST_EXTRA_ARGS)
@@ -119,7 +120,7 @@
page->count_info += dir;
}
- void adjust_l2_page(unsigned long mfn)
+ void adjust_l2_page(unsigned long mfn, int shadow)
{
unsigned long *pt = map_domain_mem(mfn << PAGE_SHIFT);
int i;
@@ -133,7 +134,7 @@
if ( noisy )
{
- if ( shadow_enabled )
+ if ( shadow )
{
if ( page_get_owner(l1page) != NULL )
{
@@ -145,6 +146,17 @@
errors++;
continue;
}
+
+ u32 page_type = l1page->u.inuse.type_info &
PGT_type_mask;
+
+ if ( page_type != PGT_l1_shadow )
+ {
+ printk("Audit %d: [Shadow L2 mfn=%lx i=%x] "
+ "Expected Shadow L1 t=%x mfn=%lx\n",
+ d->id, mfn, i,
+ l1page->u.inuse.type_info, l1mfn);
+ errors++;
+ }
}
else
{
@@ -154,7 +166,9 @@
"belonging to other dom %p (id=%d)\n",
l1mfn,
page_get_owner(l1page),
- page_get_owner(l1page)->id);
+ (page_get_owner(l1page)
+ ? page_get_owner(l1page)->id
+ : -1));
errors++;
continue;
}
@@ -179,7 +193,7 @@
}
}
- adjust(l1page, !shadow_enabled);
+ adjust(l1page, !shadow);
}
}
@@ -280,7 +294,7 @@
errors++;
}
- if ( shadow_enabled &&
+ if ( shadow_refcounts &&
page_is_page_table(gpage) &&
! page_out_of_sync(gpage) )
{
@@ -336,19 +350,21 @@
break;
case PGT_l1_shadow:
adjust(pfn_to_page(gmfn), 0);
- adjust_l1_page(smfn);
+ if ( shadow_refcounts )
+ adjust_l1_page(smfn);
if ( page->u.inuse.type_info & PGT_pinned )
adjust(page, 0);
break;
case PGT_hl2_shadow:
adjust(pfn_to_page(gmfn), 0);
- adjust_hl2_page(smfn);
+ if ( shadow_refcounts )
+ adjust_hl2_page(smfn);
if ( page->u.inuse.type_info & PGT_pinned )
adjust(page, 0);
break;
case PGT_l2_shadow:
adjust(pfn_to_page(gmfn), 0);
- adjust_l2_page(smfn);
+ adjust_l2_page(smfn, 1);
if ( page->u.inuse.type_info & PGT_pinned )
adjust(page, 0);
break;
@@ -391,45 +407,43 @@
struct exec_domain *ed;
for_each_exec_domain(d, ed)
- {
- if ( !shadow_enabled )
- {
- if ( pagetable_val(ed->arch.guest_table) )
- adjust(&frame_table[pagetable_val(ed->arch.guest_table)
- >> PAGE_SHIFT], 1);
- }
- else
- {
- if ( pagetable_val(ed->arch.guest_table) )
- adjust(&frame_table[pagetable_val(ed->arch.guest_table)
- >> PAGE_SHIFT], 0);
- if ( pagetable_val(ed->arch.shadow_table) )
-
adjust(&frame_table[pagetable_val(ed->arch.shadow_table)
- >> PAGE_SHIFT], 0);
- if ( ed->arch.monitor_shadow_ref )
- adjust(&frame_table[ed->arch.monitor_shadow_ref], 0);
- }
- }
+ {
+ if ( pagetable_val(ed->arch.guest_table) )
+ adjust(&frame_table[pagetable_get_pfn(ed->arch.guest_table)],
1);
+ if ( pagetable_val(ed->arch.shadow_table) )
+ adjust(&frame_table[pagetable_get_pfn(ed->arch.shadow_table)],
0);
+ if ( ed->arch.monitor_shadow_ref )
+ adjust(&frame_table[ed->arch.monitor_shadow_ref], 0);
+ }
}
void adjust_guest_pages()
{
struct list_head *list_ent = d->page_list.next;
struct pfn_info *page;
- unsigned long mfn;
+ unsigned long mfn, snapshot_mfn;
while ( list_ent != &d->page_list )
{
u32 page_type;
page = list_entry(list_ent, struct pfn_info, list);
- mfn = page_to_pfn(page);
+ snapshot_mfn = mfn = page_to_pfn(page);
page_type = page->u.inuse.type_info & PGT_type_mask;
BUG_ON(page_get_owner(page) != d);
page_count++;
+ if ( shadow_enabled && !shadow_refcounts &&
+ page_out_of_sync(page) )
+ {
+ unsigned long gpfn = __mfn_to_gpfn(d, mfn);
+ ASSERT( VALID_M2P(gpfn) );
+ snapshot_mfn = __shadow_status(d, gpfn, PGT_snapshot);
+ ASSERT( snapshot_mfn );
+ }
+
switch ( page_type )
{
case PGT_l2_page_table:
@@ -437,7 +451,7 @@
if ( noisy )
{
- if ( shadow_enabled )
+ if ( shadow_refcounts )
{
printk("Audit %d: found an L2 guest page "
"mfn=%lx t=%08x c=%08x while in shadow mode\n",
@@ -446,19 +460,22 @@
errors++;
}
- if ( (page->u.inuse.type_info & PGT_validated) !=
- PGT_validated )
+ if ( (page->u.inuse.type_info & PGT_count_mask) != 0 )
{
- printk("Audit %d: L2 mfn=%lx not validated %08x\n",
- d->id, mfn, page->u.inuse.type_info);
- errors++;
- }
+ if ( (page->u.inuse.type_info & PGT_validated) !=
+ PGT_validated )
+ {
+ printk("Audit %d: L2 mfn=%lx not validated %08x\n",
+ d->id, mfn, page->u.inuse.type_info);
+ errors++;
+ }
- if ( (page->u.inuse.type_info & PGT_pinned) != PGT_pinned )
- {
- printk("Audit %d: L2 mfn=%lx not pinned t=%08x\n",
- d->id, mfn, page->u.inuse.type_info);
- errors++;
+ if ( (page->u.inuse.type_info & PGT_pinned) !=
PGT_pinned )
+ {
+ printk("Audit %d: L2 mfn=%lx not pinned t=%08x\n",
+ d->id, mfn, page->u.inuse.type_info);
+ errors++;
+ }
}
}
@@ -466,7 +483,7 @@
adjust(page, 1);
if ( page->u.inuse.type_info & PGT_validated )
- adjust_l2_page(mfn);
+ adjust_l2_page(snapshot_mfn, 0);
break;
@@ -475,7 +492,7 @@
if ( noisy )
{
- if ( shadow_enabled )
+ if ( shadow_refcounts )
{
printk("found an L1 guest page mfn=%lx t=%08x c=%08x "
"while in shadow mode\n",
@@ -483,21 +500,24 @@
errors++;
}
- if ( (page->u.inuse.type_info & PGT_validated) !=
PGT_validated )
+ if ( (page->u.inuse.type_info & PGT_count_mask) != 0 )
{
- printk("Audit %d: L1 not validated mfn=%lx t=%08x\n",
- d->id, mfn, page->u.inuse.type_info);
- errors++;
- }
-
- if ( (page->u.inuse.type_info & PGT_pinned) != PGT_pinned )
- {
- if ( !VM_ASSIST(d, VMASST_TYPE_writable_pagetables) )
+ if ( (page->u.inuse.type_info & PGT_validated) !=
+ PGT_validated )
{
- printk("Audit %d: L1 mfn=%lx not pinned t=%08x\n",
+ printk("Audit %d: L1 not validated mfn=%lx
t=%08x\n",
d->id, mfn, page->u.inuse.type_info);
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|