diff options
author | Jan Beulich <jbeulich@suse.com> | 2013-01-23 14:11:39 +0100 |
---|---|---|
committer | Jan Beulich <jbeulich@suse.com> | 2013-01-23 14:11:39 +0100 |
commit | bad20150553601964143dff43d932accceba3e5e (patch) | |
tree | 7185f1c557326846a774513a38ae276d9e3e279a /xen/arch/x86/mm.c | |
parent | b52f69ab85a35d6140ca5e8ec74240fb1e0a5e7e (diff) | |
download | xen-bad20150553601964143dff43d932accceba3e5e.tar.gz xen-bad20150553601964143dff43d932accceba3e5e.tar.bz2 xen-bad20150553601964143dff43d932accceba3e5e.zip |
x86: properly use map_domain_page() during page table manipulation
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Keir Fraser <keir@xen.org>
Diffstat (limited to 'xen/arch/x86/mm.c')
-rw-r--r-- | xen/arch/x86/mm.c | 31 |
1 files changed, 23 insertions, 8 deletions
diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index c270c1cd29..6706f1d3cc 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -1331,7 +1331,7 @@ static int alloc_l4_table(struct page_info *page, int preemptible) { struct domain *d = page_get_owner(page); unsigned long pfn = page_to_mfn(page); - l4_pgentry_t *pl4e = page_to_virt(page); + l4_pgentry_t *pl4e = map_domain_page(pfn); unsigned int i; int rc = 0, partial = page->partial_pte; @@ -1365,12 +1365,16 @@ static int alloc_l4_table(struct page_info *page, int preemptible) put_page_from_l4e(pl4e[i], pfn, 0, 0); } if ( rc < 0 ) + { + unmap_domain_page(pl4e); return rc; + } adjust_guest_l4e(pl4e[i], d); } init_guest_l4_table(pl4e, d); + unmap_domain_page(pl4e); return rc > 0 ? 0 : rc; } @@ -1464,7 +1468,7 @@ static int free_l4_table(struct page_info *page, int preemptible) { struct domain *d = page_get_owner(page); unsigned long pfn = page_to_mfn(page); - l4_pgentry_t *pl4e = page_to_virt(page); + l4_pgentry_t *pl4e = map_domain_page(pfn); int rc = 0, partial = page->partial_pte; unsigned int i = page->nr_validated_ptes - !partial; @@ -1487,6 +1491,9 @@ static int free_l4_table(struct page_info *page, int preemptible) page->partial_pte = 0; rc = -EAGAIN; } + + unmap_domain_page(pl4e); + return rc > 0 ? 0 : rc; } @@ -4983,15 +4990,23 @@ int mmio_ro_do_page_fault(struct vcpu *v, unsigned long addr, return rc != X86EMUL_UNHANDLEABLE ? EXCRET_fault_fixed : 0; } -void free_xen_pagetable(void *v) +void *alloc_xen_pagetable(void) { - if ( system_state == SYS_STATE_early_boot ) - return; + if ( system_state != SYS_STATE_early_boot ) + { + void *ptr = alloc_xenheap_page(); - if ( is_xen_heap_page(virt_to_page(v)) ) + BUG_ON(!dom0 && !ptr); + return ptr; + } + + return mfn_to_virt(alloc_boot_pages(1, 1)); +} + +void free_xen_pagetable(void *v) +{ + if ( system_state != SYS_STATE_early_boot ) free_xenheap_page(v); - else - free_domheap_page(virt_to_page(v)); } /* Convert to from superpage-mapping flags for map_pages_to_xen(). */ |