Skip to content

Commit 3a860d1

Browse files
committed
xtensa: disable preemption around cache alias management calls
Although cache alias management calls set up and tear down TLB entries and fast_second_level_miss is able to restore TLB entry should it be evicted they absolutely cannot preempt each other because they use the same TLBTEMP area for different purposes. Disable preemption around all cache alias management calls to enforce that. Cc: [email protected] Signed-off-by: Max Filippov <[email protected]>
1 parent 481535c commit 3a860d1

File tree

1 file changed

+14
-0
lines changed

1 file changed

+14
-0
lines changed

arch/xtensa/mm/cache.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,10 @@ static inline void kmap_invalidate_coherent(struct page *page,
7070
kvaddr = TLBTEMP_BASE_1 +
7171
(page_to_phys(page) & DCACHE_ALIAS_MASK);
7272

73+
preempt_disable();
7374
__invalidate_dcache_page_alias(kvaddr,
7475
page_to_phys(page));
76+
preempt_enable();
7577
}
7678
}
7779
}
@@ -156,6 +158,7 @@ void flush_dcache_page(struct page *page)
156158
if (!alias && !mapping)
157159
return;
158160

161+
preempt_disable();
159162
virt = TLBTEMP_BASE_1 + (phys & DCACHE_ALIAS_MASK);
160163
__flush_invalidate_dcache_page_alias(virt, phys);
161164

@@ -166,6 +169,7 @@ void flush_dcache_page(struct page *page)
166169

167170
if (mapping)
168171
__invalidate_icache_page_alias(virt, phys);
172+
preempt_enable();
169173
}
170174

171175
/* There shouldn't be an entry in the cache for this page anymore. */
@@ -199,8 +203,10 @@ void local_flush_cache_page(struct vm_area_struct *vma, unsigned long address,
199203
unsigned long phys = page_to_phys(pfn_to_page(pfn));
200204
unsigned long virt = TLBTEMP_BASE_1 + (address & DCACHE_ALIAS_MASK);
201205

206+
preempt_disable();
202207
__flush_invalidate_dcache_page_alias(virt, phys);
203208
__invalidate_icache_page_alias(virt, phys);
209+
preempt_enable();
204210
}
205211
EXPORT_SYMBOL(local_flush_cache_page);
206212

@@ -227,11 +233,13 @@ update_mmu_cache(struct vm_area_struct * vma, unsigned long addr, pte_t *ptep)
227233
unsigned long phys = page_to_phys(page);
228234
unsigned long tmp;
229235

236+
preempt_disable();
230237
tmp = TLBTEMP_BASE_1 + (phys & DCACHE_ALIAS_MASK);
231238
__flush_invalidate_dcache_page_alias(tmp, phys);
232239
tmp = TLBTEMP_BASE_1 + (addr & DCACHE_ALIAS_MASK);
233240
__flush_invalidate_dcache_page_alias(tmp, phys);
234241
__invalidate_icache_page_alias(tmp, phys);
242+
preempt_enable();
235243

236244
clear_bit(PG_arch_1, &page->flags);
237245
}
@@ -265,7 +273,9 @@ void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
265273

266274
if (alias) {
267275
unsigned long t = TLBTEMP_BASE_1 + (vaddr & DCACHE_ALIAS_MASK);
276+
preempt_disable();
268277
__flush_invalidate_dcache_page_alias(t, phys);
278+
preempt_enable();
269279
}
270280

271281
/* Copy data */
@@ -280,9 +290,11 @@ void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
280290
if (alias) {
281291
unsigned long t = TLBTEMP_BASE_1 + (vaddr & DCACHE_ALIAS_MASK);
282292

293+
preempt_disable();
283294
__flush_invalidate_dcache_range((unsigned long) dst, len);
284295
if ((vma->vm_flags & VM_EXEC) != 0)
285296
__invalidate_icache_page_alias(t, phys);
297+
preempt_enable();
286298

287299
} else if ((vma->vm_flags & VM_EXEC) != 0) {
288300
__flush_dcache_range((unsigned long)dst,len);
@@ -304,7 +316,9 @@ extern void copy_from_user_page(struct vm_area_struct *vma, struct page *page,
304316

305317
if (alias) {
306318
unsigned long t = TLBTEMP_BASE_1 + (vaddr & DCACHE_ALIAS_MASK);
319+
preempt_disable();
307320
__flush_invalidate_dcache_page_alias(t, phys);
321+
preempt_enable();
308322
}
309323

310324
memcpy(dst, src, len);

0 commit comments

Comments
 (0)