3131 */
3232#define __TLBI_0 (op , arg ) asm (ARM64_ASM_PREAMBLE \
3333 "tlbi " #op "\n" \
34- ALTERNATIVE("nop\n nop", \
35- "dsb ish\n tlbi " #op, \
36- ARM64_WORKAROUND_REPEAT_TLBI, \
37- CONFIG_ARM64_WORKAROUND_REPEAT_TLBI) \
3834 : : )
3935
4036#define __TLBI_1 (op , arg ) asm (ARM64_ASM_PREAMBLE \
41- "tlbi " #op ", %0\n" \
42- ALTERNATIVE("nop\n nop", \
43- "dsb ish\n tlbi " #op ", %0", \
44- ARM64_WORKAROUND_REPEAT_TLBI, \
45- CONFIG_ARM64_WORKAROUND_REPEAT_TLBI) \
46- : : "r" (arg))
37+ "tlbi " #op ", %x0\n" \
38+ : : "rZ" (arg))
4739
4840#define __TLBI_N (op , arg , n , ...) __TLBI_##n(op, arg)
4941
@@ -88,6 +80,71 @@ static inline unsigned long get_trans_granule(void)
8880 }
8981}
9082
83+ #ifdef CONFIG_ARM64_ERRATUM_4193714
84+
85+ void sme_do_dvmsync (const struct cpumask * mask );
86+
87+ static inline void sme_dvmsync (struct mm_struct * mm )
88+ {
89+ if (!alternative_has_cap_unlikely (ARM64_WORKAROUND_4193714 ))
90+ return ;
91+
92+ sme_do_dvmsync (mm_cpumask (mm ));
93+ }
94+
95+ static inline void sme_dvmsync_add_pending (struct arch_tlbflush_unmap_batch * batch ,
96+ struct mm_struct * mm )
97+ {
98+ if (!alternative_has_cap_unlikely (ARM64_WORKAROUND_4193714 ))
99+ return ;
100+
101+ /*
102+ * Order the mm_cpumask() read after the hardware DVMSync.
103+ */
104+ dsb (ish );
105+ if (cpumask_empty (mm_cpumask (mm )))
106+ return ;
107+
108+ /*
109+ * Allocate the batch cpumask on first use. Fall back to an immediate
110+ * IPI for this mm in case of failure.
111+ */
112+ if (!cpumask_available (batch -> cpumask ) &&
113+ !zalloc_cpumask_var (& batch -> cpumask , GFP_ATOMIC )) {
114+ sme_do_dvmsync (mm_cpumask (mm ));
115+ return ;
116+ }
117+
118+ cpumask_or (batch -> cpumask , batch -> cpumask , mm_cpumask (mm ));
119+ }
120+
121+ static inline void sme_dvmsync_batch (struct arch_tlbflush_unmap_batch * batch )
122+ {
123+ if (!alternative_has_cap_unlikely (ARM64_WORKAROUND_4193714 ))
124+ return ;
125+
126+ if (!cpumask_available (batch -> cpumask ))
127+ return ;
128+
129+ sme_do_dvmsync (batch -> cpumask );
130+ cpumask_clear (batch -> cpumask );
131+ }
132+
133+ #else
134+
135+ static inline void sme_dvmsync (struct mm_struct * mm )
136+ {
137+ }
138+ static inline void sme_dvmsync_add_pending (struct arch_tlbflush_unmap_batch * batch ,
139+ struct mm_struct * mm )
140+ {
141+ }
142+ static inline void sme_dvmsync_batch (struct arch_tlbflush_unmap_batch * batch )
143+ {
144+ }
145+
146+ #endif /* CONFIG_ARM64_ERRATUM_4193714 */
147+
91148/*
92149 * Level-based TLBI operations.
93150 *
@@ -181,6 +238,48 @@ static inline unsigned long get_trans_granule(void)
181238 (__pages >> (5 * (scale) + 1)) - 1; \
182239 })
183240
241+ #define __repeat_tlbi_sync (op , arg ...) \
242+ do { \
243+ if (!alternative_has_cap_unlikely(ARM64_WORKAROUND_REPEAT_TLBI)) \
244+ break; \
245+ __tlbi(op, ##arg); \
246+ dsb(ish); \
247+ } while (0)
248+
249+ /*
250+ * Complete broadcast TLB maintenance issued by the host which invalidates
251+ * stage 1 information in the host's own translation regime.
252+ */
253+ static inline void __tlbi_sync_s1ish (struct mm_struct * mm )
254+ {
255+ dsb (ish );
256+ __repeat_tlbi_sync (vale1is , 0 );
257+ sme_dvmsync (mm );
258+ }
259+
260+ static inline void __tlbi_sync_s1ish_batch (struct arch_tlbflush_unmap_batch * batch )
261+ {
262+ dsb (ish );
263+ __repeat_tlbi_sync (vale1is , 0 );
264+ sme_dvmsync_batch (batch );
265+ }
266+
267+ static inline void __tlbi_sync_s1ish_kernel (void )
268+ {
269+ dsb (ish );
270+ __repeat_tlbi_sync (vale1is , 0 );
271+ }
272+
273+ /*
274+ * Complete broadcast TLB maintenance issued by hyp code which invalidates
275+ * stage 1 translation information in any translation regime.
276+ */
277+ static inline void __tlbi_sync_s1ish_hyp (void )
278+ {
279+ dsb (ish );
280+ __repeat_tlbi_sync (vale2is , 0 );
281+ }
282+
184283/*
185284 * TLB Invalidation
186285 * ================
@@ -266,7 +365,7 @@ static inline void flush_tlb_all(void)
266365{
267366 dsb (ishst );
268367 __tlbi (vmalle1is );
269- dsb ( ish );
368+ __tlbi_sync_s1ish_kernel ( );
270369 isb ();
271370}
272371
@@ -278,7 +377,7 @@ static inline void flush_tlb_mm(struct mm_struct *mm)
278377 asid = __TLBI_VADDR (0 , ASID (mm ));
279378 __tlbi (aside1is , asid );
280379 __tlbi_user (aside1is , asid );
281- dsb ( ish );
380+ __tlbi_sync_s1ish ( mm );
282381 mmu_notifier_arch_invalidate_secondary_tlbs (mm , 0 , -1UL );
283382}
284383
@@ -305,20 +404,11 @@ static inline void flush_tlb_page(struct vm_area_struct *vma,
305404 unsigned long uaddr )
306405{
307406 flush_tlb_page_nosync (vma , uaddr );
308- dsb ( ish );
407+ __tlbi_sync_s1ish ( vma -> vm_mm );
309408}
310409
311410static inline bool arch_tlbbatch_should_defer (struct mm_struct * mm )
312411{
313- /*
314- * TLB flush deferral is not required on systems which are affected by
315- * ARM64_WORKAROUND_REPEAT_TLBI, as __tlbi()/__tlbi_user() implementation
316- * will have two consecutive TLBI instructions with a dsb(ish) in between
317- * defeating the purpose (i.e save overall 'dsb ish' cost).
318- */
319- if (alternative_has_cap_unlikely (ARM64_WORKAROUND_REPEAT_TLBI ))
320- return false;
321-
322412 return true;
323413}
324414
@@ -334,7 +424,7 @@ static inline bool arch_tlbbatch_should_defer(struct mm_struct *mm)
334424 */
335425static inline void arch_tlbbatch_flush (struct arch_tlbflush_unmap_batch * batch )
336426{
337- dsb ( ish );
427+ __tlbi_sync_s1ish_batch ( batch );
338428}
339429
340430/*
@@ -469,7 +559,7 @@ static inline void __flush_tlb_range(struct vm_area_struct *vma,
469559{
470560 __flush_tlb_range_nosync (vma -> vm_mm , start , end , stride ,
471561 last_level , tlb_level );
472- dsb ( ish );
562+ __tlbi_sync_s1ish ( vma -> vm_mm );
473563}
474564
475565static inline void flush_tlb_range (struct vm_area_struct * vma ,
@@ -501,7 +591,7 @@ static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end
501591 dsb (ishst );
502592 __flush_tlb_range_op (vaale1is , start , pages , stride , 0 ,
503593 TLBI_TTL_UNKNOWN , false, lpa2_is_enabled ());
504- dsb ( ish );
594+ __tlbi_sync_s1ish_kernel ( );
505595 isb ();
506596}
507597
@@ -515,14 +605,15 @@ static inline void __flush_tlb_kernel_pgtable(unsigned long kaddr)
515605
516606 dsb (ishst );
517607 __tlbi (vaae1is , addr );
518- dsb ( ish );
608+ __tlbi_sync_s1ish_kernel ( );
519609 isb ();
520610}
521611
522612static inline void arch_tlbbatch_add_pending (struct arch_tlbflush_unmap_batch * batch ,
523613 struct mm_struct * mm , unsigned long start , unsigned long end )
524614{
525615 __flush_tlb_range_nosync (mm , start , end , PAGE_SIZE , true, 3 );
616+ sme_dvmsync_add_pending (batch , mm );
526617}
527618#endif
528619
0 commit comments