parisc: Add cacheflush() syscall
authorHelge Deller <deller@gmx.de>
Fri, 26 May 2023 08:59:15 +0000 (10:59 +0200)
committerHelge Deller <deller@gmx.de>
Fri, 30 Jun 2023 15:14:13 +0000 (17:14 +0200)
Signed-off-by: Helge Deller <deller@gmx.de>
arch/parisc/include/uapi/asm/cachectl.h [new file with mode: 0644]
arch/parisc/kernel/cache.c
arch/parisc/kernel/syscalls/syscall.tbl

diff --git a/arch/parisc/include/uapi/asm/cachectl.h b/arch/parisc/include/uapi/asm/cachectl.h
new file mode 100644 (file)
index 0000000..68d6b45
--- /dev/null
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _ASM_CACHECTL
+#define _ASM_CACHECTL
+
+/*
+ * Options for cacheflush system call
+ */
+#define ICACHE (1<<0)          /* flush instruction cache        */
+#define DCACHE (1<<1)          /* writeback and flush data cache */
+#define BCACHE (ICACHE|DCACHE) /* flush both caches              */
+
+#endif /* _ASM_CACHECTL */
index 5011602..b55b35c 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/pagemap.h>
 #include <linux/sched.h>
 #include <linux/sched/mm.h>
+#include <linux/syscalls.h>
 #include <asm/pdc.h>
 #include <asm/cache.h>
 #include <asm/cacheflush.h>
@@ -28,6 +29,7 @@
 #include <asm/sections.h>
 #include <asm/shmparam.h>
 #include <asm/mmu_context.h>
+#include <asm/cachectl.h>
 
 int split_tlb __ro_after_init;
 int dcache_stride __ro_after_init;
@@ -790,3 +792,50 @@ void invalidate_kernel_vmap_range(void *vaddr, int size)
        flush_tlb_kernel_range(start, end);
 }
 EXPORT_SYMBOL(invalidate_kernel_vmap_range);
+
+
+SYSCALL_DEFINE3(cacheflush, unsigned long, addr, unsigned long, bytes,
+       unsigned int, cache)
+{
+       unsigned long start, end;
+       ASM_EXCEPTIONTABLE_VAR(error);
+
+       if (bytes == 0)
+               return 0;
+       if (!access_ok((void __user *) addr, bytes))
+               return -EFAULT;
+
+       end = addr + bytes;
+
+       if (cache & DCACHE) {
+               start = addr;
+               __asm__ __volatile__ (
+#ifdef CONFIG_64BIT
+                       "1: cmpb,*<<,n  %0,%2,1b\n"
+#else
+                       "1: cmpb,<<,n   %0,%2,1b\n"
+#endif
+                       "   fic,m       %3(%4,%0)\n"
+                       "2: sync\n"
+                       ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 2b)
+                       : "+r" (start), "+r" (error)
+                       : "r" (end), "r" (dcache_stride), "i" (SR_USER));
+       }
+
+       if (cache & ICACHE && error == 0) {
+               start = addr;
+               __asm__ __volatile__ (
+#ifdef CONFIG_64BIT
+                       "1: cmpb,*<<,n  %0,%2,1b\n"
+#else
+                       "1: cmpb,<<,n   %0,%2,1b\n"
+#endif
+                       "   fdc,m       %3(%4,%0)\n"
+                       "2: sync\n"
+                       ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 2b)
+                       : "+r" (start), "+r" (error)
+                       : "r" (end), "r" (icache_stride), "i" (SR_USER));
+       }
+
+       return error;
+}
index 3c71fad..a0a9145 100644 (file)
 353    common  pkey_free               sys_pkey_free
 354    common  rseq                    sys_rseq
 355    common  kexec_file_load         sys_kexec_file_load             sys_kexec_file_load
+356    common  cacheflush              sys_cacheflush
 # up to 402 is unassigned and reserved for arch specific syscalls
 403    32      clock_gettime64                 sys_clock_gettime               sys_clock_gettime
 404    32      clock_settime64                 sys_clock_settime               sys_clock_settime