@@ -672,8 +672,8 @@ static int clone_mapping(const void *ptr, root_pgentry_t *rpt)
unsigned long linear = (unsigned long)ptr, pfn;
unsigned int flags;
l3_pgentry_t *pl3e;
- l2_pgentry_t *pl2e;
- l1_pgentry_t *pl1e;
+ l2_pgentry_t *pl2e = NULL;
+ l1_pgentry_t *pl1e = NULL;
int rc = 0;
/*
@@ -688,7 +688,7 @@ static int clone_mapping(const void *ptr, root_pgentry_t *rpt)
(linear >= XEN_VIRT_END && linear < DIRECTMAP_VIRT_START) )
return -EINVAL;
- pl3e = l4e_to_l3e(idle_pg_table[root_table_offset(linear)]) +
+ pl3e = map_l3t_from_l4e(idle_pg_table[root_table_offset(linear)]) +
l3_table_offset(linear);
flags = l3e_get_flags(*pl3e);
@@ -701,7 +701,7 @@ static int clone_mapping(const void *ptr, root_pgentry_t *rpt)
}
else
{
- pl2e = l3e_to_l2e(*pl3e) + l2_table_offset(linear);
+ pl2e = map_l2t_from_l3e(*pl3e) + l2_table_offset(linear);
flags = l2e_get_flags(*pl2e);
ASSERT(flags & _PAGE_PRESENT);
if ( flags & _PAGE_PSE )
@@ -712,7 +712,7 @@ static int clone_mapping(const void *ptr, root_pgentry_t *rpt)
}
else
{
- pl1e = l2e_to_l1e(*pl2e) + l1_table_offset(linear);
+ pl1e = map_l1t_from_l2e(*pl2e) + l1_table_offset(linear);
flags = l1e_get_flags(*pl1e);
if ( !(flags & _PAGE_PRESENT) )
goto out;
@@ -720,51 +720,58 @@ static int clone_mapping(const void *ptr, root_pgentry_t *rpt)
}
}
+ UNMAP_DOMAIN_PAGE(pl1e);
+ UNMAP_DOMAIN_PAGE(pl2e);
+ UNMAP_DOMAIN_PAGE(pl3e);
+
if ( !(root_get_flags(rpt[root_table_offset(linear)]) & _PAGE_PRESENT) )
{
- pl3e = alloc_xen_pagetable();
+ mfn_t l3mfn;
+
+ pl3e = alloc_map_clear_xen_pt(&l3mfn);
rc = -ENOMEM;
if ( !pl3e )
goto out;
- clear_page(pl3e);
l4e_write(&rpt[root_table_offset(linear)],
- l4e_from_paddr(__pa(pl3e), __PAGE_HYPERVISOR));
+ l4e_from_mfn(l3mfn, __PAGE_HYPERVISOR));
}
else
- pl3e = l4e_to_l3e(rpt[root_table_offset(linear)]);
+ pl3e = map_l3t_from_l4e(rpt[root_table_offset(linear)]);
pl3e += l3_table_offset(linear);
if ( !(l3e_get_flags(*pl3e) & _PAGE_PRESENT) )
{
- pl2e = alloc_xen_pagetable();
+ mfn_t l2mfn;
+
+ pl2e = alloc_map_clear_xen_pt(&l2mfn);
rc = -ENOMEM;
if ( !pl2e )
goto out;
- clear_page(pl2e);
- l3e_write(pl3e, l3e_from_paddr(__pa(pl2e), __PAGE_HYPERVISOR));
+ l3e_write(pl3e, l3e_from_mfn(l2mfn, __PAGE_HYPERVISOR));
}
else
{
ASSERT(!(l3e_get_flags(*pl3e) & _PAGE_PSE));
- pl2e = l3e_to_l2e(*pl3e);
+ pl2e = map_l2t_from_l3e(*pl3e);
}
pl2e += l2_table_offset(linear);
if ( !(l2e_get_flags(*pl2e) & _PAGE_PRESENT) )
{
- pl1e = alloc_xen_pagetable();
+ mfn_t l1mfn;
+
+ pl1e = alloc_map_clear_xen_pt(&l1mfn);
rc = -ENOMEM;
if ( !pl1e )
goto out;
- clear_page(pl1e);
- l2e_write(pl2e, l2e_from_paddr(__pa(pl1e), __PAGE_HYPERVISOR));
+ l2e_write(pl2e, l2e_from_mfn(l1mfn, __PAGE_HYPERVISOR));
}
else
{
ASSERT(!(l2e_get_flags(*pl2e) & _PAGE_PSE));
- pl1e = l2e_to_l1e(*pl2e);
+ pl1e = map_l1t_from_l2e(*pl2e);
}
pl1e += l1_table_offset(linear);
@@ -780,6 +787,9 @@ static int clone_mapping(const void *ptr, root_pgentry_t *rpt)
rc = 0;
out:
+ unmap_domain_page(pl1e);
+ unmap_domain_page(pl2e);
+ unmap_domain_page(pl3e);
return rc;
}