mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
xen/arm32: flushtlb: Reduce scope of barrier for local TLB flush
Per G5-9224 in ARM DDI 0487I.a: "A DSB NSH is sufficient to ensure completion of TLB maintenance instructions that apply to a single PE. A DSB ISH is sufficient to ensure completion of TLB maintenance instructions that apply to PEs in the same Inner Shareable domain. " This is quoting the Armv8 specification because I couldn't find an explicit statement in the Armv7 specification. Instead, I could find bits in various places that confirm the same implementation. Furthermore, Linux has been using 'nsh' since 2013 (62cbbc42e001 "ARM: tlb: reduce scope of barrier domains for TLB invalidation"). This means barrier after local TLB flushes could be reduced to non-shareable. Signed-off-by: Julien Grall <jgrall@amazon.com> Reviewed-by: Michal Orzel <michal.orzel@amd.com> Tested-by: Henry Wang <Henry.Wang@arm.com>
This commit is contained in:
1 parent
cbfaf6ccd2
commit
d56c70b6e1
1 file changed
+15
-12
@@ -15,30 +15,33 @@
|
||||
* 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.
|
||||
*
|
||||
* Note that for local TLB flush, using non-shareable (nsh) is sufficient
|
||||
* (see G5-9224 in ARM DDI 0487I.a).
|
||||
*/
|
||||
#define TLB_HELPER(name, tlbop) \
|
||||
static inline void name(void) \
|
||||
{ \
|
||||
dsb(ishst); \
|
||||
WRITE_CP32(0, tlbop); \
|
||||
dsb(ish); \
|
||||
isb(); \
|
||||
#define TLB_HELPER(name, tlbop, sh) \
|
||||
static inline void name(void) \
|
||||
{ \
|
||||
dsb(sh ## st); \
|
||||
WRITE_CP32(0, tlbop); \
|
||||
dsb(sh); \
|
||||
isb(); \
|
||||
}
|
||||
|
||||
/* Flush local TLBs, current VMID only */
|
||||
TLB_HELPER(flush_guest_tlb_local, TLBIALL);
|
||||
TLB_HELPER(flush_guest_tlb_local, TLBIALL, nsh);
|
||||
|
||||
/* Flush inner shareable TLBs, current VMID only */
|
||||
TLB_HELPER(flush_guest_tlb, TLBIALLIS);
|
||||
TLB_HELPER(flush_guest_tlb, TLBIALLIS, ish);
|
||||
|
||||
/* Flush local TLBs, all VMIDs, non-hypervisor mode */
|
||||
TLB_HELPER(flush_all_guests_tlb_local, TLBIALLNSNH);
|
||||
TLB_HELPER(flush_all_guests_tlb_local, TLBIALLNSNH, nsh);
|
||||
|
||||
/* Flush innershareable TLBs, all VMIDs, non-hypervisor mode */
|
||||
TLB_HELPER(flush_all_guests_tlb, TLBIALLNSNHIS);
|
||||
TLB_HELPER(flush_all_guests_tlb, TLBIALLNSNHIS, ish);
|
||||
|
||||
/* Flush all hypervisor mappings from the TLB of the local processor. */
|
||||
TLB_HELPER(flush_xen_tlb_local, TLBIALLH);
|
||||
TLB_HELPER(flush_xen_tlb_local, TLBIALLH, nsh);
|
||||
|
||||
/* Flush TLB of local processor for address va. */
|
||||
static inline void __flush_xen_tlb_one_local(vaddr_t va)
|
||||
|
||||