[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v2 6/7] xen/arm: tlbflush: Rework TLB helpers
On Wed, 8 May 2019, Julien Grall wrote: > All the TLBs helpers invalidate all the TLB entries are using the same > pattern: > DSB SY > TLBI ... > DSB SY > ISB > > This pattern is following pattern recommended by the Arm Arm to ensure > visibility of updates to translation tables (see K11.5.2 in ARM DDI > 0487D.b). > > We have been a bit too eager in Xen and use system-wide DSBs when this > can be limited to the inner-shareable domain. > > Furthermore, the first DSB can be restrict further to only store in the > inner-shareable domain. This is because the DSB is here to ensure > visibility of the update to translation table walks. > > Lastly, there are a lack of documentation in most of the TLBs helper. > > Rather than trying to update the helpers one by one, this patch > introduce a per-arch macro to generate the TLB helpers. This will be > easier to update the TLBs helper in the future and the documentation. > > Signed-off-by: Julien Grall <julien.grall@xxxxxxx> > Reviewed-by: Andrii Anisov <andrii_anisov@xxxxxxxx> Reviewed-by: Stefano Stabellini <sstabellini@xxxxxxxxxx> > --- > Changes in v2: > - Update the reference to the Arm Arm to the latest spec > - Add Andrii's reviewed-by > --- > xen/include/asm-arm/arm32/flushtlb.h | 73 ++++++++++++++-------------------- > xen/include/asm-arm/arm64/flushtlb.h | 76 > +++++++++++++++--------------------- > 2 files changed, 60 insertions(+), 89 deletions(-) > > diff --git a/xen/include/asm-arm/arm32/flushtlb.h > b/xen/include/asm-arm/arm32/flushtlb.h > index b629db61cb..9085e65011 100644 > --- a/xen/include/asm-arm/arm32/flushtlb.h > +++ b/xen/include/asm-arm/arm32/flushtlb.h > @@ -1,59 +1,44 @@ > #ifndef __ASM_ARM_ARM32_FLUSHTLB_H__ > #define __ASM_ARM_ARM32_FLUSHTLB_H__ > > -/* Flush local TLBs, current VMID only */ > -static inline void flush_guest_tlb_local(void) > -{ > - dsb(sy); > - > - WRITE_CP32((uint32_t) 0, TLBIALL); > - > - dsb(sy); > - isb(); > +/* > + * Every invalidation operation use the following patterns: > + * > + * DSB ISHST // Ensure prior page-tables updates have completed > + * TLBI... // Invalidate the TLB > + * DSB ISH // Ensure the TLB invalidation has completed > + * ISB // See explanation below > + * > + * For Xen page-tables the ISB will discard any instructions fetched > + * from the old mappings. > + * > + * For the Stage-2 page-tables the ISB ensures the completion of the DSB > + * (and therefore the TLB invalidation) before continuing. So we know > + * the TLBs cannot contain an entry for a mapping we may have removed. > + */ > +#define TLB_HELPER(name, tlbop) \ > +static inline void name(void) \ > +{ \ > + dsb(ishst); \ > + WRITE_CP32(0, tlbop); \ > + dsb(ish); \ > + isb(); \ > } > > -/* Flush inner shareable TLBs, current VMID only */ > -static inline void flush_guest_tlb(void) > -{ > - dsb(sy); > - > - WRITE_CP32((uint32_t) 0, TLBIALLIS); > +/* Flush local TLBs, current VMID only */ > +TLB_HELPER(flush_guest_tlb_local, TLBIALL); > > - dsb(sy); > - isb(); > -} > +/* Flush inner shareable TLBs, current VMID only */ > +TLB_HELPER(flush_guest_tlb, TLBIALLIS); > > /* Flush local TLBs, all VMIDs, non-hypervisor mode */ > -static inline void flush_all_guests_tlb_local(void) > -{ > - dsb(sy); > - > - WRITE_CP32((uint32_t) 0, TLBIALLNSNH); > - > - dsb(sy); > - isb(); > -} > +TLB_HELPER(flush_all_guests_tlb_local, TLBIALLNSNH); > > /* Flush innershareable TLBs, all VMIDs, non-hypervisor mode */ > -static inline void flush_all_guests_tlb(void) > -{ > - dsb(sy); > - > - WRITE_CP32((uint32_t) 0, TLBIALLNSNHIS); > - > - dsb(sy); > - isb(); > -} > +TLB_HELPER(flush_all_guests_tlb, TLBIALLNSNHIS); > > /* Flush all hypervisor mappings from the TLB of the local processor. */ > -static inline void flush_xen_tlb_local(void) > -{ > - asm volatile("dsb;" /* Ensure preceding are visible */ > - CMD_CP32(TLBIALLH) > - "dsb;" /* Ensure completion of the TLB flush */ > - "isb;" > - : : : "memory"); > -} > +TLB_HELPER(flush_xen_tlb_local, TLBIALLH); > > /* Flush TLB of local processor for address va. */ > static inline void __flush_xen_tlb_one_local(vaddr_t va) > diff --git a/xen/include/asm-arm/arm64/flushtlb.h > b/xen/include/asm-arm/arm64/flushtlb.h > index 2fed34b2ec..ceec59542e 100644 > --- a/xen/include/asm-arm/arm64/flushtlb.h > +++ b/xen/include/asm-arm/arm64/flushtlb.h > @@ -1,60 +1,46 @@ > #ifndef __ASM_ARM_ARM64_FLUSHTLB_H__ > #define __ASM_ARM_ARM64_FLUSHTLB_H__ > > -/* Flush local TLBs, current VMID only */ > -static inline void flush_guest_tlb_local(void) > -{ > - asm volatile( > - "dsb sy;" > - "tlbi vmalls12e1;" > - "dsb sy;" > - "isb;" > - : : : "memory"); > +/* > + * Every invalidation operation use the following patterns: > + * > + * DSB ISHST // Ensure prior page-tables updates have completed > + * TLBI... // Invalidate the TLB > + * DSB ISH // Ensure the TLB invalidation has completed > + * ISB // See explanation below > + * > + * For Xen page-tables the ISB will discard any instructions fetched > + * from the old mappings. > + * > + * For the Stage-2 page-tables the ISB ensures the completion of the DSB > + * (and therefore the TLB invalidation) before continuing. So we know > + * the TLBs cannot contain an entry for a mapping we may have removed. > + */ > +#define TLB_HELPER(name, tlbop) \ > +static inline void name(void) \ > +{ \ > + asm volatile( \ > + "dsb ishst;" \ > + "tlbi " # tlbop ";" \ > + "dsb ish;" \ > + "isb;" \ > + : : : "memory"); \ > } > > +/* Flush local TLBs, current VMID only. */ > +TLB_HELPER(flush_guest_tlb_local, vmalls12e1); > + > /* Flush innershareable TLBs, current VMID only */ > -static inline void flush_guest_tlb(void) > -{ > - asm volatile( > - "dsb sy;" > - "tlbi vmalls12e1is;" > - "dsb sy;" > - "isb;" > - : : : "memory"); > -} > +TLB_HELPER(flush_guest_tlb, vmalls12e1is); > > /* Flush local TLBs, all VMIDs, non-hypervisor mode */ > -static inline void flush_all_guests_tlb_local(void) > -{ > - asm volatile( > - "dsb sy;" > - "tlbi alle1;" > - "dsb sy;" > - "isb;" > - : : : "memory"); > -} > +TLB_HELPER(flush_all_guests_tlb_local, alle1); > > /* Flush innershareable TLBs, all VMIDs, non-hypervisor mode */ > -static inline void flush_all_guests_tlb(void) > -{ > - asm volatile( > - "dsb sy;" > - "tlbi alle1is;" > - "dsb sy;" > - "isb;" > - : : : "memory"); > -} > +TLB_HELPER(flush_all_guests_tlb, alle1is); > > /* Flush all hypervisor mappings from the TLB of the local processor. */ > -static inline void flush_xen_tlb_local(void) > -{ > - asm volatile ( > - "dsb sy;" /* Ensure visibility of PTE writes */ > - "tlbi alle2;" /* Flush hypervisor TLB */ > - "dsb sy;" /* Ensure completion of TLB flush */ > - "isb;" > - : : : "memory"); > -} > +TLB_HELPER(flush_xen_tlb_local, alle2); > > /* Flush TLB of local processor for address va. */ > static inline void __flush_xen_tlb_one_local(vaddr_t va) > -- > 2.11.0 > _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |