]> git.baikalelectronics.ru Git - kernel.git/commitdiff
MIPS: Add CPU shared FTLB feature detection
authorPaul Burton <paul.burton@imgtec.com>
Fri, 2 Jun 2017 22:38:01 +0000 (15:38 -0700)
committerRalf Baechle <ralf@linux-mips.org>
Thu, 29 Jun 2017 00:42:29 +0000 (02:42 +0200)
Some systems share FTLB RAMs or entries between sibling CPUs (ie.
hardware threads, or VP(E)s, within a core). These properties require
kernel handling in various places. As a start this patch introduces
cpu_has_shared_ftlb_ram & cpu_has_shared_ftlb_entries feature macros
which we set appropriately for I6400 & I6500 CPUs. Further patches will
make use of these macros as appropriate.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/16202/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
arch/mips/include/asm/cpu-features.h
arch/mips/include/asm/cpu.h
arch/mips/kernel/cpu-probe.c

index 494d38274142697b62c4ff3959c859bd1fc91d64..d6ea8e7c510794084b6e8a7397279f5e7718bc7c 100644 (file)
 # define cpu_has_perf          (cpu_data[0].options & MIPS_CPU_PERF)
 #endif
 
+#if defined(CONFIG_SMP) && defined(__mips_isa_rev) && (__mips_isa_rev >= 6)
+/*
+ * Some systems share FTLB RAMs between threads within a core (siblings in
+ * kernel parlance). This means that FTLB entries may become invalid at almost
+ * any point when an entry is evicted due to a sibling thread writing an entry
+ * to the shared FTLB RAM.
+ *
+ * This is only relevant to SMP systems, and the only systems that exhibit this
+ * property implement MIPSr6 or higher so we constrain support for this to
+ * kernels that will run on such systems.
+ */
+# ifndef cpu_has_shared_ftlb_ram
+#  define cpu_has_shared_ftlb_ram \
+       (current_cpu_data.options & MIPS_CPU_SHARED_FTLB_RAM)
+# endif
+
+/*
+ * Some systems take this a step further & share FTLB entries between siblings.
+ * This is implemented as TLB writes happening as usual, but if an entry
+ * written by a sibling exists in the shared FTLB for a translation which would
+ * otherwise cause a TLB refill exception then the CPU will use the entry
+ * written by its sibling rather than triggering a refill & writing a matching
+ * TLB entry for itself.
+ *
+ * This is naturally only valid if a TLB entry is known to be suitable for use
+ * on all siblings in a CPU, and so it only takes effect when MMIDs are in use
+ * rather than ASIDs or when a TLB entry is marked global.
+ */
+# ifndef cpu_has_shared_ftlb_entries
+#  define cpu_has_shared_ftlb_entries \
+       (current_cpu_data.options & MIPS_CPU_SHARED_FTLB_ENTRIES)
+# endif
+#endif /* SMP && __mips_isa_rev >= 6 */
+
+#ifndef cpu_has_shared_ftlb_ram
+# define cpu_has_shared_ftlb_ram 0
+#endif
+#ifndef cpu_has_shared_ftlb_entries
+# define cpu_has_shared_ftlb_entries 0
+#endif
+
 /*
  * Guest capabilities
  */
index 53b8b1f490846c92b8cad61489af32b64aace38c..ce798594c868ab18de9ea16dd89b24a4ee3a2159 100644 (file)
@@ -418,6 +418,10 @@ enum cpu_type_enum {
 #define MIPS_CPU_GUESTID       MBIT_ULL(51)    /* CPU uses VZ ASE GuestID feature */
 #define MIPS_CPU_DRG           MBIT_ULL(52)    /* CPU has VZ Direct Root to Guest (DRG) */
 #define MIPS_CPU_UFR           MBIT_ULL(53)    /* CPU supports User mode FR switching */
+#define MIPS_CPU_SHARED_FTLB_RAM \
+                               MBIT_ULL(54)    /* CPU shares FTLB RAM with another */
+#define MIPS_CPU_SHARED_FTLB_ENTRIES \
+                               MBIT_ULL(55)    /* CPU shares FTLB entries with another */
 
 /*
  * CPU ASE encodings
index 09462bba629fa51f5c20a00a65eee4397ee935cf..3f0d43ce994ab7ce52cbf5527076d5f5b03d1ccd 100644 (file)
@@ -1653,6 +1653,17 @@ static inline void cpu_probe_mips(struct cpuinfo_mips *c, unsigned int cpu)
        decode_configs(c);
 
        spram_config();
+
+       switch (__get_cpu_type(c->cputype)) {
+       case CPU_I6500:
+               c->options |= MIPS_CPU_SHARED_FTLB_ENTRIES;
+               /* fall-through */
+       case CPU_I6400:
+               c->options |= MIPS_CPU_SHARED_FTLB_RAM;
+               /* fall-through */
+       default:
+               break;
+       }
 }
 
 static inline void cpu_probe_alchemy(struct cpuinfo_mips *c, unsigned int cpu)