[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH early-RFC 3/5] xen/arm: mm: Introduce helpers to prepare/enable/disable the identity mapping
From: Julien GralL <jgrall@xxxxxxxxxx> In follow-up patches we will need to have part of Xen identity mapped in order to safely switch the TTBR. On some platform, the identity mapping may have to start at 0. If we always keep the identity region mapped, NULL pointer ference would lead to access to valid mapping. It would be possible to relocate Xen to avoid clashing with address 0. However the identity mapping is only meant to be used in very limited places. Therefore it would be better to keep the identity region invalid for most of the time. Two new helpers are introduced: - prepare_identity_mapping() will setup the page-tables so it is easy to create the mapping afterwards. - update_identity_mapping() will create/remove the identity mapping Signed-off-by: Julien Grall <jgrall@xxxxxxxxxx> --- xen/arch/arm/include/asm/mm.h | 2 + xen/arch/arm/mm.c | 73 +++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/xen/arch/arm/include/asm/mm.h b/xen/arch/arm/include/asm/mm.h index 045a8ba4bb63..76973ea9a0ff 100644 --- a/xen/arch/arm/include/asm/mm.h +++ b/xen/arch/arm/include/asm/mm.h @@ -177,6 +177,8 @@ extern unsigned long total_pages; /* Boot-time pagetable setup */ extern void setup_pagetables(unsigned long boot_phys_offset); +/* Enable/disable the identity mapping */ +extern void update_identity_mapping(bool enable); /* Map FDT in boot pagetable */ extern void *early_fdt_map(paddr_t fdt_paddr); /* Remove early mappings */ diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c index 75ed9a3ce249..5c4dece16f7f 100644 --- a/xen/arch/arm/mm.c +++ b/xen/arch/arm/mm.c @@ -138,6 +138,12 @@ static DEFINE_PAGE_TABLE(cpu0_pgtable); static DEFINE_PAGE_TABLES(cpu0_dommap, DOMHEAP_SECOND_PAGES); #endif +#ifdef CONFIG_ARM_64 +static DEFINE_PAGE_TABLE(xen_first_id); +static DEFINE_PAGE_TABLE(xen_second_id); +static DEFINE_PAGE_TABLE(xen_third_id); +#endif + /* Common pagetable leaves */ /* Second level page tables. * @@ -573,6 +579,70 @@ void __init remove_early_mappings(void) BUG_ON(rc); } +/* + * The identity mapping may start at physical address 0. So don't want + * to keep it mapped longer than necessary. + * + * When this is called, we are still using the boot_pgtable. + * + * XXX: Handle Arm32 properly. + */ +static void prepare_identity_mapping(void) +{ + paddr_t id_addr = virt_to_maddr(_start); + lpae_t pte; + DECLARE_OFFSETS(id_offsets, id_addr); + + printk("id_addr 0x%lx\n", id_addr); +#ifdef CONFIG_ARM_64 + if ( id_offsets[0] != 0 ) + panic("Cannot handled ID mapping above 512GB\n"); +#endif + + /* Link first ID table */ + pte = pte_of_xenaddr((vaddr_t)xen_first_id); + pte.pt.table = 1; + pte.pt.xn = 0; + + write_pte(&boot_pgtable[id_offsets[0]], pte); + + /* Link second ID table */ + pte = pte_of_xenaddr((vaddr_t)xen_second_id); + pte.pt.table = 1; + pte.pt.xn = 0; + + write_pte(&xen_first_id[id_offsets[1]], pte); + + /* Link third ID table */ + pte = pte_of_xenaddr((vaddr_t)xen_third_id); + pte.pt.table = 1; + pte.pt.xn = 0; + + write_pte(&xen_second_id[id_offsets[2]], pte); + + /* The mapping in the third table will be created at a later stage */ + + /* + * Link the identity mapping in the runtime Xen page tables. No need to + * use write_pte here as they are not live yet. + */ + xen_pgtable[id_offsets[0]] = boot_pgtable[id_offsets[0]]; +} + +void update_identity_mapping(bool enable) +{ + paddr_t id_addr = virt_to_maddr(_start); + int rc; + + if ( enable ) + rc = map_pages_to_xen(id_addr, maddr_to_mfn(id_addr), 1, + PAGE_HYPERVISOR_RX); + else + rc = destroy_xen_mappings(id_addr, id_addr + PAGE_SIZE); + + BUG_ON(rc); +} + /* * After boot, Xen page-tables should not contain mapping that are both * Writable and eXecutables. @@ -609,6 +679,9 @@ void __init setup_pagetables(unsigned long boot_phys_offset) phys_offset = boot_phys_offset; + /* XXX: Find a better place to call it */ + prepare_identity_mapping(); + #ifdef CONFIG_ARM_64 pte = pte_of_xenaddr((uintptr_t)xen_first); pte.pt.table = 1; -- 2.32.0
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |