summaryrefslogtreecommitdiff
path: root/arch/parisc/kernel/cache.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2021-11-01 16:51:13 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2021-11-01 16:51:13 -0700
commit552ebfe022ec67aca4ff2bda0722ed0e28fc90d5 (patch)
tree3bb6c2318f8f66a04fa98400591b970a77e8c6bd /arch/parisc/kernel/cache.c
parent46f876322820c189ab525cfcba2519a17dbc0a6f (diff)
parent6e866a462867b60841202e900f10936a0478608c (diff)
Merge tag 'for-5.16/parisc-1' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux
Pull parisc updates from Helge Deller: "Lots of new features and fixes: - Added TOC (table of content) support, which is a debugging feature which is either initiated by pressing the TOC button or via command in the BMC. If pressed the Linux built-in KDB/KGDB will be called (Sven Schnelle) - Fix CONFIG_PREEMPT (Sven) - Fix unwinder on 64-bit kernels (Sven) - Various kgdb fixes (Sven) - Added KFENCE support (me) - Switch to ARCH_STACKWALK implementation (me) - Fix ptrace check on syscall return (me) - Fix kernel crash with fixmaps on PA1.x machines (me) - Move thread_info into task struct, aka CONFIG_THREAD_INFO_IN_TASK (me) - Updated defconfigs - Smaller cleanups, including Makefile cleanups (Masahiro Yamada), use kthread_run() macro (Cai Huoqing), use swap() macro (Yihao Han)" * tag 'for-5.16/parisc-1' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux: (36 commits) parisc: Fix set_fixmap() on PA1.x CPUs parisc: Use swap() to swap values in setup_bootmem() parisc: Update defconfigs parisc: decompressor: clean up Makefile parisc: decompressor: remove repeated depenency of misc.o parisc: Remove unused constants from asm-offsets.c parisc/ftrace: use static key to enable/disable function graph tracer parisc/ftrace: set function trace function parisc: Make use of the helper macro kthread_run() parisc: mark xchg functions notrace parisc: enhance warning regarding usage of O_NONBLOCK parisc: Drop ifdef __KERNEL__ from non-uapi kernel headers parisc: Use PRIV_USER and PRIV_KERNEL in ptrace.h parisc: Use PRIV_USER in syscall.S parisc/kgdb: add kgdb_roundup() to make kgdb work with idle polling parisc: Move thread_info into task struct parisc: add support for TOC (transfer of control) parisc/firmware: add functions to retrieve TOC data parisc: add PIM TOC data structures parisc: move virt_map macro to assembly.h ...
Diffstat (limited to 'arch/parisc/kernel/cache.c')
-rw-r--r--arch/parisc/kernel/cache.c87
1 files changed, 36 insertions, 51 deletions
diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c
index 39e02227e231..c61827e4928a 100644
--- a/arch/parisc/kernel/cache.c
+++ b/arch/parisc/kernel/cache.c
@@ -543,10 +543,33 @@ static inline pte_t *get_ptep(pgd_t *pgd, unsigned long addr)
return ptep;
}
+static void flush_cache_pages(struct vm_area_struct *vma, struct mm_struct *mm,
+ unsigned long start, unsigned long end)
+{
+ unsigned long addr, pfn;
+ pte_t *ptep;
+
+ for (addr = start; addr < end; addr += PAGE_SIZE) {
+ ptep = get_ptep(mm->pgd, addr);
+ if (ptep) {
+ pfn = pte_pfn(*ptep);
+ flush_cache_page(vma, addr, pfn);
+ }
+ }
+}
+
+static void flush_user_cache_tlb(struct vm_area_struct *vma,
+ unsigned long start, unsigned long end)
+{
+ flush_user_dcache_range_asm(start, end);
+ if (vma->vm_flags & VM_EXEC)
+ flush_user_icache_range_asm(start, end);
+ flush_tlb_range(vma, start, end);
+}
+
void flush_cache_mm(struct mm_struct *mm)
{
struct vm_area_struct *vma;
- pgd_t *pgd;
/* Flushing the whole cache on each cpu takes forever on
rp3440, etc. So, avoid it if the mm isn't too big. */
@@ -558,45 +581,22 @@ 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);
- if (vma->vm_flags & VM_EXEC)
- flush_user_icache_range_asm(vma->vm_start, vma->vm_end);
- flush_tlb_range(vma, vma->vm_start, vma->vm_end);
- }
+ for (vma = mm->mmap; vma; vma = vma->vm_next)
+ flush_user_cache_tlb(vma, vma->vm_start, vma->vm_end);
+ preempt_enable();
return;
}
- pgd = mm->pgd;
- for (vma = mm->mmap; vma; vma = vma->vm_next) {
- unsigned long addr;
-
- for (addr = vma->vm_start; addr < vma->vm_end;
- addr += PAGE_SIZE) {
- unsigned long pfn;
- pte_t *ptep = get_ptep(pgd, addr);
- if (!ptep)
- continue;
- pfn = pte_pfn(*ptep);
- if (!pfn_valid(pfn))
- continue;
- if (unlikely(mm->context)) {
- flush_tlb_page(vma, addr);
- __flush_cache_page(vma, addr, PFN_PHYS(pfn));
- } else {
- __purge_cache_page(vma, addr, PFN_PHYS(pfn));
- }
- }
- }
+ for (vma = mm->mmap; vma; vma = vma->vm_next)
+ flush_cache_pages(vma, mm, vma->vm_start, vma->vm_end);
+ preempt_enable();
}
void flush_cache_range(struct vm_area_struct *vma,
unsigned long start, unsigned long end)
{
- pgd_t *pgd;
- unsigned long addr;
-
if ((!IS_ENABLED(CONFIG_SMP) || !arch_irqs_disabled()) &&
end - start >= parisc_cache_flush_threshold) {
if (vma->vm_mm->context)
@@ -605,30 +605,15 @@ void flush_cache_range(struct vm_area_struct *vma,
return;
}
+ preempt_disable();
if (vma->vm_mm->context == mfsp(3)) {
- flush_user_dcache_range_asm(start, end);
- if (vma->vm_flags & VM_EXEC)
- flush_user_icache_range_asm(start, end);
- flush_tlb_range(vma, start, end);
+ flush_user_cache_tlb(vma, start, end);
+ preempt_enable();
return;
}
- pgd = vma->vm_mm->pgd;
- for (addr = vma->vm_start; addr < vma->vm_end; addr += PAGE_SIZE) {
- unsigned long pfn;
- pte_t *ptep = get_ptep(pgd, addr);
- if (!ptep)
- continue;
- pfn = pte_pfn(*ptep);
- if (pfn_valid(pfn)) {
- if (unlikely(vma->vm_mm->context)) {
- flush_tlb_page(vma, addr);
- __flush_cache_page(vma, addr, PFN_PHYS(pfn));
- } else {
- __purge_cache_page(vma, addr, PFN_PHYS(pfn));
- }
- }
- }
+ flush_cache_pages(vma, vma->vm_mm, vma->vm_start, vma->vm_end);
+ preempt_enable();
}
void