18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci#ifndef _PARISC_TLBFLUSH_H 38c2ecf20Sopenharmony_ci#define _PARISC_TLBFLUSH_H 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ci/* TLB flushing routines.... */ 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci#include <linux/mm.h> 88c2ecf20Sopenharmony_ci#include <linux/sched.h> 98c2ecf20Sopenharmony_ci#include <asm/mmu_context.h> 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ciextern void flush_tlb_all(void); 128c2ecf20Sopenharmony_ciextern void flush_tlb_all_local(void *); 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci#define smp_flush_tlb_all() flush_tlb_all() 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ciint __flush_tlb_range(unsigned long sid, 178c2ecf20Sopenharmony_ci unsigned long start, unsigned long end); 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci#define flush_tlb_range(vma, start, end) \ 208c2ecf20Sopenharmony_ci __flush_tlb_range((vma)->vm_mm->context, start, end) 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci#define flush_tlb_kernel_range(start, end) \ 238c2ecf20Sopenharmony_ci __flush_tlb_range(0, start, end) 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci/* 268c2ecf20Sopenharmony_ci * flush_tlb_mm() 278c2ecf20Sopenharmony_ci * 288c2ecf20Sopenharmony_ci * The code to switch to a new context is NOT valid for processes 298c2ecf20Sopenharmony_ci * which play with the space id's. Thus, we have to preserve the 308c2ecf20Sopenharmony_ci * space and just flush the entire tlb. However, the compilers, 318c2ecf20Sopenharmony_ci * dynamic linker, etc, do not manipulate space id's, so there 328c2ecf20Sopenharmony_ci * could be a significant performance benefit in switching contexts 338c2ecf20Sopenharmony_ci * and not flushing the whole tlb. 348c2ecf20Sopenharmony_ci */ 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_cistatic inline void flush_tlb_mm(struct mm_struct *mm) 378c2ecf20Sopenharmony_ci{ 388c2ecf20Sopenharmony_ci BUG_ON(mm == &init_mm); /* Should never happen */ 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci#if 1 || defined(CONFIG_SMP) 418c2ecf20Sopenharmony_ci /* Except for very small threads, flushing the whole TLB is 428c2ecf20Sopenharmony_ci * faster than using __flush_tlb_range. The pdtlb and pitlb 438c2ecf20Sopenharmony_ci * instructions are very slow because of the TLB broadcast. 448c2ecf20Sopenharmony_ci * It might be faster to do local range flushes on all CPUs 458c2ecf20Sopenharmony_ci * on PA 2.0 systems. 468c2ecf20Sopenharmony_ci */ 478c2ecf20Sopenharmony_ci flush_tlb_all(); 488c2ecf20Sopenharmony_ci#else 498c2ecf20Sopenharmony_ci /* FIXME: currently broken, causing space id and protection ids 508c2ecf20Sopenharmony_ci * to go out of sync, resulting in faults on userspace accesses. 518c2ecf20Sopenharmony_ci * This approach needs further investigation since running many 528c2ecf20Sopenharmony_ci * small applications (e.g., GCC testsuite) is faster on HP-UX. 538c2ecf20Sopenharmony_ci */ 548c2ecf20Sopenharmony_ci if (mm) { 558c2ecf20Sopenharmony_ci if (mm->context != 0) 568c2ecf20Sopenharmony_ci free_sid(mm->context); 578c2ecf20Sopenharmony_ci mm->context = alloc_sid(); 588c2ecf20Sopenharmony_ci if (mm == current->active_mm) 598c2ecf20Sopenharmony_ci load_context(mm->context); 608c2ecf20Sopenharmony_ci } 618c2ecf20Sopenharmony_ci#endif 628c2ecf20Sopenharmony_ci} 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_cistatic inline void flush_tlb_page(struct vm_area_struct *vma, 658c2ecf20Sopenharmony_ci unsigned long addr) 668c2ecf20Sopenharmony_ci{ 678c2ecf20Sopenharmony_ci purge_tlb_entries(vma->vm_mm, addr); 688c2ecf20Sopenharmony_ci} 698c2ecf20Sopenharmony_ci#endif 70