@@ -167,15 +167,25 @@ static void __init replace_va_mapping(struct domain *d, l4_pgentry_t *l4start,
unsigned long va, mfn_t mfn)
{
l4_pgentry_t *pl4e = l4start + l4_table_offset(va);
- l3_pgentry_t *pl3e = l4e_to_l3e(*pl4e) + l3_table_offset(va);
- l2_pgentry_t *pl2e = l3e_to_l2e(*pl3e) + l2_table_offset(va);
- l1_pgentry_t *pl1e = l2e_to_l1e(*pl2e) + l1_table_offset(va);
- struct page_info *page = mfn_to_page(l1e_get_mfn(*pl1e));
+ l3_pgentry_t *pl3e;
+ l2_pgentry_t *pl2e;
+ l1_pgentry_t *pl1e;
- put_page_and_type(page);
+ pl3e = map_xen_pagetable_new(l4e_get_mfn(*pl4e));
+ pl3e += l3_table_offset(va);
+ pl2e = map_xen_pagetable_new(l3e_get_mfn(*pl3e));
+ pl2e += l2_table_offset(va);
+ pl1e = map_xen_pagetable_new(l2e_get_mfn(*pl2e));
+ pl1e += l1_table_offset(va);
+
+ put_page_and_type(mfn_to_page(l1e_get_mfn(*pl1e)));
*pl1e = l1e_from_mfn(mfn, (!is_pv_32bit_domain(d) ? L1_PROT
: COMPAT_L1_PROT));
+
+ UNMAP_XEN_PAGETABLE_NEW(pl1e);
+ UNMAP_XEN_PAGETABLE_NEW(pl2e);
+ UNMAP_XEN_PAGETABLE_NEW(pl3e);
}
static void evtchn_reserve(struct domain *d, unsigned int port)