Commit c6d96328 authored by Helge Deller's avatar Helge Deller
Browse files

parisc: Add cacheflush() syscall



Signed-off-by: default avatarHelge Deller <deller@gmx.de>
parent 40c9c62c
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
/* 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 */
+49 −0
Original line number Diff line number Diff line
@@ -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;
}
+1 −0
Original line number Diff line number Diff line
@@ -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