powerpc/fsl: Flush the branch predictor at each kernel entry (32 bit)
authorDiana Craciun <diana.craciun@nxp.com>
Fri, 29 Mar 2019 11:26:14 +0000 (22:26 +1100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 3 Apr 2019 04:26:20 +0000 (06:26 +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 d0862a1..15ac510 100644 (file)
@@ -43,6 +43,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 e2750b8..2386ce2 100644 (file)
@@ -453,6 +453,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
@@ -547,6 +554,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