Skip to content

Commit bd77c44

Browse files
kvaneeshmpe
authored andcommitted
powerpc/mm/radix: Use tlbiel only if we ever ran on the current cpu
Before this patch, we used tlbiel, if we ever ran only on this core. That was mostly derived from the nohash usage of the same. But is incorrect, the ISA 3.0 clarifies tlbiel such that: "All TLB entries that have all of the following properties are made invalid on the thread executing the tlbiel instruction" ie. tlbiel only invalidates TLB entries on the current thread. So if the mm has been used on any other thread (aka. cpu) then we must broadcast the invalidate. This bug could lead to invalid TLB entries if a program runs on multiple threads of a core. Hence use tlbiel, if we only ever ran on only the current cpu. Fixes: 1a472c9 ("powerpc/mm/radix: Add tlbflush routines") Cc: [email protected] # v4.7+ Signed-off-by: Aneesh Kumar K.V <[email protected]> Signed-off-by: Michael Ellerman <[email protected]>
1 parent 39715bf commit bd77c44

File tree

2 files changed

+16
-4
lines changed

2 files changed

+16
-4
lines changed

arch/powerpc/include/asm/tlb.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,23 @@ static inline int mm_is_core_local(struct mm_struct *mm)
5252
return cpumask_subset(mm_cpumask(mm),
5353
topology_sibling_cpumask(smp_processor_id()));
5454
}
55+
56+
static inline int mm_is_thread_local(struct mm_struct *mm)
57+
{
58+
return cpumask_equal(mm_cpumask(mm),
59+
cpumask_of(smp_processor_id()));
60+
}
61+
5562
#else
5663
static inline int mm_is_core_local(struct mm_struct *mm)
5764
{
5865
return 1;
5966
}
67+
68+
static inline int mm_is_thread_local(struct mm_struct *mm)
69+
{
70+
return 1;
71+
}
6072
#endif
6173

6274
#endif /* __KERNEL__ */

arch/powerpc/mm/tlb-radix.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ void radix__flush_tlb_mm(struct mm_struct *mm)
175175
if (unlikely(pid == MMU_NO_CONTEXT))
176176
goto no_context;
177177

178-
if (!mm_is_core_local(mm)) {
178+
if (!mm_is_thread_local(mm)) {
179179
int lock_tlbie = !mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE);
180180

181181
if (lock_tlbie)
@@ -201,7 +201,7 @@ void radix__flush_tlb_pwc(struct mmu_gather *tlb, unsigned long addr)
201201
if (unlikely(pid == MMU_NO_CONTEXT))
202202
goto no_context;
203203

204-
if (!mm_is_core_local(mm)) {
204+
if (!mm_is_thread_local(mm)) {
205205
int lock_tlbie = !mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE);
206206

207207
if (lock_tlbie)
@@ -226,7 +226,7 @@ void radix__flush_tlb_page_psize(struct mm_struct *mm, unsigned long vmaddr,
226226
pid = mm ? mm->context.id : 0;
227227
if (unlikely(pid == MMU_NO_CONTEXT))
228228
goto bail;
229-
if (!mm_is_core_local(mm)) {
229+
if (!mm_is_thread_local(mm)) {
230230
int lock_tlbie = !mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE);
231231

232232
if (lock_tlbie)
@@ -321,7 +321,7 @@ void radix__flush_tlb_range_psize(struct mm_struct *mm, unsigned long start,
321321
{
322322
unsigned long pid;
323323
unsigned long addr;
324-
int local = mm_is_core_local(mm);
324+
int local = mm_is_thread_local(mm);
325325
unsigned long ap = mmu_get_ap(psize);
326326
int lock_tlbie = !mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE);
327327
unsigned long page_size = 1UL << mmu_psize_defs[psize].shift;

0 commit comments

Comments
 (0)