diff options
author | Jan Beulich <jbeulich@suse.com> | 2013-01-23 14:13:41 +0100 |
---|---|---|
committer | Jan Beulich <jbeulich@suse.com> | 2013-01-23 14:13:41 +0100 |
commit | f697f2fc18f11c28cffc61f39025c3bfa92d376d (patch) | |
tree | e640615cef12e9e6c3400a2eabd570f19d4d078f /xen/arch/x86/mm | |
parent | bcf557675d858e3b2e92788f5424ed4bfdac413d (diff) | |
download | xen-f697f2fc18f11c28cffc61f39025c3bfa92d376d.tar.gz xen-f697f2fc18f11c28cffc61f39025c3bfa92d376d.tar.bz2 xen-f697f2fc18f11c28cffc61f39025c3bfa92d376d.zip |
x86: properly use map_domain_page() in miscellaneous places
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Keir Fraser <keir@xen.org>
Diffstat (limited to 'xen/arch/x86/mm')
-rw-r--r-- | xen/arch/x86/mm/shadow/common.c | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/xen/arch/x86/mm/shadow/common.c b/xen/arch/x86/mm/shadow/common.c index ce79131e1f..292c1f7f8f 100644 --- a/xen/arch/x86/mm/shadow/common.c +++ b/xen/arch/x86/mm/shadow/common.c @@ -3543,6 +3543,9 @@ int shadow_track_dirty_vram(struct domain *d, } else { + unsigned long map_mfn = INVALID_MFN; + void *map_sl1p = NULL; + /* Iterate over VRAM to track dirty bits. */ for ( i = 0; i < nr; i++ ) { mfn_t mfn = get_gfn_query_unlocked(d, begin_pfn + i, &t); @@ -3576,7 +3579,17 @@ int shadow_track_dirty_vram(struct domain *d, { /* Hopefully the most common case: only one mapping, * whose dirty bit we can use. */ - l1_pgentry_t *sl1e = maddr_to_virt(sl1ma); + l1_pgentry_t *sl1e; + unsigned long sl1mfn = paddr_to_pfn(sl1ma); + + if ( sl1mfn != map_mfn ) + { + if ( map_sl1p ) + sh_unmap_domain_page(map_sl1p); + map_sl1p = sh_map_domain_page(_mfn(sl1mfn)); + map_mfn = sl1mfn; + } + sl1e = map_sl1p + (sl1ma & ~PAGE_MASK); if ( l1e_get_flags(*sl1e) & _PAGE_DIRTY ) { @@ -3603,6 +3616,9 @@ int shadow_track_dirty_vram(struct domain *d, } } + if ( map_sl1p ) + sh_unmap_domain_page(map_sl1p); + rc = -EFAULT; if ( copy_to_guest(dirty_bitmap, dirty_vram->dirty_bitmap, dirty_size) == 0 ) { memset(dirty_vram->dirty_bitmap, 0, dirty_size); |