MIPS: dump_tlb: Take global bit into account
authorJames Hogan <james.hogan@imgtec.com>
Tue, 19 May 2015 08:50:35 +0000 (09:50 +0100)
committerRalf Baechle <ralf@linux-mips.org>
Sun, 21 Jun 2015 19:52:35 +0000 (21:52 +0200)
The TLB only matches the ASID when the global bit isn't set, so
dump_tlb() shouldn't really be skipping global entries just because the
ASID doesn't match. Fix the condition to read the TLB entry's global bit
from EntryLo0. Note that after a TLB read the global bits in both
EntryLo registers reflect the same global bit in the TLB entry.

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Maciej W. Rozycki <macro@linux-mips.org>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/10079/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
arch/mips/lib/dump_tlb.c
arch/mips/lib/r3k_dump_tlb.c

index f02cc554d72005c5ea30823f9200a3f11d3f4a0c..995c393e3342c9338f0fce5128fda90f204dafd6 100644 (file)
@@ -73,7 +73,15 @@ static void dump_tlb(int first, int last)
                 */
                if ((entryhi & ~0x1ffffUL) == CKSEG0)
                        continue;
-               if ((entryhi & 0xff) != asid)
+               /*
+                * ASID takes effect in absence of G (global) bit.
+                * We check both G bits, even though architecturally they should
+                * match one another, because some revisions of the SB1 core may
+                * leave only a single G bit set after a machine check exception
+                * due to duplicate TLB entry.
+                */
+               if (!((entrylo0 | entrylo1) & MIPS_ENTRYLO_G) &&
+                   (entryhi & 0xff) != asid)
                        continue;
 
                /*
index e210f04b2bc30e8891ed433cc22d83c34f56c8c6..1335e4394e33558392d32f1f579a1c7e1f0b3f8c 100644 (file)
@@ -35,8 +35,9 @@ static void dump_tlb(int first, int last)
                entrylo0 = read_c0_entrylo0();
 
                /* Unused entries have a virtual address of KSEG0.  */
-               if ((entryhi & PAGE_MASK) != KSEG0
-                   && (entryhi & ASID_MASK) == asid) {
+               if ((entryhi & PAGE_MASK) != KSEG0 &&
+                   (entrylo0 & R3K_ENTRYLO_G ||
+                    (entryhi & ASID_MASK) == asid)) {
                        /*
                         * Only print entries in use
                         */