diff options
author | Jan Beulich <jbeulich@suse.com> | 2013-01-23 14:03:25 +0100 |
---|---|---|
committer | Jan Beulich <jbeulich@suse.com> | 2013-01-23 14:03:25 +0100 |
commit | a2fd3bc4d44f1fca34fcfcff843b1eb940dc2c9a (patch) | |
tree | 169e29c47186cc749f0f60bb2d1d854d0c6400f7 /xen | |
parent | 3fc87c0c65f83cc613726b2c33942a19715f4289 (diff) | |
download | xen-a2fd3bc4d44f1fca34fcfcff843b1eb940dc2c9a.tar.gz xen-a2fd3bc4d44f1fca34fcfcff843b1eb940dc2c9a.tar.bz2 xen-a2fd3bc4d44f1fca34fcfcff843b1eb940dc2c9a.zip |
x86: introduce virt_to_xen_l1e()
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Keir Fraser <keir@xen.org>
Diffstat (limited to 'xen')
-rw-r--r-- | xen/arch/x86/mm.c | 5 | ||||
-rw-r--r-- | xen/arch/x86/x86_64/mm.c | 22 | ||||
-rw-r--r-- | xen/include/asm-x86/page.h | 1 |
3 files changed, 24 insertions, 4 deletions
diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index fa5fbbceaf..9c289e4221 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -5204,12 +5204,9 @@ int map_pages_to_xen( /* Normal page mapping. */ if ( !(l2e_get_flags(*pl2e) & _PAGE_PRESENT) ) { - pl1e = alloc_xen_pagetable(); + pl1e = virt_to_xen_l1e(virt); if ( pl1e == NULL ) return -ENOMEM; - clear_page(pl1e); - l2e_write(pl2e, l2e_from_pfn(virt_to_mfn(pl1e), - __PAGE_HYPERVISOR)); } else if ( l2e_get_flags(*pl2e) & _PAGE_PSE ) { diff --git a/xen/arch/x86/x86_64/mm.c b/xen/arch/x86/x86_64/mm.c index 5acad4870f..333f57a556 100644 --- a/xen/arch/x86/x86_64/mm.c +++ b/xen/arch/x86/x86_64/mm.c @@ -121,6 +121,28 @@ l2_pgentry_t *virt_to_xen_l2e(unsigned long v) return l3e_to_l2e(*pl3e) + l2_table_offset(v); } +l1_pgentry_t *virt_to_xen_l1e(unsigned long v) +{ + l2_pgentry_t *pl2e; + + pl2e = virt_to_xen_l2e(v); + if ( !pl2e ) + return NULL; + + if ( !(l2e_get_flags(*pl2e) & _PAGE_PRESENT) ) + { + l1_pgentry_t *pl1e = alloc_xen_pagetable(); + + if ( !pl1e ) + return NULL; + clear_page(pl1e); + l2e_write(pl2e, l2e_from_paddr(__pa(pl1e), __PAGE_HYPERVISOR)); + } + + BUG_ON(l2e_get_flags(*pl2e) & _PAGE_PSE); + return l2e_to_l1e(*pl2e) + l1_table_offset(v); +} + void *do_page_walk(struct vcpu *v, unsigned long addr) { unsigned long mfn = pagetable_get_pfn(v->arch.guest_table); diff --git a/xen/include/asm-x86/page.h b/xen/include/asm-x86/page.h index e4d4f85552..37b998b20e 100644 --- a/xen/include/asm-x86/page.h +++ b/xen/include/asm-x86/page.h @@ -328,6 +328,7 @@ void setup_idle_pagetable(void); /* Allocator functions for Xen pagetables. */ void *alloc_xen_pagetable(void); void free_xen_pagetable(void *v); +l1_pgentry_t *virt_to_xen_l1e(unsigned long v); l2_pgentry_t *virt_to_xen_l2e(unsigned long v); l3_pgentry_t *virt_to_xen_l3e(unsigned long v); |