Commit b4d20eff authored by Linus Walleij's avatar Linus Walleij Committed by Russell King (Oracle)
Browse files

ARM: 9387/2: mm: Rewrite cacheflush vtables in CFI safe C



Instead of defining all cache flush operations with an assembly
macro in proc-macros.S, provide an explicit struct cpu_cache_fns
for each CPU cache type in mm/cache.c.

As a side effect from rewriting the vtables in C, we can
avoid the aliasing for the "louis" cache callback, instead we
can just assign the NN_flush_kern_cache_all() function to the
louis callback in the C vtable.

As the louis cache callback is called explicitly (not through the
vtable) if we only have one type of cache support compiled in, we
need an ifdef quirk for this in the !MULTI_CACHE case.

Feroceon and XScale have some dma mapping quirk, in this case we
can just define two structs and assign all but one callback to the
main implementation; since each of them invoked define_cache_functions
twice they require MULTI_CACHE by definition so the compiled-in
shortcut is not used on these variants.

Tested-by: default avatarKees Cook <keescook@chromium.org>
Reviewed-by: default avatarSami Tolvanen <samitolvanen@google.com>
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Signed-off-by: default avatarRussell King (Oracle) <rmk+kernel@armlinux.org.uk>
parent 2074beeb
Loading
Loading
Loading
Loading
+9 −19
Original line number Diff line number Diff line
@@ -118,6 +118,10 @@
# define MULTI_CACHE 1
#endif

#ifdef CONFIG_CPU_CACHE_NOP
#  define MULTI_CACHE 1
#endif

#if defined(CONFIG_CPU_V7M)
#  define MULTI_CACHE 1
#endif
@@ -126,29 +130,15 @@
#error Unknown cache maintenance model
#endif

#ifndef __ASSEMBLER__
static inline void nop_flush_icache_all(void) { }
static inline void nop_flush_kern_cache_all(void) { }
static inline void nop_flush_kern_cache_louis(void) { }
static inline void nop_flush_user_cache_all(void) { }
static inline void nop_flush_user_cache_range(unsigned long a,
		unsigned long b, unsigned int c) { }

static inline void nop_coherent_kern_range(unsigned long a, unsigned long b) { }
static inline int nop_coherent_user_range(unsigned long a,
		unsigned long b) { return 0; }
static inline void nop_flush_kern_dcache_area(void *a, size_t s) { }

static inline void nop_dma_flush_range(const void *a, const void *b) { }

static inline void nop_dma_map_area(const void *s, size_t l, int f) { }
static inline void nop_dma_unmap_area(const void *s, size_t l, int f) { }
#endif

#ifndef MULTI_CACHE
#define __cpuc_flush_icache_all		__glue(_CACHE,_flush_icache_all)
#define __cpuc_flush_kern_all		__glue(_CACHE,_flush_kern_cache_all)
/* This function only has a dedicated assembly callback on the v7 cache */
#ifdef CONFIG_CPU_CACHE_V7
#define __cpuc_flush_kern_louis		__glue(_CACHE,_flush_kern_cache_louis)
#else
#define __cpuc_flush_kern_louis		__glue(_CACHE,_flush_kern_cache_all)
#endif
#define __cpuc_flush_user_all		__glue(_CACHE,_flush_user_cache_all)
#define __cpuc_flush_user_range		__glue(_CACHE,_flush_user_cache_range)
#define __cpuc_coherent_kern_range	__glue(_CACHE,_coherent_kern_range)
+1 −0
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@ obj-$(CONFIG_CPU_CACHE_V7) += cache-v7.o
obj-$(CONFIG_CPU_CACHE_FA)	+= cache-fa.o
obj-$(CONFIG_CPU_CACHE_NOP)	+= cache-nop.o
obj-$(CONFIG_CPU_CACHE_V7M)	+= cache-v7m.o
obj-y				+= cache.o

obj-$(CONFIG_CPU_COPY_V4WT)	+= copypage-v4wt.o
obj-$(CONFIG_CPU_COPY_V4WB)	+= copypage-v4wb.o
+1 −0
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@
 * Copyright (C) 2015-2016 Broadcom
 */

#include <linux/cfi_types.h>
#include <linux/err.h>
#include <linux/spinlock.h>
#include <linux/io.h>
+0 −8
Original line number Diff line number Diff line
@@ -243,11 +243,3 @@ SYM_FUNC_END(fa_dma_map_area)
SYM_TYPED_FUNC_START(fa_dma_unmap_area)
	ret	lr
SYM_FUNC_END(fa_dma_unmap_area)

	.globl	fa_flush_kern_cache_louis
	.equ	fa_flush_kern_cache_louis, fa_flush_kern_cache_all

	__INITDATA

	@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
	define_cache_functions fa
+0 −8
Original line number Diff line number Diff line
@@ -18,9 +18,6 @@ SYM_TYPED_FUNC_START(nop_flush_kern_cache_all)
	ret	lr
SYM_FUNC_END(nop_flush_kern_cache_all)

	.globl nop_flush_kern_cache_louis
	.equ nop_flush_kern_cache_louis, nop_flush_icache_all

SYM_TYPED_FUNC_START(nop_flush_user_cache_all)
	ret	lr
SYM_FUNC_END(nop_flush_user_cache_all)
@@ -50,11 +47,6 @@ SYM_TYPED_FUNC_START(nop_dma_map_area)
	ret	lr
SYM_FUNC_END(nop_dma_map_area)

	__INITDATA

	@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
	define_cache_functions nop

SYM_TYPED_FUNC_START(nop_dma_unmap_area)
	ret	lr
SYM_FUNC_END(nop_dma_unmap_area)
Loading