[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] shadow: check for gfn_to_mfn returning INVALID_MFN
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1211465294 -3600 # Node ID 2195290728d4774eb86bbd73a6bee07f93d9e44a # Parent b259eebb0223e58eb9caf88f80b5aae1f12fc394 shadow: check for gfn_to_mfn returning INVALID_MFN Signed-off-by: Samuel Thibault <samuel.thibault@xxxxxxxxxxxxx> --- xen/arch/x86/mm/shadow/common.c | 119 ++++++++++++++++++++++------------------ 1 files changed, 67 insertions(+), 52 deletions(-) diff -r b259eebb0223 -r 2195290728d4 xen/arch/x86/mm/shadow/common.c --- a/xen/arch/x86/mm/shadow/common.c Thu May 22 11:04:02 2008 +0100 +++ b/xen/arch/x86/mm/shadow/common.c Thu May 22 15:08:14 2008 +0100 @@ -2799,8 +2799,11 @@ int shadow_track_dirty_vram(struct domai if ( !d->dirty_vram ) { /* Just recount from start. */ - for ( i = begin_pfn; i < end_pfn; i++ ) - flush_tlb |= sh_remove_all_mappings(d->vcpu[0], gfn_to_mfn(d, i, &t)); + for ( i = begin_pfn; i < end_pfn; i++ ) { + mfn_t mfn = gfn_to_mfn(d, i, &t); + if (mfn_x(mfn) != INVALID_MFN) + flush_tlb |= sh_remove_all_mappings(d->vcpu[0], mfn); + } gdprintk(XENLOG_INFO, "tracking VRAM %lx - %lx\n", begin_pfn, end_pfn); @@ -2840,61 +2843,70 @@ int shadow_track_dirty_vram(struct domai /* Iterate over VRAM to track dirty bits. */ for ( i = 0; i < nr; i++ ) { mfn_t mfn = gfn_to_mfn(d, begin_pfn + i, &t); - struct page_info *page = mfn_to_page(mfn); - u32 count_info = page->u.inuse.type_info & PGT_count_mask; + struct page_info *page; + u32 count_info; int dirty = 0; paddr_t sl1ma = d->dirty_vram->sl1ma[i]; - switch (count_info) + if (mfn_x(mfn) == INVALID_MFN) { - case 0: - /* No guest reference, nothing to track. */ - break; - case 1: - /* One guest reference. */ - if ( sl1ma == INVALID_PADDR ) + dirty = 1; + } + else + { + page = mfn_to_page(mfn); + count_info = page->u.inuse.type_info & PGT_count_mask; + switch (count_info) { - /* We don't know which sl1e points to this, too bad. */ + case 0: + /* No guest reference, nothing to track. */ + break; + case 1: + /* One guest reference. */ + if ( sl1ma == INVALID_PADDR ) + { + /* We don't know which sl1e points to this, too bad. */ + dirty = 1; + /* TODO: Heuristics for finding the single mapping of + * this gmfn */ + flush_tlb |= sh_remove_all_mappings(d->vcpu[0], mfn); + } + else + { + /* Hopefully the most common case: only one mapping, + * whose dirty bit we can use. */ + l1_pgentry_t *sl1e; +#ifdef __i386__ + void *sl1p = map_sl1p; + unsigned long sl1mfn = paddr_to_pfn(sl1ma); + + if ( sl1mfn != map_mfn ) { + if ( map_sl1p ) + sh_unmap_domain_page(map_sl1p); + map_sl1p = sl1p = sh_map_domain_page(_mfn(sl1mfn)); + map_mfn = sl1mfn; + } + sl1e = sl1p + (sl1ma & ~PAGE_MASK); +#else + sl1e = maddr_to_virt(sl1ma); +#endif + + if ( l1e_get_flags(*sl1e) & _PAGE_DIRTY ) + { + dirty = 1; + /* Note: this is atomic, so we may clear a + * _PAGE_ACCESSED set by another processor. */ + l1e_remove_flags(*sl1e, _PAGE_DIRTY); + flush_tlb = 1; + } + } + break; + default: + /* More than one guest reference, + * we don't afford tracking that. */ dirty = 1; - /* TODO: Heuristics for finding the single mapping of - * this gmfn */ - flush_tlb |= sh_remove_all_mappings(d->vcpu[0], gfn_to_mfn(d, begin_pfn + i, &t)); + break; } - else - { - /* Hopefully the most common case: only one mapping, - * whose dirty bit we can use. */ - l1_pgentry_t *sl1e; -#ifdef __i386__ - void *sl1p = map_sl1p; - unsigned long sl1mfn = paddr_to_pfn(sl1ma); - - if ( sl1mfn != map_mfn ) { - if ( map_sl1p ) - sh_unmap_domain_page(map_sl1p); - map_sl1p = sl1p = sh_map_domain_page(_mfn(sl1mfn)); - map_mfn = sl1mfn; - } - sl1e = sl1p + (sl1ma & ~PAGE_MASK); -#else - sl1e = maddr_to_virt(sl1ma); -#endif - - if ( l1e_get_flags(*sl1e) & _PAGE_DIRTY ) - { - dirty = 1; - /* Note: this is atomic, so we may clear a - * _PAGE_ACCESSED set by another processor. */ - l1e_remove_flags(*sl1e, _PAGE_DIRTY); - flush_tlb = 1; - } - } - break; - default: - /* More than one guest reference, - * we don't afford tracking that. */ - dirty = 1; - break; } if ( dirty ) @@ -2916,8 +2928,11 @@ int shadow_track_dirty_vram(struct domai { /* was clean for more than two seconds, try to disable guest * write access */ - for ( i = begin_pfn; i < end_pfn; i++ ) - flush_tlb |= sh_remove_write_access(d->vcpu[0], gfn_to_mfn(d, i, &t), 1, 0); + for ( i = begin_pfn; i < end_pfn; i++ ) { + mfn_t mfn = gfn_to_mfn(d, i, &t); + if (mfn_x(mfn) != INVALID_MFN) + flush_tlb |= sh_remove_write_access(d->vcpu[0], mfn, 1, 0); + } d->dirty_vram->last_dirty = -1; } rc = 0; _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |