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:
Julien Grall committed 2023-01-24 19:34:44 +00:00
1 parent cbfaf6ccd2
commit d56c70b6e1
1 file changed
+15 -12
+15 -12
View File
@@ -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)
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.