]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
powerpc/fsl: Flush the branch predictor at each kernel entry (32 bit)
authorDiana Craciun <diana.craciun@nxp.com>
Mon, 29 Apr 2019 15:49:04 +0000 (18:49 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 16 May 2019 17:44:53 +0000 (19:44 +0200)
commit 7fef436295bf6c05effe682c8797dfcb0deb112a 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/head_booke.h
arch/powerpc/kernel/head_fsl_booke.S

index a620203f7de33fd52b56f4ca12dc227dd24ec139..384bb4d80520c01923202bed52a4a40aec7eeeca 100644 (file)
@@ -42,6 +42,9 @@
        andi.   r11, r11, MSR_PR;       /* check whether user or kernel    */\
        mr      r11, r1;                                                     \
        beq     1f;                                                          \
+START_BTB_FLUSH_SECTION                                        \
+       BTB_FLUSH(r11)                                          \
+END_BTB_FLUSH_SECTION                                  \
        /* if from user, start at top of this thread's kernel stack */       \
        lwz     r11, THREAD_INFO-THREAD(r10);                                \
        ALLOC_STACK_FRAME(r11, THREAD_SIZE);                                 \
        stw     r9,_CCR(r8);            /* save CR on stack                */\
        mfspr   r11,exc_level_srr1;     /* check whether user or kernel    */\
        DO_KVM  BOOKE_INTERRUPT_##intno exc_level_srr1;                      \
+START_BTB_FLUSH_SECTION                                                                \
+       BTB_FLUSH(r10)                                                                  \
+END_BTB_FLUSH_SECTION                                                          \
        andi.   r11,r11,MSR_PR;                                              \
        mfspr   r11,SPRN_SPRG_THREAD;   /* if from user, start at top of   */\
        lwz     r11,THREAD_INFO-THREAD(r11); /* this thread's kernel stack */\
index fffd1f96bb1d0d81319ceb72ddcbf7ad15b82880..275769b6fb0db51261fe850ff38b650abac9eb8c 100644 (file)
@@ -451,6 +451,13 @@ END_FTR_SECTION_IFSET(CPU_FTR_EMB_HV)
        mfcr    r13
        stw     r13, THREAD_NORMSAVE(3)(r10)
        DO_KVM  BOOKE_INTERRUPT_DTLB_MISS SPRN_SRR1
+START_BTB_FLUSH_SECTION
+       mfspr r11, SPRN_SRR1
+       andi. r10,r11,MSR_PR
+       beq 1f
+       BTB_FLUSH(r10)
+1:
+END_BTB_FLUSH_SECTION
        mfspr   r10, SPRN_DEAR          /* Get faulting address */
 
        /* If we are faulting a kernel address, we have to use the
@@ -545,6 +552,14 @@ END_FTR_SECTION_IFSET(CPU_FTR_EMB_HV)
        mfcr    r13
        stw     r13, THREAD_NORMSAVE(3)(r10)
        DO_KVM  BOOKE_INTERRUPT_ITLB_MISS SPRN_SRR1
+START_BTB_FLUSH_SECTION
+       mfspr r11, SPRN_SRR1
+       andi. r10,r11,MSR_PR
+       beq 1f
+       BTB_FLUSH(r10)
+1:
+END_BTB_FLUSH_SECTION
+
        mfspr   r10, SPRN_SRR0          /* Get faulting address */
 
        /* If we are faulting a kernel address, we have to use the