Commit 6b0ef279 authored by Ard Biesheuvel's avatar Ard Biesheuvel Committed by Russell King (Oracle)
Browse files

ARM: 9384/2: mm: Make tlbflush routines CFI safe



Instead of avoiding CFI entirely on the TLB flush helpers, reorganize
the code so that the CFI machinery can deal with it. The important
things to take into account are:
- functions in asm called indirectly from C need to be defined using
  SYM_TYPED_FUNC_START()
- a reference to the asm function needs to be visible to the compiler,
  in order to get it to emit the typeid symbol.

The latter means that defining the cpu_tlb_fns structs is best done from
C code, so that the references in the static initializers will be
visible to the compiler.

Signed-off-by: default avatarArd Biesheuvel <ardb@kernel.org>
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 4cece764
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -62,6 +62,7 @@ obj-$(CONFIG_CPU_TLB_FEROCEON) += tlb-v4wbi.o # reuse v4wbi TLB functions
obj-$(CONFIG_CPU_TLB_V6)	+= tlb-v6.o
obj-$(CONFIG_CPU_TLB_V7)	+= tlb-v7.o
obj-$(CONFIG_CPU_TLB_FA)	+= tlb-fa.o
obj-y				+= tlb.o

obj-$(CONFIG_CPU_ARM7TDMI)	+= proc-arm7tdmi.o
obj-$(CONFIG_CPU_ARM720T)	+= proc-arm720.o
+0 −15
Original line number Diff line number Diff line
@@ -338,21 +338,6 @@ ENTRY(\name\()_cache_fns)
	.size	\name\()_cache_fns, . - \name\()_cache_fns
.endm

.macro define_tlb_functions name:req, flags_up:req, flags_smp
	.type	\name\()_tlb_fns, #object
	.align 2
ENTRY(\name\()_tlb_fns)
	.long	\name\()_flush_user_tlb_range
	.long	\name\()_flush_kern_tlb_range
	.ifnb \flags_smp
		ALT_SMP(.long	\flags_smp )
		ALT_UP(.long	\flags_up )
	.else
		.long	\flags_up
	.endif
	.size	\name\()_tlb_fns, . - \name\()_tlb_fns
.endm

.macro globl_equ x, y
	.globl	\x
	.equ	\x, \y
+5 −7
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
 */
#include <linux/linkage.h>
#include <linux/init.h>
#include <linux/cfi_types.h>
#include <asm/assembler.h>
#include <asm/asm-offsets.h>
#include <asm/tlbflush.h>
@@ -31,7 +32,7 @@
 *	- mm    - mm_struct describing address space
 */
	.align	4
ENTRY(fa_flush_user_tlb_range)
SYM_TYPED_FUNC_START(fa_flush_user_tlb_range)
	vma_vm_mm ip, r2
	act_mm	r3				@ get current->active_mm
	eors	r3, ip, r3			@ == mm ?
@@ -46,9 +47,10 @@ ENTRY(fa_flush_user_tlb_range)
	blo	1b
	mcr	p15, 0, r3, c7, c10, 4		@ data write barrier
	ret	lr
SYM_FUNC_END(fa_flush_user_tlb_range)


ENTRY(fa_flush_kern_tlb_range)
SYM_TYPED_FUNC_START(fa_flush_kern_tlb_range)
	mov	r3, #0
	mcr	p15, 0, r3, c7, c10, 4		@ drain WB
	bic	r0, r0, #0x0ff
@@ -60,8 +62,4 @@ ENTRY(fa_flush_kern_tlb_range)
	mcr	p15, 0, r3, c7, c10, 4		@ data write barrier
	mcr	p15, 0, r3, c7, c5, 4		@ prefetch flush (isb)
	ret	lr

	__INITDATA

	/* define struct cpu_tlb_fns (see <asm/tlbflush.h> and proc-macros.S) */
	define_tlb_functions fa, fa_tlb_flags
SYM_FUNC_END(fa_flush_kern_tlb_range)
+9 −6
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@
 */
#include <linux/linkage.h>
#include <linux/init.h>
#include <linux/cfi_types.h>
#include <asm/assembler.h>
#include <asm/asm-offsets.h>
#include <asm/tlbflush.h>
@@ -27,7 +28,7 @@
 *	- mm    - mm_struct describing address space
 */
	.align	5
ENTRY(v4_flush_user_tlb_range)
SYM_TYPED_FUNC_START(v4_flush_user_tlb_range)
	vma_vm_mm ip, r2
	act_mm	r3				@ get current->active_mm
	eors	r3, ip, r3				@ == mm ?
@@ -40,6 +41,7 @@ ENTRY(v4_flush_user_tlb_range)
	cmp	r0, r1
	blo	1b
	ret	lr
SYM_FUNC_END(v4_flush_user_tlb_range)

/*
 *	v4_flush_kern_tlb_range(start, end)
@@ -50,10 +52,11 @@ ENTRY(v4_flush_user_tlb_range)
 *	- start - virtual address (may not be aligned)
 *	- end   - virtual address (may not be aligned)
 */
#ifdef CONFIG_CFI_CLANG
SYM_TYPED_FUNC_START(v4_flush_kern_tlb_range)
	b	.v4_flush_kern_tlb_range
SYM_FUNC_END(v4_flush_kern_tlb_range)
#else
.globl v4_flush_kern_tlb_range
.equ v4_flush_kern_tlb_range, .v4_flush_kern_tlb_range

	__INITDATA

	/* define struct cpu_tlb_fns (see <asm/tlbflush.h> and proc-macros.S) */
	define_tlb_functions v4, v4_tlb_flags
#endif
+5 −7
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@
 */
#include <linux/linkage.h>
#include <linux/init.h>
#include <linux/cfi_types.h>
#include <asm/assembler.h>
#include <asm/asm-offsets.h>
#include <asm/tlbflush.h>
@@ -27,7 +28,7 @@
 *	- mm    - mm_struct describing address space
 */
	.align	5
ENTRY(v4wb_flush_user_tlb_range)
SYM_TYPED_FUNC_START(v4wb_flush_user_tlb_range)
	vma_vm_mm ip, r2
	act_mm	r3				@ get current->active_mm
	eors	r3, ip, r3				@ == mm ?
@@ -43,6 +44,7 @@ ENTRY(v4wb_flush_user_tlb_range)
	cmp	r0, r1
	blo	1b
	ret	lr
SYM_FUNC_END(v4wb_flush_user_tlb_range)

/*
 *	v4_flush_kern_tlb_range(start, end)
@@ -53,7 +55,7 @@ ENTRY(v4wb_flush_user_tlb_range)
 *	- start - virtual address (may not be aligned)
 *	- end   - virtual address (may not be aligned)
 */
ENTRY(v4wb_flush_kern_tlb_range)
SYM_TYPED_FUNC_START(v4wb_flush_kern_tlb_range)
	mov	r3, #0
	mcr	p15, 0, r3, c7, c10, 4		@ drain WB
	bic	r0, r0, #0x0ff
@@ -64,8 +66,4 @@ ENTRY(v4wb_flush_kern_tlb_range)
	cmp	r0, r1
	blo	1b
	ret	lr

	__INITDATA

	/* define struct cpu_tlb_fns (see <asm/tlbflush.h> and proc-macros.S) */
	define_tlb_functions v4wb, v4wb_tlb_flags
SYM_FUNC_END(v4wb_flush_kern_tlb_range)
Loading