aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/mm.c
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@suse.com>2013-01-23 14:11:39 +0100
committerJan Beulich <jbeulich@suse.com>2013-01-23 14:11:39 +0100
commitbad20150553601964143dff43d932accceba3e5e (patch)
tree7185f1c557326846a774513a38ae276d9e3e279a /xen/arch/x86/mm.c
parentb52f69ab85a35d6140ca5e8ec74240fb1e0a5e7e (diff)
downloadxen-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.c31
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(). */