@@ -333,21 +333,23 @@ void unmap_domain_page_global(const void *ptr)
mfn_t domain_page_map_to_mfn(const void *ptr)
{
unsigned long va = (unsigned long)ptr;
- const l1_pgentry_t *pl1e;
+ l1_pgentry_t l1e;
if ( va >= DIRECTMAP_VIRT_START )
return _mfn(virt_to_mfn(ptr));
if ( va >= VMAP_VIRT_START && va < VMAP_VIRT_END )
{
- pl1e = virt_to_xen_l1e(va);
+ l1_pgentry_t *pl1e = virt_to_xen_l1e(va);
BUG_ON(!pl1e);
+ l1e = *pl1e;
+ UNMAP_XEN_PAGETABLE_NEW(pl1e);
}
else
{
ASSERT(va >= MAPCACHE_VIRT_START && va < MAPCACHE_VIRT_END);
- pl1e = &__linear_l1_table[l1_linear_offset(va)];
+ l1e = __linear_l1_table[l1_linear_offset(va)];
}
- return l1e_get_mfn(*pl1e);
+ return l1e_get_mfn(l1e);
}
@@ -5024,26 +5024,44 @@ l1_pgentry_t *virt_to_xen_l1e(unsigned long v)
if ( !(l2e_get_flags(*pl2e) & _PAGE_PRESENT) )
{
bool locking = system_state > SYS_STATE_boot;
- l1_pgentry_t *l1t = alloc_xen_pagetable();
+ l1_pgentry_t *l1t;
+ mfn_t mfn;
- if ( !l1t )
+ mfn = alloc_xen_pagetable_new();
+ if ( mfn_eq(mfn, INVALID_MFN) )
goto out;
+
+ l1t = map_xen_pagetable_new(mfn);
+
if ( locking )
spin_lock(&map_pgdir_lock);
if ( !(l2e_get_flags(*pl2e) & _PAGE_PRESENT) )
{
clear_page(l1t);
- l2e_write(pl2e, l2e_from_paddr(__pa(l1t), __PAGE_HYPERVISOR));
+ l2e_write(pl2e, l2e_from_mfn(mfn, __PAGE_HYPERVISOR));
+ pl1e = l1t + l1_table_offset(v);
l1t = NULL;
}
if ( locking )
spin_unlock(&map_pgdir_lock);
+
if ( l1t )
- free_xen_pagetable(l1t);
+ {
+ ASSERT(!pl1e);
+ ASSERT(!mfn_eq(mfn, INVALID_MFN));
+ UNMAP_XEN_PAGETABLE_NEW(l1t);
+ free_xen_pagetable_new(mfn);
+ }
}
BUG_ON(l2e_get_flags(*pl2e) & _PAGE_PSE);
- pl1e = l2e_to_l1e(*pl2e) + l1_table_offset(v);
+
+ if ( !pl1e )
+ {
+ ASSERT(l2e_get_flags(*pl2e) & _PAGE_PRESENT);
+ pl1e = (l1_pgentry_t *)map_xen_pagetable_new(l2e_get_mfn(*pl2e))
+ + l1_table_offset(v);
+ }
out:
UNMAP_XEN_PAGETABLE_NEW(pl2e);
@@ -5447,6 +5465,7 @@ int map_pages_to_xen(
spin_unlock(&map_pgdir_lock);
}
end_of_loop:
+ UNMAP_XEN_PAGETABLE_NEW(pl1e);
UNMAP_XEN_PAGETABLE_NEW(pl2e);
UNMAP_XEN_PAGETABLE_NEW(pl3e);
}
@@ -5456,6 +5475,7 @@ int map_pages_to_xen(
rc = 0;
out:
+ UNMAP_XEN_PAGETABLE_NEW(pl1e);
UNMAP_XEN_PAGETABLE_NEW(pl2e);
UNMAP_XEN_PAGETABLE_NEW(pl3e);
return rc;