[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH early-RFC 3/5] xen/arm: mm: Introduce helpers to prepare/enable/disable the identity mapping
Hi Julien, > On 9 Mar 2022, at 12:20, Julien Grall <julien@xxxxxxx> wrote: > > 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 Nit: Would be better to first say what the patch is doing and then explaining the NULL pointer possible issue. > > 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); Debug print that should be removed. > +#ifdef CONFIG_ARM_64 > + if ( id_offsets[0] != 0 ) > + panic("Cannot handled ID mapping above 512GB\n"); The error message here might not be really helpful for the user. How about saying that Xen cannot be loaded in memory with a physical address above 512GB ? > +#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) You probably want an __init attribute here. > +{ > + 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 */ Why do you think this place is not right ? > + prepare_identity_mapping(); > + > #ifdef CONFIG_ARM_64 > pte = pte_of_xenaddr((uintptr_t)xen_first); > pte.pt.table = 1; > -- > 2.32.0 Cheers Bertrand
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |