All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] Initial Spectre variant 1 patches
@ 2018-05-31 13:30 Russell King - ARM Linux
  2018-05-31 13:31 ` [PATCH 1/3] ARM: spectre-v1: add speculation barrier (csdb) macros Russell King
                   ` (3 more replies)
  0 siblings, 4 replies; 10+ messages in thread
From: Russell King - ARM Linux @ 2018-05-31 13:30 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

This series adds initial support for the Spectre variant 1 workarounds
to the kernel.  This does _not_ cover the user accessors, which are
still in development.

The series adds support for the array_index_mask_nospec() macro, used
by generic kernel code to mask out of bounds pointers, and also adds
the syscall table hardening.

 arch/arm/include/asm/assembler.h |  8 ++++++++
 arch/arm/include/asm/barrier.h   | 31 +++++++++++++++++++++++++++++++
 arch/arm/kernel/entry-common.S   | 14 +++-----------
 arch/arm/kernel/entry-header.S   | 25 +++++++++++++++++++++++++
 4 files changed, 67 insertions(+), 11 deletions(-)

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 8.8Mbps down 630kbps up
According to speedtest.net: 8.21Mbps down 510kbps up

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 1/3] ARM: spectre-v1: add speculation barrier (csdb) macros
  2018-05-31 13:30 [PATCH 0/3] Initial Spectre variant 1 patches Russell King - ARM Linux
@ 2018-05-31 13:31 ` Russell King
  2018-05-31 14:17   ` Mark Rutland
  2018-05-31 13:31 ` [PATCH 2/3] ARM: spectre-v1: add array_index_mask_nospec() implementation Russell King
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 10+ messages in thread
From: Russell King @ 2018-05-31 13:31 UTC (permalink / raw)
  To: linux-arm-kernel

Add assembly and C macros for the new CSDB instruction.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/include/asm/assembler.h |  8 ++++++++
 arch/arm/include/asm/barrier.h   | 13 +++++++++++++
 2 files changed, 21 insertions(+)

diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index bc8d4bbd82e2..ef1386b1af9b 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -447,6 +447,14 @@ THUMB(	orr	\reg , \reg , #PSR_T_BIT	)
 	.size \name , . - \name
 	.endm
 
+	.macro	csdb
+#ifdef CONFIG_THUMB2_KERNEL
+	.inst.w	0xf3af8014
+#else
+	.inst	0xe320f014
+#endif
+	.endm
+
 	.macro check_uaccess, addr:req, size:req, limit:req, tmp:req, bad:req
 #ifndef CONFIG_CPU_USE_DOMAINS
 	adds	\tmp, \addr, #\size - 1
diff --git a/arch/arm/include/asm/barrier.h b/arch/arm/include/asm/barrier.h
index 40f5c410fd8c..3d9c1d4b7e75 100644
--- a/arch/arm/include/asm/barrier.h
+++ b/arch/arm/include/asm/barrier.h
@@ -17,6 +17,12 @@
 #define isb(option) __asm__ __volatile__ ("isb " #option : : : "memory")
 #define dsb(option) __asm__ __volatile__ ("dsb " #option : : : "memory")
 #define dmb(option) __asm__ __volatile__ ("dmb " #option : : : "memory")
+#ifdef CONFIG_THUMB2_KERNEL
+#define CSDB	".inst.w 0xf3af8014"
+#else
+#define CSDB	".inst	0xe320f014"
+#endif
+#define csdb() __asm__ __volatile__(CSDB : : : "memory")
 #elif defined(CONFIG_CPU_XSC3) || __LINUX_ARM_ARCH__ == 6
 #define isb(x) __asm__ __volatile__ ("mcr p15, 0, %0, c7, c5, 4" \
 				    : : "r" (0) : "memory")
@@ -37,6 +43,13 @@
 #define dmb(x) __asm__ __volatile__ ("" : : : "memory")
 #endif
 
+#ifndef CSDB
+#define CSDB
+#endif
+#ifndef csdb
+#define csdb()
+#endif
+
 #ifdef CONFIG_ARM_HEAVY_MB
 extern void (*soc_mb)(void);
 extern void arm_heavy_mb(void);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 2/3] ARM: spectre-v1: add array_index_mask_nospec() implementation
  2018-05-31 13:30 [PATCH 0/3] Initial Spectre variant 1 patches Russell King - ARM Linux
  2018-05-31 13:31 ` [PATCH 1/3] ARM: spectre-v1: add speculation barrier (csdb) macros Russell King
@ 2018-05-31 13:31 ` Russell King
  2018-05-31 14:22   ` Mark Rutland
  2018-05-31 13:31 ` [PATCH 3/3] ARM: spectre-v1: fix syscall entry Russell King
  2018-05-31 18:04 ` [PATCH 0/3] Initial Spectre variant 1 patches Tony Lindgren
  3 siblings, 1 reply; 10+ messages in thread
From: Russell King @ 2018-05-31 13:31 UTC (permalink / raw)
  To: linux-arm-kernel

Add an implementation of the array_index_mask_nospec() function for
mitigating Spectre variant 1 throughout the kernel.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/include/asm/barrier.h | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/arch/arm/include/asm/barrier.h b/arch/arm/include/asm/barrier.h
index 3d9c1d4b7e75..a89adcf53b99 100644
--- a/arch/arm/include/asm/barrier.h
+++ b/arch/arm/include/asm/barrier.h
@@ -76,6 +76,24 @@ extern void arm_heavy_mb(void);
 #define __smp_rmb()	__smp_mb()
 #define __smp_wmb()	dmb(ishst)
 
+#ifdef CONFIG_CPU_SPECTRE
+static inline unsigned long array_index_mask_nospec(unsigned long idx,
+						    unsigned long sz)
+{
+	unsigned long mask;
+
+	asm(	"cmp	%1, %2\n"
+	"	sbc	%0, %1, %1\n"
+	CSDB
+	: "=r" (mask)
+	: "r" (idx), "Ir" (sz)
+	: "cc");
+
+	return mask;
+}
+#define array_index_mask_nospec array_index_mask_nospec
+#endif
+
 #include <asm-generic/barrier.h>
 
 #endif /* !__ASSEMBLY__ */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 3/3] ARM: spectre-v1: fix syscall entry
  2018-05-31 13:30 [PATCH 0/3] Initial Spectre variant 1 patches Russell King - ARM Linux
  2018-05-31 13:31 ` [PATCH 1/3] ARM: spectre-v1: add speculation barrier (csdb) macros Russell King
  2018-05-31 13:31 ` [PATCH 2/3] ARM: spectre-v1: add array_index_mask_nospec() implementation Russell King
@ 2018-05-31 13:31 ` Russell King
  2018-05-31 15:55   ` Mark Rutland
  2018-05-31 18:04 ` [PATCH 0/3] Initial Spectre variant 1 patches Tony Lindgren
  3 siblings, 1 reply; 10+ messages in thread
From: Russell King @ 2018-05-31 13:31 UTC (permalink / raw)
  To: linux-arm-kernel

Prevent speculation at the syscall table decoding by clamping the index
used to zero on invalid system call numbers, and using the csdb
speculative barrier.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/kernel/entry-common.S | 14 +++-----------
 arch/arm/kernel/entry-header.S | 25 +++++++++++++++++++++++++
 2 files changed, 28 insertions(+), 11 deletions(-)

diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index 3c4f88701f22..78b9f20dd6a3 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -242,9 +242,7 @@ ENTRY(vector_swi)
 	tst	r10, #_TIF_SYSCALL_WORK		@ are we tracing syscalls?
 	bne	__sys_trace
 
-	cmp	scno, #NR_syscalls		@ check upper syscall limit
-	badr	lr, ret_fast_syscall		@ return address
-	ldrcc	pc, [tbl, scno, lsl #2]		@ call sys_* routine
+	invoke_syscall tbl, scno, r10, ret_fast_syscall
 
 	add	r1, sp, #S_OFF
 2:	cmp	scno, #(__ARM_NR_BASE - __NR_SYSCALL_BASE)
@@ -278,14 +276,8 @@ ENDPROC(vector_swi)
 	mov	r1, scno
 	add	r0, sp, #S_OFF
 	bl	syscall_trace_enter
-
-	badr	lr, __sys_trace_return		@ return address
-	mov	scno, r0			@ syscall number (possibly new)
-	add	r1, sp, #S_R0 + S_OFF		@ pointer to regs
-	cmp	scno, #NR_syscalls		@ check upper syscall limit
-	ldmccia	r1, {r0 - r6}			@ have to reload r0 - r6
-	stmccia	sp, {r4, r5}			@ and update the stack args
-	ldrcc	pc, [tbl, scno, lsl #2]		@ call sys_* routine
+	mov	scno, r0
+	invoke_syscall tbl, scno, r10, __sys_trace_return, reload=1
 	cmp	scno, #-1			@ skip the syscall?
 	bne	2b
 	add	sp, sp, #S_OFF			@ restore stack
diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S
index 0f07579af472..773424843d6e 100644
--- a/arch/arm/kernel/entry-header.S
+++ b/arch/arm/kernel/entry-header.S
@@ -378,6 +378,31 @@
 #endif
 	.endm
 
+	.macro	invoke_syscall, table, nr, tmp, ret, reload=0
+#ifdef CONFIG_CPU_SPECTRE
+	mov	\tmp, \nr
+	cmp	\tmp, #NR_syscalls		@ check upper syscall limit
+	movcs	\tmp, #0
+	csdb
+	badr	lr, \ret			@ return address
+	.if	\reload
+	add	r1, sp, #S_R0 + S_OFF		@ pointer to regs
+	ldmccia	r1, {r0 - r6}			@ reload r0-r6
+	stmccia	sp, {r4, r5}			@ update stack arguments
+	.endif
+	ldrcc	pc, [\table, \tmp, lsl #2]	@ call sys_* routine
+#else
+	cmp	\nr, #NR_syscalls		@ check upper syscall limit
+	badr	lr, \ret			@ return address
+	.if	\reload
+	add	r1, sp, #S_R0 + S_OFF		@ pointer to regs
+	ldmccia	r1, {r0 - r6}			@ reload r0-r6
+	stmccia	sp, {r4, r5}			@ update stack arguments
+	.endif
+	ldrcc	pc, [\table, \nr, lsl #2]	@ call sys_* routine
+#endif
+	.endm
+
 /*
  * These are the registers used in the syscall handler, and allow us to
  * have in theory up to 7 arguments to a function - r0 to r6.
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 1/3] ARM: spectre-v1: add speculation barrier (csdb) macros
  2018-05-31 13:31 ` [PATCH 1/3] ARM: spectre-v1: add speculation barrier (csdb) macros Russell King
@ 2018-05-31 14:17   ` Mark Rutland
  0 siblings, 0 replies; 10+ messages in thread
From: Mark Rutland @ 2018-05-31 14:17 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, May 31, 2018 at 02:31:12PM +0100, Russell King wrote:
> Add assembly and C macros for the new CSDB instruction.
> 
> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>

Looks correct to me per the Cache Speculation Side-chaneels 2.1
document.

Acked-by: Mark Rutland <mark.rutland@arm.com>

Mark.

> ---
>  arch/arm/include/asm/assembler.h |  8 ++++++++
>  arch/arm/include/asm/barrier.h   | 13 +++++++++++++
>  2 files changed, 21 insertions(+)
> 
> diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
> index bc8d4bbd82e2..ef1386b1af9b 100644
> --- a/arch/arm/include/asm/assembler.h
> +++ b/arch/arm/include/asm/assembler.h
> @@ -447,6 +447,14 @@ THUMB(	orr	\reg , \reg , #PSR_T_BIT	)
>  	.size \name , . - \name
>  	.endm
>  
> +	.macro	csdb
> +#ifdef CONFIG_THUMB2_KERNEL
> +	.inst.w	0xf3af8014
> +#else
> +	.inst	0xe320f014
> +#endif
> +	.endm
> +
>  	.macro check_uaccess, addr:req, size:req, limit:req, tmp:req, bad:req
>  #ifndef CONFIG_CPU_USE_DOMAINS
>  	adds	\tmp, \addr, #\size - 1
> diff --git a/arch/arm/include/asm/barrier.h b/arch/arm/include/asm/barrier.h
> index 40f5c410fd8c..3d9c1d4b7e75 100644
> --- a/arch/arm/include/asm/barrier.h
> +++ b/arch/arm/include/asm/barrier.h
> @@ -17,6 +17,12 @@
>  #define isb(option) __asm__ __volatile__ ("isb " #option : : : "memory")
>  #define dsb(option) __asm__ __volatile__ ("dsb " #option : : : "memory")
>  #define dmb(option) __asm__ __volatile__ ("dmb " #option : : : "memory")
> +#ifdef CONFIG_THUMB2_KERNEL
> +#define CSDB	".inst.w 0xf3af8014"
> +#else
> +#define CSDB	".inst	0xe320f014"
> +#endif
> +#define csdb() __asm__ __volatile__(CSDB : : : "memory")
>  #elif defined(CONFIG_CPU_XSC3) || __LINUX_ARM_ARCH__ == 6
>  #define isb(x) __asm__ __volatile__ ("mcr p15, 0, %0, c7, c5, 4" \
>  				    : : "r" (0) : "memory")
> @@ -37,6 +43,13 @@
>  #define dmb(x) __asm__ __volatile__ ("" : : : "memory")
>  #endif
>  
> +#ifndef CSDB
> +#define CSDB
> +#endif
> +#ifndef csdb
> +#define csdb()
> +#endif
> +
>  #ifdef CONFIG_ARM_HEAVY_MB
>  extern void (*soc_mb)(void);
>  extern void arm_heavy_mb(void);
> -- 
> 2.7.4
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 2/3] ARM: spectre-v1: add array_index_mask_nospec() implementation
  2018-05-31 13:31 ` [PATCH 2/3] ARM: spectre-v1: add array_index_mask_nospec() implementation Russell King
@ 2018-05-31 14:22   ` Mark Rutland
  0 siblings, 0 replies; 10+ messages in thread
From: Mark Rutland @ 2018-05-31 14:22 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, May 31, 2018 at 02:31:17PM +0100, Russell King wrote:
> Add an implementation of the array_index_mask_nospec() function for
> mitigating Spectre variant 1 throughout the kernel.
> 
> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
> ---
>  arch/arm/include/asm/barrier.h | 18 ++++++++++++++++++
>  1 file changed, 18 insertions(+)
> 
> diff --git a/arch/arm/include/asm/barrier.h b/arch/arm/include/asm/barrier.h
> index 3d9c1d4b7e75..a89adcf53b99 100644
> --- a/arch/arm/include/asm/barrier.h
> +++ b/arch/arm/include/asm/barrier.h
> @@ -76,6 +76,24 @@ extern void arm_heavy_mb(void);
>  #define __smp_rmb()	__smp_mb()
>  #define __smp_wmb()	dmb(ishst)
>  
> +#ifdef CONFIG_CPU_SPECTRE
> +static inline unsigned long array_index_mask_nospec(unsigned long idx,
> +						    unsigned long sz)
> +{
> +	unsigned long mask;
> +
> +	asm(	"cmp	%1, %2\n"
> +	"	sbc	%0, %1, %1\n"
> +	CSDB
> +	: "=r" (mask)
> +	: "r" (idx), "Ir" (sz)
> +	: "cc");
> +
> +	return mask;
> +}
> +#define array_index_mask_nospec array_index_mask_nospec
> +#endif

I believe that the asm should be volatile, otherwise there are cases
where the compiler could remove an invocation that's redundant under
architectural execution, but required under speculation [1].

With that made volatile:

Acked-by: Mark Rutland <mark.rutland@arm.com>

Thanks,
Mark.

[1] https://lkml.kernel.org/r/20180530060546.jnjoltsturoduohh at salmiak

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 3/3] ARM: spectre-v1: fix syscall entry
  2018-05-31 13:31 ` [PATCH 3/3] ARM: spectre-v1: fix syscall entry Russell King
@ 2018-05-31 15:55   ` Mark Rutland
  2018-05-31 16:06     ` [PATCH v2 " Russell King
  0 siblings, 1 reply; 10+ messages in thread
From: Mark Rutland @ 2018-05-31 15:55 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, May 31, 2018 at 02:31:23PM +0100, Russell King wrote:
> Prevent speculation at the syscall table decoding by clamping the index
> used to zero on invalid system call numbers, and using the csdb
> speculative barrier.
> 
> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
> ---
>  arch/arm/kernel/entry-common.S | 14 +++-----------
>  arch/arm/kernel/entry-header.S | 25 +++++++++++++++++++++++++
>  2 files changed, 28 insertions(+), 11 deletions(-)
> 
> diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
> index 3c4f88701f22..78b9f20dd6a3 100644
> --- a/arch/arm/kernel/entry-common.S
> +++ b/arch/arm/kernel/entry-common.S
> @@ -242,9 +242,7 @@ ENTRY(vector_swi)
>  	tst	r10, #_TIF_SYSCALL_WORK		@ are we tracing syscalls?
>  	bne	__sys_trace
>  
> -	cmp	scno, #NR_syscalls		@ check upper syscall limit
> -	badr	lr, ret_fast_syscall		@ return address
> -	ldrcc	pc, [tbl, scno, lsl #2]		@ call sys_* routine
> +	invoke_syscall tbl, scno, r10, ret_fast_syscall
>  
>  	add	r1, sp, #S_OFF
>  2:	cmp	scno, #(__ARM_NR_BASE - __NR_SYSCALL_BASE)
> @@ -278,14 +276,8 @@ ENDPROC(vector_swi)
>  	mov	r1, scno
>  	add	r0, sp, #S_OFF
>  	bl	syscall_trace_enter
> -
> -	badr	lr, __sys_trace_return		@ return address
> -	mov	scno, r0			@ syscall number (possibly new)
> -	add	r1, sp, #S_R0 + S_OFF		@ pointer to regs
> -	cmp	scno, #NR_syscalls		@ check upper syscall limit
> -	ldmccia	r1, {r0 - r6}			@ have to reload r0 - r6
> -	stmccia	sp, {r4, r5}			@ and update the stack args
> -	ldrcc	pc, [tbl, scno, lsl #2]		@ call sys_* routine
> +	mov	scno, r0
> +	invoke_syscall tbl, scno, r10, __sys_trace_return, reload=1
>  	cmp	scno, #-1			@ skip the syscall?
>  	bne	2b
>  	add	sp, sp, #S_OFF			@ restore stack

I *think* you might also need to adjust sys_syscall.

> diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S
> index 0f07579af472..773424843d6e 100644
> --- a/arch/arm/kernel/entry-header.S
> +++ b/arch/arm/kernel/entry-header.S
> @@ -378,6 +378,31 @@
>  #endif
>  	.endm
>  
> +	.macro	invoke_syscall, table, nr, tmp, ret, reload=0
> +#ifdef CONFIG_CPU_SPECTRE
> +	mov	\tmp, \nr
> +	cmp	\tmp, #NR_syscalls		@ check upper syscall limit
> +	movcs	\tmp, #0
> +	csdb

To the best of my understanding, this sequence is sufficient.

> +	badr	lr, \ret			@ return address
> +	.if	\reload
> +	add	r1, sp, #S_R0 + S_OFF		@ pointer to regs
> +	ldmccia	r1, {r0 - r6}			@ reload r0-r6
> +	stmccia	sp, {r4, r5}			@ update stack arguments
> +	.endif
> +	ldrcc	pc, [\table, \tmp, lsl #2]	@ call sys_* routine
> +#else
> +	cmp	\nr, #NR_syscalls		@ check upper syscall limit
> +	badr	lr, \ret			@ return address
> +	.if	\reload
> +	add	r1, sp, #S_R0 + S_OFF		@ pointer to regs
> +	ldmccia	r1, {r0 - r6}			@ reload r0-r6
> +	stmccia	sp, {r4, r5}			@ update stack arguments
> +	.endif
> +	ldrcc	pc, [\table, \nr, lsl #2]	@ call sys_* routine
> +#endif
> +	.endm

I couldn't find a nice way to avoid dupliacting the body without more
ifdeffery, given the nr parameter can't be clobbered.

So modulo sys_syscall, this looks good to me.

Mark.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v2 3/3] ARM: spectre-v1: fix syscall entry
  2018-05-31 15:55   ` Mark Rutland
@ 2018-05-31 16:06     ` Russell King
  2018-05-31 16:08       ` Mark Rutland
  0 siblings, 1 reply; 10+ messages in thread
From: Russell King @ 2018-05-31 16:06 UTC (permalink / raw)
  To: linux-arm-kernel

Prevent speculation at the syscall table decoding by clamping the index
used to zero on invalid system call numbers, and using the csdb
speculative barrier.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/kernel/entry-common.S | 18 +++++++-----------
 arch/arm/kernel/entry-header.S | 25 +++++++++++++++++++++++++
 2 files changed, 32 insertions(+), 11 deletions(-)

diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index 3c4f88701f22..20df608bf343 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -242,9 +242,7 @@ ENTRY(vector_swi)
 	tst	r10, #_TIF_SYSCALL_WORK		@ are we tracing syscalls?
 	bne	__sys_trace
 
-	cmp	scno, #NR_syscalls		@ check upper syscall limit
-	badr	lr, ret_fast_syscall		@ return address
-	ldrcc	pc, [tbl, scno, lsl #2]		@ call sys_* routine
+	invoke_syscall tbl, scno, r10, ret_fast_syscall
 
 	add	r1, sp, #S_OFF
 2:	cmp	scno, #(__ARM_NR_BASE - __NR_SYSCALL_BASE)
@@ -278,14 +276,8 @@ ENDPROC(vector_swi)
 	mov	r1, scno
 	add	r0, sp, #S_OFF
 	bl	syscall_trace_enter
-
-	badr	lr, __sys_trace_return		@ return address
-	mov	scno, r0			@ syscall number (possibly new)
-	add	r1, sp, #S_R0 + S_OFF		@ pointer to regs
-	cmp	scno, #NR_syscalls		@ check upper syscall limit
-	ldmccia	r1, {r0 - r6}			@ have to reload r0 - r6
-	stmccia	sp, {r4, r5}			@ and update the stack args
-	ldrcc	pc, [tbl, scno, lsl #2]		@ call sys_* routine
+	mov	scno, r0
+	invoke_syscall tbl, scno, r10, __sys_trace_return, reload=1
 	cmp	scno, #-1			@ skip the syscall?
 	bne	2b
 	add	sp, sp, #S_OFF			@ restore stack
@@ -363,6 +355,10 @@ ENTRY(\sym)
 		bic	scno, r0, #__NR_OABI_SYSCALL_BASE
 		cmp	scno, #__NR_syscall - __NR_SYSCALL_BASE
 		cmpne	scno, #NR_syscalls	@ check range
+#ifdef CONFIG_CPU_SPECTRE
+		movhs	scno, #0
+		csdb
+#endif
 		stmloia	sp, {r5, r6}		@ shuffle args
 		movlo	r0, r1
 		movlo	r1, r2
diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S
index 0f07579af472..773424843d6e 100644
--- a/arch/arm/kernel/entry-header.S
+++ b/arch/arm/kernel/entry-header.S
@@ -378,6 +378,31 @@
 #endif
 	.endm
 
+	.macro	invoke_syscall, table, nr, tmp, ret, reload=0
+#ifdef CONFIG_CPU_SPECTRE
+	mov	\tmp, \nr
+	cmp	\tmp, #NR_syscalls		@ check upper syscall limit
+	movcs	\tmp, #0
+	csdb
+	badr	lr, \ret			@ return address
+	.if	\reload
+	add	r1, sp, #S_R0 + S_OFF		@ pointer to regs
+	ldmccia	r1, {r0 - r6}			@ reload r0-r6
+	stmccia	sp, {r4, r5}			@ update stack arguments
+	.endif
+	ldrcc	pc, [\table, \tmp, lsl #2]	@ call sys_* routine
+#else
+	cmp	\nr, #NR_syscalls		@ check upper syscall limit
+	badr	lr, \ret			@ return address
+	.if	\reload
+	add	r1, sp, #S_R0 + S_OFF		@ pointer to regs
+	ldmccia	r1, {r0 - r6}			@ reload r0-r6
+	stmccia	sp, {r4, r5}			@ update stack arguments
+	.endif
+	ldrcc	pc, [\table, \nr, lsl #2]	@ call sys_* routine
+#endif
+	.endm
+
 /*
  * These are the registers used in the syscall handler, and allow us to
  * have in theory up to 7 arguments to a function - r0 to r6.
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v2 3/3] ARM: spectre-v1: fix syscall entry
  2018-05-31 16:06     ` [PATCH v2 " Russell King
@ 2018-05-31 16:08       ` Mark Rutland
  0 siblings, 0 replies; 10+ messages in thread
From: Mark Rutland @ 2018-05-31 16:08 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, May 31, 2018 at 05:06:32PM +0100, Russell King wrote:
> Prevent speculation at the syscall table decoding by clamping the index
> used to zero on invalid system call numbers, and using the csdb
> speculative barrier.
> 
> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>

Acked-by: Mark Rutland <mark.rutland@arm.com>

Mark.

> ---
>  arch/arm/kernel/entry-common.S | 18 +++++++-----------
>  arch/arm/kernel/entry-header.S | 25 +++++++++++++++++++++++++
>  2 files changed, 32 insertions(+), 11 deletions(-)
> 
> diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
> index 3c4f88701f22..20df608bf343 100644
> --- a/arch/arm/kernel/entry-common.S
> +++ b/arch/arm/kernel/entry-common.S
> @@ -242,9 +242,7 @@ ENTRY(vector_swi)
>  	tst	r10, #_TIF_SYSCALL_WORK		@ are we tracing syscalls?
>  	bne	__sys_trace
>  
> -	cmp	scno, #NR_syscalls		@ check upper syscall limit
> -	badr	lr, ret_fast_syscall		@ return address
> -	ldrcc	pc, [tbl, scno, lsl #2]		@ call sys_* routine
> +	invoke_syscall tbl, scno, r10, ret_fast_syscall
>  
>  	add	r1, sp, #S_OFF
>  2:	cmp	scno, #(__ARM_NR_BASE - __NR_SYSCALL_BASE)
> @@ -278,14 +276,8 @@ ENDPROC(vector_swi)
>  	mov	r1, scno
>  	add	r0, sp, #S_OFF
>  	bl	syscall_trace_enter
> -
> -	badr	lr, __sys_trace_return		@ return address
> -	mov	scno, r0			@ syscall number (possibly new)
> -	add	r1, sp, #S_R0 + S_OFF		@ pointer to regs
> -	cmp	scno, #NR_syscalls		@ check upper syscall limit
> -	ldmccia	r1, {r0 - r6}			@ have to reload r0 - r6
> -	stmccia	sp, {r4, r5}			@ and update the stack args
> -	ldrcc	pc, [tbl, scno, lsl #2]		@ call sys_* routine
> +	mov	scno, r0
> +	invoke_syscall tbl, scno, r10, __sys_trace_return, reload=1
>  	cmp	scno, #-1			@ skip the syscall?
>  	bne	2b
>  	add	sp, sp, #S_OFF			@ restore stack
> @@ -363,6 +355,10 @@ ENTRY(\sym)
>  		bic	scno, r0, #__NR_OABI_SYSCALL_BASE
>  		cmp	scno, #__NR_syscall - __NR_SYSCALL_BASE
>  		cmpne	scno, #NR_syscalls	@ check range
> +#ifdef CONFIG_CPU_SPECTRE
> +		movhs	scno, #0
> +		csdb
> +#endif
>  		stmloia	sp, {r5, r6}		@ shuffle args
>  		movlo	r0, r1
>  		movlo	r1, r2
> diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S
> index 0f07579af472..773424843d6e 100644
> --- a/arch/arm/kernel/entry-header.S
> +++ b/arch/arm/kernel/entry-header.S
> @@ -378,6 +378,31 @@
>  #endif
>  	.endm
>  
> +	.macro	invoke_syscall, table, nr, tmp, ret, reload=0
> +#ifdef CONFIG_CPU_SPECTRE
> +	mov	\tmp, \nr
> +	cmp	\tmp, #NR_syscalls		@ check upper syscall limit
> +	movcs	\tmp, #0
> +	csdb
> +	badr	lr, \ret			@ return address
> +	.if	\reload
> +	add	r1, sp, #S_R0 + S_OFF		@ pointer to regs
> +	ldmccia	r1, {r0 - r6}			@ reload r0-r6
> +	stmccia	sp, {r4, r5}			@ update stack arguments
> +	.endif
> +	ldrcc	pc, [\table, \tmp, lsl #2]	@ call sys_* routine
> +#else
> +	cmp	\nr, #NR_syscalls		@ check upper syscall limit
> +	badr	lr, \ret			@ return address
> +	.if	\reload
> +	add	r1, sp, #S_R0 + S_OFF		@ pointer to regs
> +	ldmccia	r1, {r0 - r6}			@ reload r0-r6
> +	stmccia	sp, {r4, r5}			@ update stack arguments
> +	.endif
> +	ldrcc	pc, [\table, \nr, lsl #2]	@ call sys_* routine
> +#endif
> +	.endm
> +
>  /*
>   * These are the registers used in the syscall handler, and allow us to
>   * have in theory up to 7 arguments to a function - r0 to r6.
> -- 
> 2.7.4
> 

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 0/3] Initial Spectre variant 1 patches
  2018-05-31 13:30 [PATCH 0/3] Initial Spectre variant 1 patches Russell King - ARM Linux
                   ` (2 preceding siblings ...)
  2018-05-31 13:31 ` [PATCH 3/3] ARM: spectre-v1: fix syscall entry Russell King
@ 2018-05-31 18:04 ` Tony Lindgren
  3 siblings, 0 replies; 10+ messages in thread
From: Tony Lindgren @ 2018-05-31 18:04 UTC (permalink / raw)
  To: linux-arm-kernel

* Russell King - ARM Linux <linux@armlinux.org.uk> [180531 13:34]:
> Hi,
> 
> This series adds initial support for the Spectre variant 1 workarounds
> to the kernel.  This does _not_ cover the user accessors, which are
> still in development.
> 
> The series adds support for the array_index_mask_nospec() macro, used
> by generic kernel code to mask out of bounds pointers, and also adds
> the syscall table hardening.

For the series including v2 patch of 3/3:

Boot-tested-by: Tony Lindgren <tony@atomide.com>
Reviewed-by: Tony Lindgren <tony@atomide.com>

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2018-05-31 18:04 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-05-31 13:30 [PATCH 0/3] Initial Spectre variant 1 patches Russell King - ARM Linux
2018-05-31 13:31 ` [PATCH 1/3] ARM: spectre-v1: add speculation barrier (csdb) macros Russell King
2018-05-31 14:17   ` Mark Rutland
2018-05-31 13:31 ` [PATCH 2/3] ARM: spectre-v1: add array_index_mask_nospec() implementation Russell King
2018-05-31 14:22   ` Mark Rutland
2018-05-31 13:31 ` [PATCH 3/3] ARM: spectre-v1: fix syscall entry Russell King
2018-05-31 15:55   ` Mark Rutland
2018-05-31 16:06     ` [PATCH v2 " Russell King
2018-05-31 16:08       ` Mark Rutland
2018-05-31 18:04 ` [PATCH 0/3] Initial Spectre variant 1 patches Tony Lindgren

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.