x86_64/mm: switch to new APIs in setup_m2p_table

While doing so, avoid repetitive mapping of l2_ro_mpt by keeping it
across loops, and only unmap and map it when crossing 1G boundaries.

Signed-off-by: Wei Liu <wei.liu2@citrix.com>
Signed-off-by: Hongyan Xia <hongyxia@amazon.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
Wei Liu authored and Jan Beulich committed 2021-04-22 14:13:34 +02:00
1 parent d87e3ff90d
commit 7e2fdcdb3e
1 file changed
+19 -13
+19 -13
View File
@@ -402,7 +402,8 @@ static int setup_m2p_table(struct mem_hotadd_info *info)
ASSERT(l4e_get_flags(idle_pg_table[l4_table_offset(RO_MPT_VIRT_START)])
& _PAGE_PRESENT);
l3_ro_mpt = l4e_to_l3e(idle_pg_table[l4_table_offset(RO_MPT_VIRT_START)]);
l3_ro_mpt = map_l3t_from_l4e(
idle_pg_table[l4_table_offset(RO_MPT_VIRT_START)]);
smap = (info->spfn & (~((1UL << (L2_PAGETABLE_SHIFT - 3)) -1)));
emap = ((info->epfn + ((1UL << (L2_PAGETABLE_SHIFT - 3)) - 1 )) &
@@ -420,6 +421,10 @@ static int setup_m2p_table(struct mem_hotadd_info *info)
i = smap;
while ( i < emap )
{
if ( (RO_MPT_VIRT_START + i * sizeof(*machine_to_phys_mapping)) &
((1UL << L3_PAGETABLE_SHIFT) - 1) )
UNMAP_DOMAIN_PAGE(l2_ro_mpt);
switch ( m2p_mapped(i) )
{
case M2P_1G_MAPPED:
@@ -455,32 +460,31 @@ static int setup_m2p_table(struct mem_hotadd_info *info)
ASSERT(!(l3e_get_flags(l3_ro_mpt[l3_table_offset(va)]) &
_PAGE_PSE));
if ( l3e_get_flags(l3_ro_mpt[l3_table_offset(va)]) &
_PAGE_PRESENT )
l2_ro_mpt = l3e_to_l2e(l3_ro_mpt[l3_table_offset(va)]) +
l2_table_offset(va);
if ( l2_ro_mpt )
/* nothing */;
else if ( l3e_get_flags(l3_ro_mpt[l3_table_offset(va)]) &
_PAGE_PRESENT )
l2_ro_mpt = map_l2t_from_l3e(l3_ro_mpt[l3_table_offset(va)]);
else
{
l2_ro_mpt = alloc_xen_pagetable();
mfn_t l2_ro_mpt_mfn;
l2_ro_mpt = alloc_mapped_pagetable(&l2_ro_mpt_mfn);
if ( !l2_ro_mpt )
{
ret = -ENOMEM;
goto error;
}
clear_page(l2_ro_mpt);
l3e_write(&l3_ro_mpt[l3_table_offset(va)],
l3e_from_paddr(__pa(l2_ro_mpt),
__PAGE_HYPERVISOR_RO | _PAGE_USER));
l2_ro_mpt += l2_table_offset(va);
l3e_from_mfn(l2_ro_mpt_mfn,
__PAGE_HYPERVISOR_RO | _PAGE_USER));
}
/* NB. Cannot be GLOBAL: guest user mode should not see it. */
l2e_write(l2_ro_mpt, l2e_from_mfn(mfn,
l2e_write(&l2_ro_mpt[l2_table_offset(va)], l2e_from_mfn(mfn,
/*_PAGE_GLOBAL|*/_PAGE_PSE|_PAGE_USER|_PAGE_PRESENT));
}
if ( !((unsigned long)l2_ro_mpt & ~PAGE_MASK) )
l2_ro_mpt = NULL;
i += ( 1UL << (L2_PAGETABLE_SHIFT - 3));
}
#undef CNT
@@ -488,6 +492,8 @@ static int setup_m2p_table(struct mem_hotadd_info *info)
ret = setup_compat_m2p_table(info);
error:
unmap_domain_page(l2_ro_mpt);
unmap_domain_page(l3_ro_mpt);
return ret;
}
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.