Author: jchandra
Date: Fri Apr 12 17:22:12 2013
New Revision: 249415
URL: http://svnweb.freebsd.org/changeset/base/249415

Log:
  Move MIPS_MAX_TLB_ENTRIES definition from cpuregs.h to tlb.c
  
  Having MIPS_MAX_TLB_ENTRIES defined to 128 is misleading, since it used
  to be 64 in older releases of MIPS architecture (where it could be read
  from Config1) and can be much more than 128 for the newer processors.
  
  For now, move the definition to the only file using it (mips/mips/tlb.c)
  and define MIPS_MAX_TLB_ENTRIES depending on the MIPS cpu defined. Also
  add few checks so that we do not write beyond the end of the tlb_state
  array.
  
  This fixes a kernel data corruption seen in Netlogic XLP, which was casued
  by tlb_save() writing beyond the end of tlb_state array when breaking into
  debugger.

Modified:
  head/sys/mips/include/cpuregs.h
  head/sys/mips/mips/tlb.c

Modified: head/sys/mips/include/cpuregs.h
==============================================================================
--- head/sys/mips/include/cpuregs.h     Fri Apr 12 17:15:47 2013        
(r249414)
+++ head/sys/mips/include/cpuregs.h     Fri Apr 12 17:22:12 2013        
(r249415)
@@ -521,7 +521,6 @@
 
 #define MIPS_CONFIG1_TLBSZ_MASK                0x7E000000      /* bits 30..25 
# tlb entries minus one */
 #define MIPS_CONFIG1_TLBSZ_SHIFT       25
-#define        MIPS_MAX_TLB_ENTRIES            128
 
 #define MIPS_CONFIG1_IS_MASK           0x01C00000      /* bits 24..22 icache 
sets per way */
 #define MIPS_CONFIG1_IS_SHIFT          22

Modified: head/sys/mips/mips/tlb.c
==============================================================================
--- head/sys/mips/mips/tlb.c    Fri Apr 12 17:15:47 2013        (r249414)
+++ head/sys/mips/mips/tlb.c    Fri Apr 12 17:22:12 2013        (r249415)
@@ -40,6 +40,14 @@
 #include <machine/pte.h>
 #include <machine/tlb.h>
 
+#if defined(CPU_CNMIPS)
+#define        MIPS_MAX_TLB_ENTRIES    128
+#elif defined(CPU_NLM)
+#define        MIPS_MAX_TLB_ENTRIES    (2048 + 128)
+#else
+#define        MIPS_MAX_TLB_ENTRIES    64
+#endif
+
 struct tlb_state {
        unsigned wired;
        struct tlb_entry {
@@ -264,12 +272,15 @@ tlb_invalidate_range(pmap_t pmap, vm_off
 void
 tlb_save(void)
 {
-       unsigned i, cpu;
+       unsigned ntlb, i, cpu;
 
        cpu = PCPU_GET(cpuid);
-
+       if (num_tlbentries > MIPS_MAX_TLB_ENTRIES)
+               ntlb = MIPS_MAX_TLB_ENTRIES;
+       else
+               ntlb = num_tlbentries;
        tlb_state[cpu].wired = mips_rd_wired();
-       for (i = 0; i < num_tlbentries; i++) {
+       for (i = 0; i < ntlb; i++) {
                mips_wr_index(i);
                tlb_read();
 
@@ -329,7 +340,7 @@ tlb_invalidate_one(unsigned i)
 DB_SHOW_COMMAND(tlb, ddb_dump_tlb)
 {
        register_t ehi, elo0, elo1;
-       unsigned i, cpu;
+       unsigned i, cpu, ntlb;
 
        /*
         * XXX
@@ -344,12 +355,18 @@ DB_SHOW_COMMAND(tlb, ddb_dump_tlb)
                db_printf("Invalid CPU %u\n", cpu);
                return;
        }
+       if (num_tlbentries > MIPS_MAX_TLB_ENTRIES) {
+               ntlb = MIPS_MAX_TLB_ENTRIES;
+               db_printf("Warning: Only %d of %d TLB entries saved!\n",
+                   ntlb, num_tlbentries);
+       } else
+               ntlb = num_tlbentries;
 
        if (cpu == PCPU_GET(cpuid))
                tlb_save();
 
        db_printf("Beginning TLB dump for CPU %u...\n", cpu);
-       for (i = 0; i < num_tlbentries; i++) {
+       for (i = 0; i < ntlb; i++) {
                if (i == tlb_state[cpu].wired) {
                        if (i != 0)
                                db_printf("^^^ WIRED ENTRIES ^^^\n");
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to