Merge branch 'drm-patches' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied...
[sfrench/cifs-2.6.git] / arch / ppc / kernel / misc.S
index 0da55368655c90a0018504d79c0125fd51326e25..a22e1f4d94c82edd1c3ee92d7ea491b82a716b30 100644 (file)
@@ -237,9 +237,19 @@ _GLOBAL(_tlbie)
        mfspr   r4,SPRN_MMUCR
        mfspr   r5,SPRN_PID                     /* Get PID */
        rlwimi  r4,r5,0,24,31                   /* Set TID */
-       mtspr   SPRN_MMUCR,r4
 
+       /* We have to run the search with interrupts disabled, even critical
+        * and debug interrupts (in fact the only critical exceptions we have
+        * are debug and machine check).  Otherwise  an interrupt which causes
+        * a TLB miss can clobber the MMUCR between the mtspr and the tlbsx. */
+       mfmsr   r5
+       lis     r6,(MSR_EE|MSR_CE|MSR_ME|MSR_DE)@ha
+       addi    r6,r6,(MSR_EE|MSR_CE|MSR_ME|MSR_DE)@l
+       andc    r6,r5,r6
+       mtmsr   r6
+       mtspr   SPRN_MMUCR,r4
        tlbsx.  r3, 0, r3
+       mtmsr   r5
        bne     10f
        sync
        /* There are only 64 TLB entries, so r3 < 64,