summaryrefslogtreecommitdiff
path: root/arch/powerpc/lib
diff options
context:
space:
mode:
authorOliver O'Halloran <oohall@gmail.com>2017-10-19 18:13:55 +1100
committerMichael Ellerman <mpe@ellerman.id.au>2017-11-13 08:00:31 +1100
commit6c44741d75a27985a0496cd58b123a58c7177108 (patch)
treecabc19300cc31e282e8663bc071b37ab24187c00 /arch/powerpc/lib
parent32ce3862af3c42a3890e99846a8d1ad8871a49f9 (diff)
powerpc/lib: Implement UACCESS_FLUSHCACHE API
Implement the architecture specific portitions of the UACCESS_FLUSHCACHE API. This provides functions for the copy_user_flushcache iterator that ensure that when the copy is finished the destination buffer contains a copy of the original and that the destination buffer is clean in the processor caches. Signed-off-by: Oliver O'Halloran <oohall@gmail.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Diffstat (limited to 'arch/powerpc/lib')
-rw-r--r--arch/powerpc/lib/pmem.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/arch/powerpc/lib/pmem.c b/arch/powerpc/lib/pmem.c
index 0fa09262ca13..53c018762e1c 100644
--- a/arch/powerpc/lib/pmem.c
+++ b/arch/powerpc/lib/pmem.c
@@ -13,6 +13,7 @@
#include <linux/string.h>
#include <linux/export.h>
+#include <linux/uaccess.h>
#include <asm/cacheflush.h>
@@ -32,3 +33,35 @@ void arch_invalidate_pmem(void *addr, size_t size)
flush_inval_dcache_range(start, start + size);
}
EXPORT_SYMBOL(arch_invalidate_pmem);
+
+/*
+ * CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE symbols
+ */
+long __copy_from_user_flushcache(void *dest, const void __user *src,
+ unsigned size)
+{
+ unsigned long copied, start = (unsigned long) dest;
+
+ copied = __copy_from_user(dest, src, size);
+ flush_inval_dcache_range(start, start + size);
+
+ return copied;
+}
+
+void *memcpy_flushcache(void *dest, const void *src, size_t size)
+{
+ unsigned long start = (unsigned long) dest;
+
+ memcpy(dest, src, size);
+ flush_inval_dcache_range(start, start + size);
+
+ return dest;
+}
+EXPORT_SYMBOL(memcpy_flushcache);
+
+void memcpy_page_flushcache(char *to, struct page *page, size_t offset,
+ size_t len)
+{
+ memcpy_flushcache(to, page_to_virt(page) + offset, len);
+}
+EXPORT_SYMBOL(memcpy_page_flushcache);