flush_cache_mm() fetches %sr3 via mtsp(3). If it matches mm->context, it flushes caches and the TLB. However, the TLB is cpu-local, so if the code gets preempted shortly after the mtsp(), and later resumed on another CPU, the wrong TLB is flushed. Signed-off-by: Sven Schnelle <svens@xxxxxxxxxxxxxx> --- arch/parisc/kernel/cache.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c index 39e02227e231..90656c49bc07 100644 --- a/arch/parisc/kernel/cache.c +++ b/arch/parisc/kernel/cache.c @@ -558,6 +558,7 @@ void flush_cache_mm(struct mm_struct *mm) return; } + preempt_disable(); if (mm->context == mfsp(3)) { for (vma = mm->mmap; vma; vma = vma->vm_next) { flush_user_dcache_range_asm(vma->vm_start, vma->vm_end); @@ -565,8 +566,10 @@ void flush_cache_mm(struct mm_struct *mm) flush_user_icache_range_asm(vma->vm_start, vma->vm_end); flush_tlb_range(vma, vma->vm_start, vma->vm_end); } + preempt_enable(); return; } + preempt_enable(); pgd = mm->pgd; for (vma = mm->mmap; vma; vma = vma->vm_next) { -- 2.33.0