[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH early-RFC 4/5] xen/arm: mm: Rework switch_ttbr()
On Wed, 9 Mar 2022, Julien Grall wrote: > From: Julien Grall <jgrall@xxxxxxxxxx> > > At the moment, switch_ttbr() is switching the TTBR whilst the MMU is > still on. > > Switching TTBR is like replacing existing mappings with new ones. So > we need to follow the break-before-make sequence. > > In this case, it means the MMU needs to be switched off while the > TTBR is updated. In order to disable the MMU, we need to first > jump to an identity mapping. > > Rename switch_ttbr() to switch_ttbr_id() and create an helper on > top to temporary map the identity mapping and call switch_ttbr() > via the identity address. > > switch_ttbr_id() is now reworked to temporarily turn off the MMU > before updating the TTBR. > > We also need to make sure the helper switch_ttbr() is part of the > identity mapping. So move _end_boot past it. > > Take the opportunity to instruction cache flush as the operation is > only necessary when the memory is updated. > > Signed-off-by: Julien Grall <jgrall@xxxxxxxxxx> > > --- > > TODO: > * Rename _end_boot to _end_id_mapping or similar > * Check the memory barriers > * I suspect the instruction cache flush will be necessary > for cache coloring. > --- > xen/arch/arm/arm64/head.S | 31 ++++++++++++++++++++----------- > xen/arch/arm/mm.c | 14 +++++++++++++- > 2 files changed, 33 insertions(+), 12 deletions(-) > > diff --git a/xen/arch/arm/arm64/head.S b/xen/arch/arm/arm64/head.S > index 878649280d73..c5cc72b8fe6f 100644 > --- a/xen/arch/arm/arm64/head.S > +++ b/xen/arch/arm/arm64/head.S > @@ -803,36 +803,45 @@ fail: PRINT("- Boot failed -\r\n") > b 1b > ENDPROC(fail) > > -GLOBAL(_end_boot) > - > /* > * Switch TTBR > * > * x0 ttbr > * > - * TODO: This code does not comply with break-before-make. > + * XXX: Check the barriers > */ > -ENTRY(switch_ttbr) > +ENTRY(switch_ttbr_id) > dsb sy /* Ensure the flushes happen before > * continuing */ > isb /* Ensure synchronization with previous > * changes to text */ > + > + /* Turn off MMU */ > + mrs x1, SCTLR_EL2 > + bic x1, x1, #SCTLR_Axx_ELx_M > + msr SCTLR_EL2, x1 > + dsb sy > + isb > + > tlbi alle2 /* Flush hypervisor TLB */ > - ic iallu /* Flush I-cache */ > dsb sy /* Ensure completion of TLB flush */ > isb > > - msr TTBR0_EL2, x0 > + msr TTBR0_EL2, x0 > + > + mrs x1, SCTLR_EL2 > + orr x1, x1, #SCTLR_Axx_ELx_M /* Enable MMU */ > + msr SCTLR_EL2, x1 > > isb /* Ensure synchronization with previous > * changes to text */ > - tlbi alle2 /* Flush hypervisor TLB */ > - ic iallu /* Flush I-cache */ > - dsb sy /* Ensure completion of TLB flush */ > - isb > + /* Turn on the MMU */ > + > > ret > -ENDPROC(switch_ttbr) > +ENDPROC(switch_ttbr_id) > + > +GLOBAL(_end_boot) > > #ifdef CONFIG_EARLY_PRINTK > /* > diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c > index 5c4dece16f7f..a53760af7af0 100644 > --- a/xen/arch/arm/mm.c > +++ b/xen/arch/arm/mm.c > @@ -660,7 +660,19 @@ static void xen_pt_enforce_wnx(void) > flush_xen_tlb_local(); > } > > -extern void switch_ttbr(uint64_t ttbr); > +extern void switch_ttbr_id(uint64_t ttbr); > + > +typedef void (switch_ttbr_fn)(uint64_t ttbr); > + > +static void switch_ttbr(uint64_t ttbr) > +{ > + vaddr_t id_addr = virt_to_maddr(switch_ttbr_id); > + switch_ttbr_fn *fn = (switch_ttbr_fn *)id_addr; > + > + update_identity_mapping(true); > + fn(ttbr); > + update_identity_mapping(false); > +} As far as I can tell this should work for coloring too. In the case of coloring: /* running on the old mapping, same as non-coloring */ update_identity_mapping(true); /* jumping to the 1:1 mapping of the old Xen and switching to the * new pagetable */ fn(ttbr); /* new pagetable is enabled, now we are back to addresses greater * than XEN_VIRT_START, which correspond to new cache-colored Xen */ update_identity_mapping(false); The only doubt that I have is: are we sure than a single page of 1:1 mapping is enough? What if: virt_to_maddr(switch_ttbr_id) - virt_to_maddr(_start) > PAGE_SIZE We might have to do a 1:1 mapping of size = _end-_start. It would work with coloring too because we are doing a 1:1 mapping of the old copy of Xen which is non-colored and contiguous (not the new copy which is colored and fragmented). Thanks Julien very much for your help!
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |