Skip to content

Commit dbb7d29

Browse files
jcmvbkbcksacilotto
authored andcommitted
xtensa: disable preemption around cache alias management calls
BugLink: https://bugs.launchpad.net/bugs/1908561 commit 3a860d1 upstream. 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]> Signed-off-by: Greg Kroah-Hartman <[email protected]> Signed-off-by: Kamal Mostafa <[email protected]> Signed-off-by: Ian May <[email protected]>
1 parent 0a4fe09 commit dbb7d29

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
@@ -71,8 +71,10 @@ static inline void kmap_invalidate_coherent(struct page *page,
7171
kvaddr = TLBTEMP_BASE_1 +
7272
(page_to_phys(page) & DCACHE_ALIAS_MASK);
7373

74+
preempt_disable();
7475
__invalidate_dcache_page_alias(kvaddr,
7576
page_to_phys(page));
77+
preempt_enable();
7678
}
7779
}
7880
}
@@ -157,6 +159,7 @@ void flush_dcache_page(struct page *page)
157159
if (!alias && !mapping)
158160
return;
159161

162+
preempt_disable();
160163
virt = TLBTEMP_BASE_1 + (phys & DCACHE_ALIAS_MASK);
161164
__flush_invalidate_dcache_page_alias(virt, phys);
162165

@@ -167,6 +170,7 @@ void flush_dcache_page(struct page *page)
167170

168171
if (mapping)
169172
__invalidate_icache_page_alias(virt, phys);
173+
preempt_enable();
170174
}
171175

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

207+
preempt_disable();
203208
__flush_invalidate_dcache_page_alias(virt, phys);
204209
__invalidate_icache_page_alias(virt, phys);
210+
preempt_enable();
205211
}
206212
EXPORT_SYMBOL(local_flush_cache_page);
207213

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

237+
preempt_disable();
231238
tmp = TLBTEMP_BASE_1 + (phys & DCACHE_ALIAS_MASK);
232239
__flush_invalidate_dcache_page_alias(tmp, phys);
233240
tmp = TLBTEMP_BASE_1 + (addr & DCACHE_ALIAS_MASK);
234241
__flush_invalidate_dcache_page_alias(tmp, phys);
235242
__invalidate_icache_page_alias(tmp, phys);
243+
preempt_enable();
236244

237245
clear_bit(PG_arch_1, &page->flags);
238246
}
@@ -266,7 +274,9 @@ void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
266274

267275
if (alias) {
268276
unsigned long t = TLBTEMP_BASE_1 + (vaddr & DCACHE_ALIAS_MASK);
277+
preempt_disable();
269278
__flush_invalidate_dcache_page_alias(t, phys);
279+
preempt_enable();
270280
}
271281

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

294+
preempt_disable();
284295
__flush_invalidate_dcache_range((unsigned long) dst, len);
285296
if ((vma->vm_flags & VM_EXEC) != 0)
286297
__invalidate_icache_page_alias(t, phys);
298+
preempt_enable();
287299

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

306318
if (alias) {
307319
unsigned long t = TLBTEMP_BASE_1 + (vaddr & DCACHE_ALIAS_MASK);
320+
preempt_disable();
308321
__flush_invalidate_dcache_page_alias(t, phys);
322+
preempt_enable();
309323
}
310324

311325
memcpy(dst, src, len);

0 commit comments

Comments
 (0)