[POWERPC] 4xx: Fix 4xx flush_tlb_page()
[pandora-kernel.git] / arch / powerpc / kernel / misc_32.S
index e708ab7..0ed2c7e 100644 (file)
@@ -288,7 +288,16 @@ _GLOBAL(_tlbia)
  */
 _GLOBAL(_tlbie)
 #if defined(CONFIG_40x)
+       /* We run the search with interrupts disabled because we have to change
+        * the PID and I don't want to preempt when that happens.
+        */
+       mfmsr   r5
+       mfspr   r6,SPRN_PID
+       wrteei  0
+       mtspr   SPRN_PID,r4
        tlbsx.  r3, 0, r3
+       mtspr   SPRN_PID,r6
+       wrtee   r5
        bne     10f
        sync
        /* There are only 64 TLB entries, so r3 < 64, which means bit 25 is clear.
@@ -297,13 +306,23 @@ _GLOBAL(_tlbie)
        tlbwe   r3, r3, TLB_TAG
        isync
 10:
-#elif defined(CONFIG_44x)
-       mfspr   r4,SPRN_MMUCR
-       mfspr   r5,SPRN_PID                     /* Get PID */
-       rlwimi  r4,r5,0,24,31                   /* Set TID */
-       mtspr   SPRN_MMUCR,r4
 
+#elif defined(CONFIG_44x)
+       mfspr   r5,SPRN_MMUCR
+       rlwimi  r5,r4,0,24,31                   /* Set TID */
+
+       /* 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   r4
+       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,r4,r6
+       mtmsr   r6
+       mtspr   SPRN_MMUCR,r5
        tlbsx.  r3, 0, r3
+       mtmsr   r4
        bne     10f
        sync
        /* There are only 64 TLB entries, so r3 < 64,