powerpc/fsl: Flush the branch predictor at each kernel entry (32 bit)
authorDiana Craciun <diana.craciun@nxp.com>
Wed, 12 Dec 2018 14:03:06 +0000 (16:03 +0200)
committerMichael Ellerman <mpe@ellerman.id.au>
Thu, 20 Dec 2018 11:59:03 +0000 (22:59 +1100)
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>
arch/powerpc/kernel/head_booke.h
arch/powerpc/kernel/head_fsl_booke.S

index d0862a100d29b147e0242dd9d02195d2007fb501..15ac51072eb3ff80a4f9233717c02b696a3cdb5d 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 e2750b856c8fc5468ca5065adb8be0ce88c5b18c..2386ce2a9c6e4604ecc5a8f245858d3f0c547b6b 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