| From foo@baz Fri Mar 29 15:53:50 CET 2019 |
| From: Michael Ellerman <mpe@ellerman.id.au> |
| Date: Fri, 29 Mar 2019 22:26:13 +1100 |
| Subject: powerpc/fsl: Flush the branch predictor at each kernel entry (64bit) |
| To: stable@vger.kernel.org, gregkh@linuxfoundation.org |
| Cc: linuxppc-dev@ozlabs.org, diana.craciun@nxp.com, msuchanek@suse.de, christophe.leroy@c-s.fr |
| Message-ID: <20190329112620.14489-26-mpe@ellerman.id.au> |
| |
| From: Diana Craciun <diana.craciun@nxp.com> |
| |
| commit 10c5e83afd4a3f01712d97d3bb1ae34d5b74a185 upstream. |
| |
| In order to protect against speculation attacks on |
| indirect branches, the branch predictor is flushed at |
| kernel entry to protect for the following situations: |
| - userspace process attacking another userspace process |
| - userspace process attacking the kernel |
| Basically when the privillege level change (i.e. the |
| kernel is entered), the branch predictor state is flushed. |
| |
| Signed-off-by: Diana Craciun <diana.craciun@nxp.com> |
| Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| arch/powerpc/kernel/entry_64.S | 5 +++++ |
| arch/powerpc/kernel/exceptions-64e.S | 26 +++++++++++++++++++++++++- |
| arch/powerpc/mm/tlb_low_64e.S | 7 +++++++ |
| 3 files changed, 37 insertions(+), 1 deletion(-) |
| |
| --- a/arch/powerpc/kernel/entry_64.S |
| +++ b/arch/powerpc/kernel/entry_64.S |
| @@ -78,6 +78,11 @@ END_FTR_SECTION_IFSET(CPU_FTR_TM) |
| std r0,GPR0(r1) |
| std r10,GPR1(r1) |
| beq 2f /* if from kernel mode */ |
| +#ifdef CONFIG_PPC_FSL_BOOK3E |
| +START_BTB_FLUSH_SECTION |
| + BTB_FLUSH(r10) |
| +END_BTB_FLUSH_SECTION |
| +#endif |
| ACCOUNT_CPU_USER_ENTRY(r13, r10, r11) |
| 2: std r2,GPR2(r1) |
| std r3,GPR3(r1) |
| --- a/arch/powerpc/kernel/exceptions-64e.S |
| +++ b/arch/powerpc/kernel/exceptions-64e.S |
| @@ -295,7 +295,8 @@ ret_from_mc_except: |
| andi. r10,r11,MSR_PR; /* save stack pointer */ \ |
| beq 1f; /* branch around if supervisor */ \ |
| ld r1,PACAKSAVE(r13); /* get kernel stack coming from usr */\ |
| -1: cmpdi cr1,r1,0; /* check if SP makes sense */ \ |
| +1: type##_BTB_FLUSH \ |
| + cmpdi cr1,r1,0; /* check if SP makes sense */ \ |
| bge- cr1,exc_##n##_bad_stack;/* bad stack (TODO: out of line) */ \ |
| mfspr r10,SPRN_##type##_SRR0; /* read SRR0 before touching stack */ |
| |
| @@ -327,6 +328,29 @@ ret_from_mc_except: |
| #define SPRN_MC_SRR0 SPRN_MCSRR0 |
| #define SPRN_MC_SRR1 SPRN_MCSRR1 |
| |
| +#ifdef CONFIG_PPC_FSL_BOOK3E |
| +#define GEN_BTB_FLUSH \ |
| + START_BTB_FLUSH_SECTION \ |
| + beq 1f; \ |
| + BTB_FLUSH(r10) \ |
| + 1: \ |
| + END_BTB_FLUSH_SECTION |
| + |
| +#define CRIT_BTB_FLUSH \ |
| + START_BTB_FLUSH_SECTION \ |
| + BTB_FLUSH(r10) \ |
| + END_BTB_FLUSH_SECTION |
| + |
| +#define DBG_BTB_FLUSH CRIT_BTB_FLUSH |
| +#define MC_BTB_FLUSH CRIT_BTB_FLUSH |
| +#define GDBELL_BTB_FLUSH GEN_BTB_FLUSH |
| +#else |
| +#define GEN_BTB_FLUSH |
| +#define CRIT_BTB_FLUSH |
| +#define DBG_BTB_FLUSH |
| +#define GDBELL_BTB_FLUSH |
| +#endif |
| + |
| #define NORMAL_EXCEPTION_PROLOG(n, intnum, addition) \ |
| EXCEPTION_PROLOG(n, intnum, GEN, addition##_GEN(n)) |
| |
| --- a/arch/powerpc/mm/tlb_low_64e.S |
| +++ b/arch/powerpc/mm/tlb_low_64e.S |
| @@ -69,6 +69,13 @@ END_FTR_SECTION_IFSET(CPU_FTR_EMB_HV) |
| std r15,EX_TLB_R15(r12) |
| std r10,EX_TLB_CR(r12) |
| #ifdef CONFIG_PPC_FSL_BOOK3E |
| +START_BTB_FLUSH_SECTION |
| + mfspr r11, SPRN_SRR1 |
| + andi. r10,r11,MSR_PR |
| + beq 1f |
| + BTB_FLUSH(r10) |
| +1: |
| +END_BTB_FLUSH_SECTION |
| std r7,EX_TLB_R7(r12) |
| #endif |
| TLB_MISS_PROLOG_STATS |