@@ -581,6 +581,13 @@
.word (fault_addr - .), (except_addr - .) ! \
.previous
+#else /* __ASSEMBLY__ */
+
+#ifdef CONFIG_64BIT
+# define COND(x) "*" __stringify(x)
+#else
+# define COND(x) __stringify(x)
+#endif
#endif /* __ASSEMBLY__ */
#endif
new file mode 100644
@@ -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 */
@@ -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;
@@ -774,3 +776,47 @@ 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 (cache & ~BCACHE)
+ return -EINVAL;
+ if (!access_ok((void __user *) addr, bytes))
+ return -EFAULT;
+ if ((cache_info.dc_size == 0) && (cache_info.ic_size == 0))
+ return 0;
+
+ end = addr + bytes;
+ if (end < addr)
+ return -EINVAL; /* wrap-around */
+
+ if (cache & ICACHE) {
+ start = addr;
+ __asm__ __volatile__ (
+ "1: cmpb," COND(<<) ",n %0,%2,1b\n"
+ " fic,m %3(%4,%0)\n"
+ "2:\n"
+ ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 2b)
+ : "+r" (start), "+r" (error)
+ : "r" (end), "r" (icache_stride), "i" (SR_USER));
+ }
+
+ if (cache & DCACHE && error == 0) {
+ start = addr;
+ __asm__ __volatile__ (
+ "1: cmpb," COND(<<) ",n %0,%2,1b\n"
+ " fdc,m %3(%4,%0)\n"
+ "2:\n"
+ ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 2b)
+ : "+r" (start), "+r" (error)
+ : "r" (end), "r" (dcache_stride), "i" (SR_USER));
+ }
+
+ return error;
+}
@@ -400,6 +400,7 @@
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
Implement the missing cacheflush() syscall. Signed-off-by: Helge Deller <deller@gmx.de> --- arch/parisc/include/asm/assembly.h | 7 ++++ arch/parisc/include/uapi/asm/cachectl.h | 12 +++++++ arch/parisc/kernel/cache.c | 46 +++++++++++++++++++++++++ arch/parisc/kernel/syscalls/syscall.tbl | 1 + 4 files changed, 66 insertions(+) create mode 100644 arch/parisc/include/uapi/asm/cachectl.h -- 2.40.1