--- /dev/null
+From ed4cbc81addbc076b016c5b979fd1a02f0897f0a Mon Sep 17 00:00:00 2001
+From: Markos Chandras <markos.chandras@imgtec.com>
+Date: Mon, 26 Jan 2015 13:04:33 +0000
+Subject: MIPS: HTW: Prevent accidental HTW start due to nested htw_{start, stop}
+
+From: Markos Chandras <markos.chandras@imgtec.com>
+
+commit ed4cbc81addbc076b016c5b979fd1a02f0897f0a upstream.
+
+activate_mm() and switch_mm() call get_new_mmu_context() which in turn
+can enable the HTW before the entryhi is changed with the new ASID.
+Since the latter will enable the HTW in local_flush_tlb_all(),
+then there is a small timing window where the HTW is running with the
+new ASID but with an old pgd since the TLBMISS_HANDLER_SETUP_PGD
+hasn't assigned a new one yet. In order to prevent that, we introduce a
+simple htw counter to avoid starting HTW accidentally due to nested
+htw_{start,stop}() sequences. Moreover, since various IPI calls can
+enforce TLB flushing operations on a different core, such an operation
+may interrupt another htw_{stop,start} in progress leading inconsistent
+updates of the htw_seq variable. In order to avoid that, we disable the
+interrupts whenever we update that variable.
+
+Signed-off-by: Markos Chandras <markos.chandras@imgtec.com>
+Cc: linux-mips@linux-mips.org
+Patchwork: https://patchwork.linux-mips.org/patch/9118/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/include/asm/cpu-info.h | 5 +++++
+ arch/mips/include/asm/mmu_context.h | 7 ++++++-
+ arch/mips/include/asm/pgtable.h | 24 ++++++++++++++++++------
+ arch/mips/kernel/cpu-probe.c | 4 +++-
+ 4 files changed, 32 insertions(+), 8 deletions(-)
+
+--- a/arch/mips/include/asm/cpu-info.h
++++ b/arch/mips/include/asm/cpu-info.h
+@@ -84,6 +84,11 @@ struct cpuinfo_mips {
+ * (shifted by _CACHE_SHIFT)
+ */
+ unsigned int writecombine;
++ /*
++ * Simple counter to prevent enabling HTW in nested
++ * htw_start/htw_stop calls
++ */
++ unsigned int htw_seq;
+ } __attribute__((aligned(SMP_CACHE_BYTES)));
+
+ extern struct cpuinfo_mips cpu_data[];
+--- a/arch/mips/include/asm/mmu_context.h
++++ b/arch/mips/include/asm/mmu_context.h
+@@ -25,7 +25,6 @@ do { \
+ if (cpu_has_htw) { \
+ write_c0_pwbase(pgd); \
+ back_to_back_c0_hazard(); \
+- htw_reset(); \
+ } \
+ } while (0)
+
+@@ -142,6 +141,7 @@ static inline void switch_mm(struct mm_s
+ unsigned long flags;
+ local_irq_save(flags);
+
++ htw_stop();
+ /* Check if our ASID is of an older version and thus invalid */
+ if ((cpu_context(cpu, next) ^ asid_cache(cpu)) & ASID_VERSION_MASK)
+ get_new_mmu_context(next, cpu);
+@@ -154,6 +154,7 @@ static inline void switch_mm(struct mm_s
+ */
+ cpumask_clear_cpu(cpu, mm_cpumask(prev));
+ cpumask_set_cpu(cpu, mm_cpumask(next));
++ htw_start();
+
+ local_irq_restore(flags);
+ }
+@@ -180,6 +181,7 @@ activate_mm(struct mm_struct *prev, stru
+
+ local_irq_save(flags);
+
++ htw_stop();
+ /* Unconditionally get a new ASID. */
+ get_new_mmu_context(next, cpu);
+
+@@ -189,6 +191,7 @@ activate_mm(struct mm_struct *prev, stru
+ /* mark mmu ownership change */
+ cpumask_clear_cpu(cpu, mm_cpumask(prev));
+ cpumask_set_cpu(cpu, mm_cpumask(next));
++ htw_start();
+
+ local_irq_restore(flags);
+ }
+@@ -203,6 +206,7 @@ drop_mmu_context(struct mm_struct *mm, u
+ unsigned long flags;
+
+ local_irq_save(flags);
++ htw_stop();
+
+ if (cpumask_test_cpu(cpu, mm_cpumask(mm))) {
+ get_new_mmu_context(mm, cpu);
+@@ -211,6 +215,7 @@ drop_mmu_context(struct mm_struct *mm, u
+ /* will get a new context next time */
+ cpu_context(cpu, mm) = 0;
+ }
++ htw_start();
+ local_irq_restore(flags);
+ }
+
+--- a/arch/mips/include/asm/pgtable.h
++++ b/arch/mips/include/asm/pgtable.h
+@@ -99,19 +99,31 @@ extern void paging_init(void);
+
+ #define htw_stop() \
+ do { \
++ unsigned long flags; \
++ \
+ if (cpu_has_htw) { \
+- write_c0_pwctl(read_c0_pwctl() & \
+- ~(1 << MIPS_PWCTL_PWEN_SHIFT)); \
+- back_to_back_c0_hazard(); \
++ local_irq_save(flags); \
++ if(!raw_current_cpu_data.htw_seq++) { \
++ write_c0_pwctl(read_c0_pwctl() & \
++ ~(1 << MIPS_PWCTL_PWEN_SHIFT)); \
++ back_to_back_c0_hazard(); \
++ } \
++ local_irq_restore(flags); \
+ } \
+ } while(0)
+
+ #define htw_start() \
+ do { \
++ unsigned long flags; \
++ \
+ if (cpu_has_htw) { \
+- write_c0_pwctl(read_c0_pwctl() | \
+- (1 << MIPS_PWCTL_PWEN_SHIFT)); \
+- back_to_back_c0_hazard(); \
++ local_irq_save(flags); \
++ if (!--raw_current_cpu_data.htw_seq) { \
++ write_c0_pwctl(read_c0_pwctl() | \
++ (1 << MIPS_PWCTL_PWEN_SHIFT)); \
++ back_to_back_c0_hazard(); \
++ } \
++ local_irq_restore(flags); \
+ } \
+ } while(0)
+
+--- a/arch/mips/kernel/cpu-probe.c
++++ b/arch/mips/kernel/cpu-probe.c
+@@ -367,8 +367,10 @@ static inline unsigned int decode_config
+ if (config3 & MIPS_CONF3_MSA)
+ c->ases |= MIPS_ASE_MSA;
+ /* Only tested on 32-bit cores */
+- if ((config3 & MIPS_CONF3_PW) && config_enabled(CONFIG_32BIT))
++ if ((config3 & MIPS_CONF3_PW) && config_enabled(CONFIG_32BIT)) {
++ c->htw_seq = 0;
+ c->options |= MIPS_CPU_HTW;
++ }
+
+ return config3 & MIPS_CONF_M;
+ }
+++ /dev/null
-From fbba7db3990cb707ff91cd6507d53a0a730afe97 Mon Sep 17 00:00:00 2001
-From: Arnd Bergmann <arnd@arndb.de>
-Date: Wed, 28 Jan 2015 22:51:04 +0100
-Subject: usb: musb: add omap-control dependency
-
-From: Arnd Bergmann <arnd@arndb.de>
-
-commit fbba7db3990cb707ff91cd6507d53a0a730afe97 upstream.
-
-The omap musb front-end calls into the phy driver directly
-instead of using a generic phy interface, which causes a link
-error when the specific driver is not built-in:
-
-drivers/built-in.o: In function `omap2430_musb_disable':
-usb/musb/omap2430.c:480: undefined reference to `omap_control_usb_set_mode'
-drivers/built-in.o: In function `omap2430_musb_enable':
-usb/musb/omap2430.c:466: undefined reference to `omap_control_usb_set_mode'
-usb/musb/omap2430.c:447: undefined reference to `omap_control_usb_set_mode'
-drivers/built-in.o: In function `omap_musb_set_mailbox':
-usb/musb/omap2430.c:273: undefined reference to `omap_control_usb_set_mode'
-usb/musb/omap2430.c:304: undefined reference to `omap_control_usb_set_mode'
-drivers/built-in.o:(.debug_addr+0xbd9e0): more undefined references to `omap_control_usb_set_mode' follow
-
-This adds an explicit dependency.
-
-Signed-off-by: Arnd Bergmann <arnd@arndb.de>
-Fixes: ca784be36cc725 ("usb: start using the control module driver")
-Signed-off-by: Felipe Balbi <balbi@ti.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
----
- drivers/usb/musb/Kconfig | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/usb/musb/Kconfig
-+++ b/drivers/usb/musb/Kconfig
-@@ -76,7 +76,7 @@ config USB_MUSB_TUSB6010
-
- config USB_MUSB_OMAP2PLUS
- tristate "OMAP2430 and onwards"
-- depends on ARCH_OMAP2PLUS && USB
-+ depends on ARCH_OMAP2PLUS && USB && OMAP_CONTROL_PHY
- select GENERIC_PHY
-
- config USB_MUSB_AM35X