--- /dev/null
+From f5b556c94c8490d42fea79d7b4ae0ecbc291e69d Mon Sep 17 00:00:00 2001
+From: Matthias Schiffer <mschiffer@universe-factory.net>
+Date: Thu, 24 Mar 2016 16:02:52 +0100
+Subject: MIPS: ath79: make bootconsole wait for both THRE and TEMT
+
+From: Matthias Schiffer <mschiffer@universe-factory.net>
+
+commit f5b556c94c8490d42fea79d7b4ae0ecbc291e69d upstream.
+
+This makes the ath79 bootconsole behave the same way as the generic 8250
+bootconsole.
+
+Also waiting for TEMT (transmit buffer is empty) instead of just THRE
+(transmit buffer is not full) ensures that all characters have been
+transmitted before the real serial driver starts reconfiguring the serial
+controller (which would sometimes result in garbage being transmitted.)
+This change does not cause a visible performance loss.
+
+In addition, this seems to fix a hang observed in certain configurations on
+many AR7xxx/AR9xxx SoCs during autoconfig of the real serial driver.
+
+A more complete follow-up patch will disable 8250 autoconfig for ath79
+altogether (the serial controller is detected as a 16550A, which is not
+fully compatible with the ath79 serial, and the autoconfig may lead to
+undefined behavior on ath79.)
+
+Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/ath79/early_printk.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/arch/mips/ath79/early_printk.c
++++ b/arch/mips/ath79/early_printk.c
+@@ -31,13 +31,15 @@ static inline void prom_putchar_wait(voi
+ } while (1);
+ }
+
++#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
++
+ static void prom_putchar_ar71xx(unsigned char ch)
+ {
+ void __iomem *base = (void __iomem *)(KSEG1ADDR(AR71XX_UART_BASE));
+
+- prom_putchar_wait(base + UART_LSR * 4, UART_LSR_THRE, UART_LSR_THRE);
++ prom_putchar_wait(base + UART_LSR * 4, BOTH_EMPTY, BOTH_EMPTY);
+ __raw_writel(ch, base + UART_TX * 4);
+- prom_putchar_wait(base + UART_LSR * 4, UART_LSR_THRE, UART_LSR_THRE);
++ prom_putchar_wait(base + UART_LSR * 4, BOTH_EMPTY, BOTH_EMPTY);
+ }
+
+ static void prom_putchar_ar933x(unsigned char ch)
--- /dev/null
+From 81a76d7119f63c359750e4adeff922a31ad1135f Mon Sep 17 00:00:00 2001
+From: James Hogan <james.hogan@imgtec.com>
+Date: Fri, 4 Dec 2015 22:25:02 +0000
+Subject: MIPS: Avoid using unwind_stack() with usermode
+
+From: James Hogan <james.hogan@imgtec.com>
+
+commit 81a76d7119f63c359750e4adeff922a31ad1135f upstream.
+
+When showing backtraces in response to traps, for example crashes and
+address errors (usually unaligned accesses) when they are set in debugfs
+to be reported, unwind_stack will be used if the PC was in the kernel
+text address range. However since EVA it is possible for user and kernel
+address ranges to overlap, and even without EVA userland can still
+trigger an address error by jumping to a KSeg0 address.
+
+Adjust the check to also ensure that it was running in kernel mode. I
+don't believe any harm can come of this problem, since unwind_stack() is
+sufficiently defensive, however it is only meant for unwinding kernel
+code, so to be correct it should use the raw backtracing instead.
+
+Signed-off-by: James Hogan <james.hogan@imgtec.com>
+Reviewed-by: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com>
+Cc: linux-mips@linux-mips.org
+Patchwork: https://patchwork.linux-mips.org/patch/11701/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+(cherry picked from commit d2941a975ac745c607dfb590e92bb30bc352dad9)
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/kernel/traps.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/mips/kernel/traps.c
++++ b/arch/mips/kernel/traps.c
+@@ -144,7 +144,7 @@ static void show_backtrace(struct task_s
+ if (!task)
+ task = current;
+
+- if (raw_show_trace || !__kernel_text_address(pc)) {
++ if (raw_show_trace || user_mode(regs) || !__kernel_text_address(pc)) {
+ show_raw_backtrace(sp);
+ return;
+ }
--- /dev/null
+From bb93078e655be1e24d68f28f2756676e62c037ce Mon Sep 17 00:00:00 2001
+From: James Hogan <james.hogan@imgtec.com>
+Date: Tue, 24 May 2016 09:35:11 +0100
+Subject: MIPS: Build microMIPS VDSO for microMIPS kernels
+
+From: James Hogan <james.hogan@imgtec.com>
+
+commit bb93078e655be1e24d68f28f2756676e62c037ce upstream.
+
+MicroMIPS kernels may be expected to run on microMIPS only cores which
+don't support the normal MIPS instruction set, so be sure to pass the
+-mmicromips flag through to the VDSO cflags.
+
+Fixes: ebb5e78cc634 ("MIPS: Initial implementation of a VDSO")
+Signed-off-by: James Hogan <james.hogan@imgtec.com>
+Cc: Paul Burton <paul.burton@imgtec.com>
+Cc: linux-mips@linux-mips.org
+Patchwork: https://patchwork.linux-mips.org/patch/13349/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/vdso/Makefile | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/arch/mips/vdso/Makefile
++++ b/arch/mips/vdso/Makefile
+@@ -5,6 +5,7 @@ obj-vdso-y := elf.o gettimeofday.o sigre
+ ccflags-vdso := \
+ $(filter -I%,$(KBUILD_CFLAGS)) \
+ $(filter -E%,$(KBUILD_CFLAGS)) \
++ $(filter -mmicromips,$(KBUILD_CFLAGS)) \
+ $(filter -march=%,$(KBUILD_CFLAGS))
+ cflags-vdso := $(ccflags-vdso) \
+ $(filter -W%,$(filter-out -Wa$(comma)%,$(KBUILD_CFLAGS))) \
--- /dev/null
+From bd239f1e1429e7781096bf3884bdb1b2b1bb4f28 Mon Sep 17 00:00:00 2001
+From: Paul Burton <paul.burton@imgtec.com>
+Date: Thu, 21 Apr 2016 12:43:57 +0100
+Subject: MIPS: Disable preemption during prctl(PR_SET_FP_MODE, ...)
+
+From: Paul Burton <paul.burton@imgtec.com>
+
+commit bd239f1e1429e7781096bf3884bdb1b2b1bb4f28 upstream.
+
+Whilst a PR_SET_FP_MODE prctl is performed there are decisions made
+based upon whether the task is executing on the current CPU. This may
+change if we're preempted, so disable preemption to avoid such changes
+for the lifetime of the mode switch.
+
+Signed-off-by: Paul Burton <paul.burton@imgtec.com>
+Fixes: 9791554b45a2 ("MIPS,prctl: add PR_[GS]ET_FP_MODE prctl options for MIPS")
+Reviewed-by: Maciej W. Rozycki <macro@imgtec.com>
+Tested-by: Aurelien Jarno <aurelien@aurel32.net>
+Cc: Adam Buchbinder <adam.buchbinder@gmail.com>
+Cc: James Hogan <james.hogan@imgtec.com>
+Cc: linux-mips@linux-mips.org
+Cc: linux-kernel@vger.kernel.org
+Patchwork: https://patchwork.linux-mips.org/patch/13144/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/kernel/process.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/arch/mips/kernel/process.c
++++ b/arch/mips/kernel/process.c
+@@ -603,6 +603,9 @@ int mips_set_process_fp_mode(struct task
+ if (!(value & PR_FP_MODE_FR) && cpu_has_fpu && cpu_has_mips_r6)
+ return -EOPNOTSUPP;
+
++ /* Proceed with the mode switch */
++ preempt_disable();
++
+ /* Save FP & vector context, then disable FPU & MSA */
+ if (task->signal == current->signal)
+ lose_fpu(1);
+@@ -661,6 +664,7 @@ int mips_set_process_fp_mode(struct task
+
+ /* Allow threads to use FP again */
+ atomic_set(&task->mm->context.fp_mode_switching, 0);
++ preempt_enable();
+
+ return 0;
+ }
--- /dev/null
+From a816b306c62195b7c43c92cb13330821a96bdc27 Mon Sep 17 00:00:00 2001
+From: James Hogan <james.hogan@imgtec.com>
+Date: Fri, 4 Dec 2015 22:25:01 +0000
+Subject: MIPS: Don't unwind to user mode with EVA
+
+From: James Hogan <james.hogan@imgtec.com>
+
+commit a816b306c62195b7c43c92cb13330821a96bdc27 upstream.
+
+When unwinding through IRQs and exceptions, the unwinding only continues
+if the PC is a kernel text address, however since EVA it is possible for
+user and kernel address ranges to overlap, potentially allowing
+unwinding to continue to user mode if the user PC happens to be in the
+kernel text address range.
+
+Adjust the check to also ensure that the register state from before the
+exception is actually running in kernel mode, i.e. !user_mode(regs).
+
+I don't believe any harm can come of this problem, since the PC is only
+output, the stack pointer is checked to ensure it resides within the
+task's stack page before it is dereferenced in search of the return
+address, and the return address register is similarly only output (if
+the PC is in a leaf function or the beginning of a non-leaf function).
+
+However unwind_stack() is only meant for unwinding kernel code, so to be
+correct the unwind should stop there.
+
+Signed-off-by: James Hogan <james.hogan@imgtec.com>
+Reviewed-by: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com>
+Cc: linux-mips@linux-mips.org
+Patchwork: https://patchwork.linux-mips.org/patch/11700/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/kernel/process.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/mips/kernel/process.c
++++ b/arch/mips/kernel/process.c
+@@ -457,7 +457,7 @@ unsigned long notrace unwind_stack_by_ad
+ *sp + sizeof(*regs) <= stack_page + THREAD_SIZE - 32) {
+ regs = (struct pt_regs *)*sp;
+ pc = regs->cp0_epc;
+- if (__kernel_text_address(pc)) {
++ if (!user_mode(regs) && __kernel_text_address(pc)) {
+ *sp = regs->regs[29];
+ *ra = regs->regs[31];
+ return pc;
--- /dev/null
+From ea1688573426adc2587ed52d086b51c7c62eaca3 Mon Sep 17 00:00:00 2001
+From: James Hogan <james.hogan@imgtec.com>
+Date: Fri, 15 Apr 2016 10:07:24 +0100
+Subject: MIPS: Fix MSA ld_*/st_* asm macros to use PTR_ADDU
+
+From: James Hogan <james.hogan@imgtec.com>
+
+commit ea1688573426adc2587ed52d086b51c7c62eaca3 upstream.
+
+The MSA ld_*/st_* assembler macros for when the toolchain doesn't
+support MSA use addu to offset the base address. However it is a virtual
+memory pointer so fix it to use PTR_ADDU which expands to daddu for
+64-bit kernels.
+
+Signed-off-by: James Hogan <james.hogan@imgtec.com>
+Cc: Paul Burton <paul.burton@imgtec.com>
+Cc: linux-mips@linux-mips.org
+Patchwork: https://patchwork.linux-mips.org/patch/13062/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/include/asm/asmmacro.h | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+--- a/arch/mips/include/asm/asmmacro.h
++++ b/arch/mips/include/asm/asmmacro.h
+@@ -393,7 +393,7 @@
+ .set push
+ .set noat
+ SET_HARDFLOAT
+- addu $1, \base, \off
++ PTR_ADDU $1, \base, \off
+ .word LDB_MSA_INSN | (\wd << 6)
+ .set pop
+ .endm
+@@ -402,7 +402,7 @@
+ .set push
+ .set noat
+ SET_HARDFLOAT
+- addu $1, \base, \off
++ PTR_ADDU $1, \base, \off
+ .word LDH_MSA_INSN | (\wd << 6)
+ .set pop
+ .endm
+@@ -411,7 +411,7 @@
+ .set push
+ .set noat
+ SET_HARDFLOAT
+- addu $1, \base, \off
++ PTR_ADDU $1, \base, \off
+ .word LDW_MSA_INSN | (\wd << 6)
+ .set pop
+ .endm
+@@ -420,7 +420,7 @@
+ .set push
+ .set noat
+ SET_HARDFLOAT
+- addu $1, \base, \off
++ PTR_ADDU $1, \base, \off
+ .word LDD_MSA_INSN | (\wd << 6)
+ .set pop
+ .endm
+@@ -429,7 +429,7 @@
+ .set push
+ .set noat
+ SET_HARDFLOAT
+- addu $1, \base, \off
++ PTR_ADDU $1, \base, \off
+ .word STB_MSA_INSN | (\wd << 6)
+ .set pop
+ .endm
+@@ -438,7 +438,7 @@
+ .set push
+ .set noat
+ SET_HARDFLOAT
+- addu $1, \base, \off
++ PTR_ADDU $1, \base, \off
+ .word STH_MSA_INSN | (\wd << 6)
+ .set pop
+ .endm
+@@ -447,7 +447,7 @@
+ .set push
+ .set noat
+ SET_HARDFLOAT
+- addu $1, \base, \off
++ PTR_ADDU $1, \base, \off
+ .word STW_MSA_INSN | (\wd << 6)
+ .set pop
+ .endm
+@@ -456,7 +456,7 @@
+ .set push
+ .set noat
+ SET_HARDFLOAT
+- addu $1, \base, \off
++ PTR_ADDU $1, \base, \off
+ .word STD_MSA_INSN | (\wd << 6)
+ .set pop
+ .endm
--- /dev/null
+From 5daebc477da4dfeb31ae193d83084def58fd2697 Mon Sep 17 00:00:00 2001
+From: James Hogan <james.hogan@imgtec.com>
+Date: Mon, 8 Feb 2016 18:43:49 +0000
+Subject: MIPS: Fix siginfo.h to use strict posix types
+
+From: James Hogan <james.hogan@imgtec.com>
+
+commit 5daebc477da4dfeb31ae193d83084def58fd2697 upstream.
+
+Commit 85efde6f4e0d ("make exported headers use strict posix types")
+changed the asm-generic siginfo.h to use the __kernel_* types, and
+commit 3a471cbc081b ("remove __KERNEL_STRICT_NAMES") make the internal
+types accessible only to the kernel, but the MIPS implementation hasn't
+been updated to match.
+
+Switch to proper types now so that the exported asm/siginfo.h won't
+produce quite so many compiler errors when included alone by a user
+program.
+
+Signed-off-by: James Hogan <james.hogan@imgtec.com>
+Cc: Christopher Ferris <cferris@google.com>
+Cc: linux-mips@linux-mips.org
+Cc: linux-kernel@vger.kernel.org
+Patchwork: https://patchwork.linux-mips.org/patch/12477/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/include/uapi/asm/siginfo.h | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+--- a/arch/mips/include/uapi/asm/siginfo.h
++++ b/arch/mips/include/uapi/asm/siginfo.h
+@@ -42,13 +42,13 @@ typedef struct siginfo {
+
+ /* kill() */
+ struct {
+- pid_t _pid; /* sender's pid */
++ __kernel_pid_t _pid; /* sender's pid */
+ __ARCH_SI_UID_T _uid; /* sender's uid */
+ } _kill;
+
+ /* POSIX.1b timers */
+ struct {
+- timer_t _tid; /* timer id */
++ __kernel_timer_t _tid; /* timer id */
+ int _overrun; /* overrun count */
+ char _pad[sizeof( __ARCH_SI_UID_T) - sizeof(int)];
+ sigval_t _sigval; /* same as below */
+@@ -57,26 +57,26 @@ typedef struct siginfo {
+
+ /* POSIX.1b signals */
+ struct {
+- pid_t _pid; /* sender's pid */
++ __kernel_pid_t _pid; /* sender's pid */
+ __ARCH_SI_UID_T _uid; /* sender's uid */
+ sigval_t _sigval;
+ } _rt;
+
+ /* SIGCHLD */
+ struct {
+- pid_t _pid; /* which child */
++ __kernel_pid_t _pid; /* which child */
+ __ARCH_SI_UID_T _uid; /* sender's uid */
+ int _status; /* exit code */
+- clock_t _utime;
+- clock_t _stime;
++ __kernel_clock_t _utime;
++ __kernel_clock_t _stime;
+ } _sigchld;
+
+ /* IRIX SIGCHLD */
+ struct {
+- pid_t _pid; /* which child */
+- clock_t _utime;
++ __kernel_pid_t _pid; /* which child */
++ __kernel_clock_t _utime;
+ int _status; /* exit code */
+- clock_t _stime;
++ __kernel_clock_t _stime;
+ } _irix_sigchld;
+
+ /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
--- /dev/null
+From 13eb192d10bcc9ac518d57356179071d603bcb4e Mon Sep 17 00:00:00 2001
+From: James Hogan <james.hogan@imgtec.com>
+Date: Tue, 24 May 2016 09:35:10 +0100
+Subject: MIPS: Fix sigreturn via VDSO on microMIPS kernel
+
+From: James Hogan <james.hogan@imgtec.com>
+
+commit 13eb192d10bcc9ac518d57356179071d603bcb4e upstream.
+
+In microMIPS kernels, handle_signal() sets the isa16 mode bit in the
+vdso address so that the sigreturn trampolines (which are offset from
+the VDSO) get executed as microMIPS.
+
+However commit ebb5e78cc634 ("MIPS: Initial implementation of a VDSO")
+changed the offsets to come from the VDSO image, which already have the
+isa16 mode bit set correctly since they're extracted from the VDSO
+shared library symbol table.
+
+Drop the isa16 mode bit handling from handle_signal() to fix sigreturn
+for cores which support both microMIPS and normal MIPS. This doesn't fix
+microMIPS only cores, since the VDSO is still built for normal MIPS, but
+thats a separate problem.
+
+Fixes: ebb5e78cc634 ("MIPS: Initial implementation of a VDSO")
+Signed-off-by: James Hogan <james.hogan@imgtec.com>
+Cc: Paul Burton <paul.burton@imgtec.com>
+Cc: linux-mips@linux-mips.org
+Patchwork: https://patchwork.linux-mips.org/patch/13348/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/kernel/signal.c | 8 --------
+ 1 file changed, 8 deletions(-)
+
+--- a/arch/mips/kernel/signal.c
++++ b/arch/mips/kernel/signal.c
+@@ -770,15 +770,7 @@ static void handle_signal(struct ksignal
+ sigset_t *oldset = sigmask_to_save();
+ int ret;
+ struct mips_abi *abi = current->thread.abi;
+-#ifdef CONFIG_CPU_MICROMIPS
+- void *vdso;
+- unsigned long tmp = (unsigned long)current->mm->context.vdso;
+-
+- set_isa16_mode(tmp);
+- vdso = (void *)tmp;
+-#else
+ void *vdso = current->mm->context.vdso;
+-#endif
+
+ if (regs->regs[0]) {
+ switch(regs->regs[2]) {
--- /dev/null
+From 987e5b834467c9251ca584febda65ef8f66351a9 Mon Sep 17 00:00:00 2001
+From: James Hogan <james.hogan@imgtec.com>
+Date: Mon, 8 Feb 2016 18:43:51 +0000
+Subject: MIPS: Fix uapi include in exported asm/siginfo.h
+
+From: James Hogan <james.hogan@imgtec.com>
+
+commit 987e5b834467c9251ca584febda65ef8f66351a9 upstream.
+
+Since commit 8cb48fe169dd ("MIPS: Provide correct siginfo_t.si_stime"),
+MIPS' uapi/asm/siginfo.h has included uapi/asm-generic/siginfo.h
+directly before defining MIPS' struct siginfo, in order to get the
+necessary definitions needed for the siginfo struct without the generic
+copy_siginfo() hitting compiler errors due to struct siginfo not yet
+being defined.
+
+Now that the generic copy_siginfo() is moved out to linux/signal.h we
+can safely include asm-generic/siginfo.h before defining the MIPS
+specific struct siginfo, which avoids the uapi/ include as well as
+breakage due to generic copy_siginfo() being defined before struct
+siginfo.
+
+Reported-by: Christopher Ferris <cferris@google.com>
+Fixes: 8cb48fe169dd ("MIPS: Provide correct siginfo_t.si_stime")
+Signed-off-by: James Hogan <james.hogan@imgtec.com>
+Cc: Petr Malat <oss@malat.biz>
+Cc: linux-mips@linux-mips.org
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/include/uapi/asm/siginfo.h | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+--- a/arch/mips/include/uapi/asm/siginfo.h
++++ b/arch/mips/include/uapi/asm/siginfo.h
+@@ -28,7 +28,7 @@
+
+ #define __ARCH_SIGSYS
+
+-#include <uapi/asm-generic/siginfo.h>
++#include <asm-generic/siginfo.h>
+
+ /* We can't use generic siginfo_t, because our si_code and si_errno are swapped */
+ typedef struct siginfo {
+@@ -118,6 +118,4 @@ typedef struct siginfo {
+ #define SI_TIMER __SI_CODE(__SI_TIMER, -3) /* sent by timer expiration */
+ #define SI_MESGQ __SI_CODE(__SI_MESGQ, -4) /* sent by real time mesq state change */
+
+-#include <asm-generic/siginfo.h>
+-
+ #endif /* _UAPI_ASM_SIGINFO_H */
--- /dev/null
+From a7e89326b415b5d81c4b1016fd4a40db861eb58d Mon Sep 17 00:00:00 2001
+From: James Hogan <james.hogan@imgtec.com>
+Date: Tue, 1 Mar 2016 22:19:36 +0000
+Subject: MIPS: Fix watchpoint restoration
+
+From: James Hogan <james.hogan@imgtec.com>
+
+commit a7e89326b415b5d81c4b1016fd4a40db861eb58d upstream.
+
+Commit f51246efee2b ("MIPS: Get rid of finish_arch_switch().") moved the
+__restore_watch() call from finish_arch_switch() (i.e. after resume()
+returns) to before the resume() call in switch_to(). This results in
+watchpoints only being restored when a task is descheduled, preventing
+the watchpoints from being effective most of the time, except due to
+chance before the watchpoints are lazily removed.
+
+Fix the call sequence from switch_to() through to
+mips_install_watch_registers() to pass the task_struct pointer of the
+next task, instead of using current. This allows the watchpoints for the
+next (non-current) task to be restored without reintroducing
+finish_arch_switch().
+
+Fixes: f51246efee2b ("MIPS: Get rid of finish_arch_switch().")
+Signed-off-by: James Hogan <james.hogan@imgtec.com>
+Cc: Paul Burton <paul.burton@imgtec.com>
+Cc: linux-mips@linux-mips.org
+Patchwork: https://patchwork.linux-mips.org/patch/12726/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/include/asm/switch_to.h | 2 +-
+ arch/mips/include/asm/watch.h | 10 +++++-----
+ arch/mips/kernel/pm.c | 2 +-
+ arch/mips/kernel/watch.c | 5 ++---
+ 4 files changed, 9 insertions(+), 10 deletions(-)
+
+--- a/arch/mips/include/asm/switch_to.h
++++ b/arch/mips/include/asm/switch_to.h
+@@ -105,7 +105,7 @@ do { \
+ __clear_software_ll_bit(); \
+ if (cpu_has_userlocal) \
+ write_c0_userlocal(task_thread_info(next)->tp_value); \
+- __restore_watch(); \
++ __restore_watch(next); \
+ (last) = resume(prev, next, task_thread_info(next)); \
+ } while (0)
+
+--- a/arch/mips/include/asm/watch.h
++++ b/arch/mips/include/asm/watch.h
+@@ -12,21 +12,21 @@
+
+ #include <asm/mipsregs.h>
+
+-void mips_install_watch_registers(void);
++void mips_install_watch_registers(struct task_struct *t);
+ void mips_read_watch_registers(void);
+ void mips_clear_watch_registers(void);
+ void mips_probe_watch_registers(struct cpuinfo_mips *c);
+
+ #ifdef CONFIG_HARDWARE_WATCHPOINTS
+-#define __restore_watch() do { \
++#define __restore_watch(task) do { \
+ if (unlikely(test_bit(TIF_LOAD_WATCH, \
+- ¤t_thread_info()->flags))) { \
+- mips_install_watch_registers(); \
++ &task_thread_info(task)->flags))) { \
++ mips_install_watch_registers(task); \
+ } \
+ } while (0)
+
+ #else
+-#define __restore_watch() do {} while (0)
++#define __restore_watch(task) do {} while (0)
+ #endif
+
+ #endif /* _ASM_WATCH_H */
+--- a/arch/mips/kernel/pm.c
++++ b/arch/mips/kernel/pm.c
+@@ -56,7 +56,7 @@ static void mips_cpu_restore(void)
+ write_c0_userlocal(current_thread_info()->tp_value);
+
+ /* Restore watch registers */
+- __restore_watch();
++ __restore_watch(current);
+ }
+
+ /**
+--- a/arch/mips/kernel/watch.c
++++ b/arch/mips/kernel/watch.c
+@@ -15,10 +15,9 @@
+ * Install the watch registers for the current thread. A maximum of
+ * four registers are installed although the machine may have more.
+ */
+-void mips_install_watch_registers(void)
++void mips_install_watch_registers(struct task_struct *t)
+ {
+- struct mips3264_watch_reg_state *watches =
+- ¤t->thread.watch.mips3264;
++ struct mips3264_watch_reg_state *watches = &t->thread.watch.mips3264;
+ switch (current_cpu_data.watch_reg_use_cnt) {
+ default:
+ BUG();
--- /dev/null
+From f4281bba818105c7c91799abe40bc05c0dbdaa25 Mon Sep 17 00:00:00 2001
+From: Paul Burton <paul.burton@imgtec.com>
+Date: Tue, 1 Mar 2016 02:37:58 +0000
+Subject: MIPS: Handle highmem pages in __update_cache
+
+From: Paul Burton <paul.burton@imgtec.com>
+
+commit f4281bba818105c7c91799abe40bc05c0dbdaa25 upstream.
+
+The following patch will expose __update_cache to highmem pages. Handle
+them by mapping them in for the duration of the cache maintenance, just
+like in __flush_dcache_page. The code for that isn't shared because we
+need the page address in __update_cache so sharing became messy. Given
+that the entirity is an extra 5 lines, just duplicate it.
+
+Signed-off-by: Paul Burton <paul.burton@imgtec.com>
+Cc: Lars Persson <lars.persson@axis.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Jerome Marchand <jmarchan@redhat.com>
+Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
+Cc: linux-mips@linux-mips.org
+Cc: linux-kernel@vger.kernel.org
+Patchwork: https://patchwork.linux-mips.org/patch/12721/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/mm/cache.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+--- a/arch/mips/mm/cache.c
++++ b/arch/mips/mm/cache.c
+@@ -143,9 +143,17 @@ void __update_cache(struct vm_area_struc
+ return;
+ page = pfn_to_page(pfn);
+ if (page_mapping(page) && Page_dcache_dirty(page)) {
+- addr = (unsigned long) page_address(page);
++ if (PageHighMem(page))
++ addr = (unsigned long)kmap_atomic(page);
++ else
++ addr = (unsigned long)page_address(page);
++
+ if (exec || pages_do_alias(addr, address & PAGE_MASK))
+ flush_data_cache_page(addr);
++
++ if (PageHighMem(page))
++ __kunmap_atomic((void *)addr);
++
+ ClearPageDcacheDirty(page);
+ }
+ }
--- /dev/null
+From aedcfbe06558a9f53002e82d5be64c6c94687726 Mon Sep 17 00:00:00 2001
+From: Harvey Hunt <harvey.hunt@imgtec.com>
+Date: Wed, 25 May 2016 11:06:35 +0100
+Subject: MIPS: lib: Mark intrinsics notrace
+
+From: Harvey Hunt <harvey.hunt@imgtec.com>
+
+commit aedcfbe06558a9f53002e82d5be64c6c94687726 upstream.
+
+On certain MIPS32 devices, the ftrace tracer "function_graph" uses
+__lshrdi3() during the capturing of trace data. ftrace then attempts to
+trace __lshrdi3() which leads to infinite recursion and a stack overflow.
+Fix this by marking __lshrdi3() as notrace. Mark the other compiler
+intrinsics as notrace in case the compiler decides to use them in the
+ftrace path.
+
+Signed-off-by: Harvey Hunt <harvey.hunt@imgtec.com>
+Cc: <linux-mips@linux-mips.org>
+Cc: <linux-kernel@vger.kernel.org>
+Patchwork: https://patchwork.linux-mips.org/patch/13354/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/lib/ashldi3.c | 2 +-
+ arch/mips/lib/ashrdi3.c | 2 +-
+ arch/mips/lib/bswapdi.c | 2 +-
+ arch/mips/lib/bswapsi.c | 2 +-
+ arch/mips/lib/cmpdi2.c | 2 +-
+ arch/mips/lib/lshrdi3.c | 2 +-
+ arch/mips/lib/ucmpdi2.c | 2 +-
+ 7 files changed, 7 insertions(+), 7 deletions(-)
+
+--- a/arch/mips/lib/ashldi3.c
++++ b/arch/mips/lib/ashldi3.c
+@@ -2,7 +2,7 @@
+
+ #include "libgcc.h"
+
+-long long __ashldi3(long long u, word_type b)
++long long notrace __ashldi3(long long u, word_type b)
+ {
+ DWunion uu, w;
+ word_type bm;
+--- a/arch/mips/lib/ashrdi3.c
++++ b/arch/mips/lib/ashrdi3.c
+@@ -2,7 +2,7 @@
+
+ #include "libgcc.h"
+
+-long long __ashrdi3(long long u, word_type b)
++long long notrace __ashrdi3(long long u, word_type b)
+ {
+ DWunion uu, w;
+ word_type bm;
+--- a/arch/mips/lib/bswapdi.c
++++ b/arch/mips/lib/bswapdi.c
+@@ -1,6 +1,6 @@
+ #include <linux/module.h>
+
+-unsigned long long __bswapdi2(unsigned long long u)
++unsigned long long notrace __bswapdi2(unsigned long long u)
+ {
+ return (((u) & 0xff00000000000000ull) >> 56) |
+ (((u) & 0x00ff000000000000ull) >> 40) |
+--- a/arch/mips/lib/bswapsi.c
++++ b/arch/mips/lib/bswapsi.c
+@@ -1,6 +1,6 @@
+ #include <linux/module.h>
+
+-unsigned int __bswapsi2(unsigned int u)
++unsigned int notrace __bswapsi2(unsigned int u)
+ {
+ return (((u) & 0xff000000) >> 24) |
+ (((u) & 0x00ff0000) >> 8) |
+--- a/arch/mips/lib/cmpdi2.c
++++ b/arch/mips/lib/cmpdi2.c
+@@ -2,7 +2,7 @@
+
+ #include "libgcc.h"
+
+-word_type __cmpdi2(long long a, long long b)
++word_type notrace __cmpdi2(long long a, long long b)
+ {
+ const DWunion au = {
+ .ll = a
+--- a/arch/mips/lib/lshrdi3.c
++++ b/arch/mips/lib/lshrdi3.c
+@@ -2,7 +2,7 @@
+
+ #include "libgcc.h"
+
+-long long __lshrdi3(long long u, word_type b)
++long long notrace __lshrdi3(long long u, word_type b)
+ {
+ DWunion uu, w;
+ word_type bm;
+--- a/arch/mips/lib/ucmpdi2.c
++++ b/arch/mips/lib/ucmpdi2.c
+@@ -2,7 +2,7 @@
+
+ #include "libgcc.h"
+
+-word_type __ucmpdi2(unsigned long long a, unsigned long long b)
++word_type notrace __ucmpdi2(unsigned long long a, unsigned long long b)
+ {
+ const DWunion au = {.ll = a};
+ const DWunion bu = {.ll = b};
--- /dev/null
+From 3484de7bcbed20ecbf2b8d80671619e7059e2dd7 Mon Sep 17 00:00:00 2001
+From: Huacai Chen <chenhc@lemote.com>
+Date: Thu, 17 Mar 2016 20:41:05 +0800
+Subject: MIPS: Loongson-3: Reserve 32MB for RS780E integrated GPU
+
+From: Huacai Chen <chenhc@lemote.com>
+
+commit 3484de7bcbed20ecbf2b8d80671619e7059e2dd7 upstream.
+
+Due to datasheet, reserving 0xff800000~0xffffffff (8MB below 4GB) is
+not enough for RS780E integrated GPU's TOM (top of memory) registers
+and MSI/MSI-x memory region, so we reserve 0xfe000000~0xffffffff (32MB
+below 4GB).
+
+Signed-off-by: Huacai Chen <chenhc@lemote.com>
+Cc: Aurelien Jarno <aurelien@aurel32.net>
+Cc: Steven J . Hill <sjhill@realitydiluted.com>
+Cc: Fuxin Zhang <zhangfx@lemote.com>
+Cc: Zhangjin Wu <wuzhangjin@gmail.com>
+Cc: linux-mips@linux-mips.org
+Patchwork: https://patchwork.linux-mips.org/patch/12889/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/loongson64/loongson-3/numa.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/arch/mips/loongson64/loongson-3/numa.c
++++ b/arch/mips/loongson64/loongson-3/numa.c
+@@ -213,10 +213,10 @@ static void __init node_mem_init(unsigne
+ BOOTMEM_DEFAULT);
+
+ if (node == 0 && node_end_pfn(0) >= (0xffffffff >> PAGE_SHIFT)) {
+- /* Reserve 0xff800000~0xffffffff for RS780E integrated GPU */
++ /* Reserve 0xfe000000~0xffffffff for RS780E integrated GPU */
+ reserve_bootmem_node(NODE_DATA(node),
+- (node_addrspace_offset | 0xff800000),
+- 8 << 20, BOOTMEM_DEFAULT);
++ (node_addrspace_offset | 0xfe000000),
++ 32 << 20, BOOTMEM_DEFAULT);
+ }
+
+ sparse_memory_present_with_active_regions(node);
--- /dev/null
+From 6533af4d4831c421cd9aa4dce7cfc19a3514cc09 Mon Sep 17 00:00:00 2001
+From: Paul Burton <paul.burton@imgtec.com>
+Date: Thu, 21 Apr 2016 18:04:53 +0100
+Subject: MIPS: Prevent "restoration" of MSA context in non-MSA kernels
+
+From: Paul Burton <paul.burton@imgtec.com>
+
+commit 6533af4d4831c421cd9aa4dce7cfc19a3514cc09 upstream.
+
+If a kernel doesn't support MSA context (ie. CONFIG_CPU_HAS_MSA=n) then
+it will only keep 64 bits per FP register in thread context, and the
+calls to set_fpr64 in restore_msa_extcontext will overrun the end of the
+FP register context into the FCSR & MSACSR values. GCC 6.x has become
+smart enough to detect this & complain like so:
+
+ arch/mips/kernel/signal.c: In function 'protected_restore_fp_context':
+ ./arch/mips/include/asm/processor.h:114:17: error: array subscript is above array bounds [-Werror=array-bounds]
+ fpr->val##width[FPR_IDX(width, idx)] = val; \
+ ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~
+ ./arch/mips/include/asm/processor.h:118:1: note: in expansion of macro 'BUILD_FPR_ACCESS'
+ BUILD_FPR_ACCESS(64)
+
+The only way to trigger this code to run would be for a program to set
+up an artificial extended MSA context structure following a sigframe &
+execute sigreturn. Whilst this doesn't allow a program to write to any
+state that it couldn't already, it makes little sense to allow this
+"restoration" of MSA context in a system that doesn't support MSA.
+
+Fix this by killing a program with SIGSYS if it tries something as crazy
+as "restoring" fake MSA context in this way, also fixing the build error
+& allowing for most of restore_msa_extcontext to be optimised out of
+kernels without support for MSA.
+
+Signed-off-by: Paul Burton <paul.burton@imgtec.com>
+Reported-by: Michal Toman <michal.toman@imgtec.com>
+Fixes: bf82cb30c7e5 ("MIPS: Save MSA extended context around signals")
+Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi>
+Cc: James Hogan <james.hogan@imgtec.com>
+Cc: Michal Toman <michal.toman@imgtec.com>
+Cc: linux-mips@linux-mips.org
+Patchwork: https://patchwork.linux-mips.org/patch/13164/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/kernel/signal.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+--- a/arch/mips/kernel/signal.c
++++ b/arch/mips/kernel/signal.c
+@@ -195,6 +195,9 @@ static int restore_msa_extcontext(void _
+ unsigned int csr;
+ int i, err;
+
++ if (!config_enabled(CONFIG_CPU_HAS_MSA))
++ return SIGSYS;
++
+ if (size != sizeof(*msa))
+ return -EINVAL;
+
+@@ -398,8 +401,8 @@ int protected_restore_fp_context(void __
+ }
+
+ fp_done:
+- if (used & USED_EXTCONTEXT)
+- err |= restore_extcontext(sc_to_extcontext(sc));
++ if (!err && (used & USED_EXTCONTEXT))
++ err = restore_extcontext(sc_to_extcontext(sc));
+
+ return err ?: sig;
+ }
--- /dev/null
+From 4249548454f7ba4581aeee26bd83f42b48a14d15 Mon Sep 17 00:00:00 2001
+From: "Maciej W. Rozycki" <macro@imgtec.com>
+Date: Thu, 12 May 2016 10:18:27 +0100
+Subject: MIPS: ptrace: Fix FP context restoration FCSR regression
+
+From: Maciej W. Rozycki <macro@imgtec.com>
+
+commit 4249548454f7ba4581aeee26bd83f42b48a14d15 upstream.
+
+Fix a floating-point context restoration regression introduced with
+commit 9b26616c8d9d ("MIPS: Respect the ISA level in FCSR handling")
+that causes a Floating Point exception and consequently a kernel oops
+with hard float configurations when one or more FCSR Enable and their
+corresponding Cause bits are set both at a time via a ptrace(2) call.
+
+To do so reinstate Cause bit masking originally introduced with commit
+b1442d39fac2 ("MIPS: Prevent user from setting FCSR cause bits") to
+address this exact problem and then inadvertently removed from the
+PTRACE_SETFPREGS request with the commit referred above.
+
+Signed-off-by: Maciej W. Rozycki <macro@imgtec.com>
+Cc: linux-mips@linux-mips.org
+Patchwork: https://patchwork.linux-mips.org/patch/13238/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/kernel/ptrace.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/arch/mips/kernel/ptrace.c
++++ b/arch/mips/kernel/ptrace.c
+@@ -176,6 +176,7 @@ int ptrace_setfpregs(struct task_struct
+ }
+
+ __get_user(value, data + 64);
++ value &= ~FPU_CSR_ALL_X;
+ fcr31 = child->thread.fpu.fcr31;
+ mask = boot_cpu_data.fpu_msk31;
+ child->thread.fpu.fcr31 = (value & ~mask) | (fcr31 & mask);
--- /dev/null
+From abf378be49f38c4d3e23581d3df3fa9f1b1b11d2 Mon Sep 17 00:00:00 2001
+From: "Maciej W. Rozycki" <macro@imgtec.com>
+Date: Thu, 12 May 2016 10:19:08 +0100
+Subject: MIPS: ptrace: Prevent writes to read-only FCSR bits
+
+From: Maciej W. Rozycki <macro@imgtec.com>
+
+commit abf378be49f38c4d3e23581d3df3fa9f1b1b11d2 upstream.
+
+Correct the cases missed with commit 9b26616c8d9d ("MIPS: Respect the
+ISA level in FCSR handling") and prevent writes to read-only FCSR bits
+there.
+
+This in particular applies to FP context initialisation where any IEEE
+754-2008 bits preset by `mips_set_personality_nan' are cleared before
+the relevant ptrace(2) call takes effect and the PTRACE_POKEUSR request
+addressing FPC_CSR where no masking of read-only FCSR bits is done.
+
+Remove the FCSR clearing from FP context initialisation then and unify
+PTRACE_POKEUSR/FPC_CSR and PTRACE_SETFPREGS handling, by factoring out
+code from `ptrace_setfpregs' and calling it from both places.
+
+This mostly matters to soft float configurations where the emulator can
+be switched this way to a mode which should not be accessible and cannot
+be set with the CTC1 instruction. With hard float configurations any
+effect is transient anyway as read-only bits will retain their values at
+the time the FP context is restored.
+
+Signed-off-by: Maciej W. Rozycki <macro@imgtec.com>
+Cc: linux-mips@linux-mips.org
+Patchwork: https://patchwork.linux-mips.org/patch/13239/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/kernel/ptrace.c | 28 +++++++++++++++++++---------
+ 1 file changed, 19 insertions(+), 9 deletions(-)
+
+--- a/arch/mips/kernel/ptrace.c
++++ b/arch/mips/kernel/ptrace.c
+@@ -57,8 +57,7 @@ static void init_fp_ctx(struct task_stru
+ /* Begin with data registers set to all 1s... */
+ memset(&target->thread.fpu.fpr, ~0, sizeof(target->thread.fpu.fpr));
+
+- /* ...and FCSR zeroed */
+- target->thread.fpu.fcr31 = 0;
++ /* FCSR has been preset by `mips_set_personality_nan'. */
+
+ /*
+ * Record that the target has "used" math, such that the context
+@@ -80,6 +79,22 @@ void ptrace_disable(struct task_struct *
+ }
+
+ /*
++ * Poke at FCSR according to its mask. Don't set the cause bits as
++ * this is currently not handled correctly in FP context restoration
++ * and will cause an oops if a corresponding enable bit is set.
++ */
++static void ptrace_setfcr31(struct task_struct *child, u32 value)
++{
++ u32 fcr31;
++ u32 mask;
++
++ value &= ~FPU_CSR_ALL_X;
++ fcr31 = child->thread.fpu.fcr31;
++ mask = boot_cpu_data.fpu_msk31;
++ child->thread.fpu.fcr31 = (value & ~mask) | (fcr31 & mask);
++}
++
++/*
+ * Read a general register set. We always use the 64-bit format, even
+ * for 32-bit kernels and for 32-bit processes on a 64-bit kernel.
+ * Registers are sign extended to fill the available space.
+@@ -159,9 +174,7 @@ int ptrace_setfpregs(struct task_struct
+ {
+ union fpureg *fregs;
+ u64 fpr_val;
+- u32 fcr31;
+ u32 value;
+- u32 mask;
+ int i;
+
+ if (!access_ok(VERIFY_READ, data, 33 * 8))
+@@ -176,10 +189,7 @@ int ptrace_setfpregs(struct task_struct
+ }
+
+ __get_user(value, data + 64);
+- value &= ~FPU_CSR_ALL_X;
+- fcr31 = child->thread.fpu.fcr31;
+- mask = boot_cpu_data.fpu_msk31;
+- child->thread.fpu.fcr31 = (value & ~mask) | (fcr31 & mask);
++ ptrace_setfcr31(child, value);
+
+ /* FIR may not be written. */
+
+@@ -809,7 +819,7 @@ long arch_ptrace(struct task_struct *chi
+ break;
+ #endif
+ case FPC_CSR:
+- child->thread.fpu.fcr31 = data & ~FPU_CSR_ALL_X;
++ ptrace_setfcr31(child, data);
+ break;
+ case DSP_BASE ... DSP_BASE + 5: {
+ dspreg_t *dregs;
--- /dev/null
+From a95d069204e178f18476f5499abab0d0d9cbc32c Mon Sep 17 00:00:00 2001
+From: Huacai Chen <chenhc@lemote.com>
+Date: Thu, 17 Mar 2016 20:37:10 +0800
+Subject: MIPS: Reserve nosave data for hibernation
+
+From: Huacai Chen <chenhc@lemote.com>
+
+commit a95d069204e178f18476f5499abab0d0d9cbc32c upstream.
+
+After commit 92923ca3aacef63c92d ("mm: meminit: only set page reserved
+in the memblock region"), the MIPS hibernation is broken. Because pages
+in nosave data section should be "reserved", but currently they aren't
+set to "reserved" at initialization. This patch makes hibernation work
+again.
+
+Signed-off-by: Huacai Chen <chenhc@lemote.com>
+Cc: Aurelien Jarno <aurelien@aurel32.net>
+Cc: Steven J . Hill <sjhill@realitydiluted.com>
+Cc: Fuxin Zhang <zhangfx@lemote.com>
+Cc: Zhangjin Wu <wuzhangjin@gmail.com>
+Cc: linux-mips@linux-mips.org
+Patchwork: https://patchwork.linux-mips.org/patch/12888/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/kernel/setup.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/arch/mips/kernel/setup.c
++++ b/arch/mips/kernel/setup.c
+@@ -706,6 +706,9 @@ static void __init arch_mem_init(char **
+ for_each_memblock(reserved, reg)
+ if (reg->size != 0)
+ reserve_bootmem(reg->base, reg->size, BOOTMEM_DEFAULT);
++
++ reserve_bootmem_region(__pa_symbol(&__nosave_begin),
++ __pa_symbol(&__nosave_end)); /* Reserve for hibernation */
+ }
+
+ static void __init resource_init(void)
--- /dev/null
+From 37d22a0d798b5c938b277d32cfd86dc231381342 Mon Sep 17 00:00:00 2001
+From: Paul Burton <paul.burton@imgtec.com>
+Date: Tue, 1 Mar 2016 02:37:59 +0000
+Subject: MIPS: Sync icache & dcache in set_pte_at
+
+From: Paul Burton <paul.burton@imgtec.com>
+
+commit 37d22a0d798b5c938b277d32cfd86dc231381342 upstream.
+
+It's possible for pages to become visible prior to update_mmu_cache
+running if a thread within the same address space preempts the current
+thread or runs simultaneously on another CPU. That is, the following
+scenario is possible:
+
+ CPU0 CPU1
+
+ write to page
+ flush_dcache_page
+ flush_icache_page
+ set_pte_at
+ map page
+ update_mmu_cache
+
+If CPU1 maps the page in between CPU0's set_pte_at, which marks it valid
+& visible, and update_mmu_cache where the dcache flush occurs then CPU1s
+icache will fill from stale data (unless it fills from the dcache, in
+which case all is good, but most MIPS CPUs don't have this property).
+Commit 4d46a67a3eb8 ("MIPS: Fix race condition in lazy cache flushing.")
+attempted to fix that by performing the dcache flush in
+flush_icache_page such that it occurs before the set_pte_at call makes
+the page visible. However it has the problem that not all code that
+writes to pages exposed to userland call flush_icache_page. There are
+many callers of set_pte_at under mm/ and only 2 of them do call
+flush_icache_page. Thus the race window between a page becoming visible
+& being coherent between the icache & dcache remains open in some cases.
+
+To illustrate some of the cases, a WARN was added to __update_cache with
+this patch applied that triggered in cases where a page about to be
+flushed from the dcache was not the last page provided to
+flush_icache_page. That is, backtraces were obtained for cases in which
+the race window is left open without this patch. The 2 standout examples
+follow.
+
+When forking a process:
+
+[ 15.271842] [<80417630>] __update_cache+0xcc/0x188
+[ 15.277274] [<80530394>] copy_page_range+0x56c/0x6ac
+[ 15.282861] [<8042936c>] copy_process.part.54+0xd40/0x17ac
+[ 15.289028] [<80429f80>] do_fork+0xe4/0x420
+[ 15.293747] [<80413808>] handle_sys+0x128/0x14c
+
+When exec'ing an ELF binary:
+
+[ 14.445964] [<80417630>] __update_cache+0xcc/0x188
+[ 14.451369] [<80538d88>] move_page_tables+0x414/0x498
+[ 14.457075] [<8055d848>] setup_arg_pages+0x220/0x318
+[ 14.462685] [<805b0f38>] load_elf_binary+0x530/0x12a0
+[ 14.468374] [<8055ec3c>] search_binary_handler+0xbc/0x214
+[ 14.474444] [<8055f6c0>] do_execveat_common+0x43c/0x67c
+[ 14.480324] [<8055f938>] do_execve+0x38/0x44
+[ 14.485137] [<80413808>] handle_sys+0x128/0x14c
+
+These code paths write into a page, call flush_dcache_page then call
+set_pte_at without flush_icache_page inbetween. The end result is that
+the icache can become corrupted & userland processes may execute
+unexpected or invalid code, typically resulting in a reserved
+instruction exception, a trap or a segfault.
+
+Fix this race condition fully by performing any cache maintenance
+required to keep the icache & dcache in sync in set_pte_at, before the
+page is made valid. This has the added bonus of ensuring the cache
+maintenance always happens in one location, rather than being duplicated
+in flush_icache_page & update_mmu_cache. It also matches the way other
+architectures solve the same problem (see arm, ia64 & powerpc).
+
+Signed-off-by: Paul Burton <paul.burton@imgtec.com>
+Reported-by: Ionela Voinescu <ionela.voinescu@imgtec.com>
+Cc: Lars Persson <lars.persson@axis.com>
+Fixes: 4d46a67a3eb8 ("MIPS: Fix race condition in lazy cache flushing.")
+Cc: Steven J. Hill <sjhill@realitydiluted.com>
+Cc: David Daney <david.daney@cavium.com>
+Cc: Huacai Chen <chenhc@lemote.com>
+Cc: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Jerome Marchand <jmarchan@redhat.com>
+Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
+Cc: linux-mips@linux-mips.org
+Cc: linux-kernel@vger.kernel.org
+Patchwork: https://patchwork.linux-mips.org/patch/12722/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/include/asm/cacheflush.h | 6 ------
+ arch/mips/include/asm/pgtable.h | 26 +++++++++++++++++++++-----
+ arch/mips/mm/cache.c | 19 +++----------------
+ 3 files changed, 24 insertions(+), 27 deletions(-)
+
+--- a/arch/mips/include/asm/cacheflush.h
++++ b/arch/mips/include/asm/cacheflush.h
+@@ -51,7 +51,6 @@ extern void (*flush_cache_range)(struct
+ unsigned long start, unsigned long end);
+ extern void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page, unsigned long pfn);
+ extern void __flush_dcache_page(struct page *page);
+-extern void __flush_icache_page(struct vm_area_struct *vma, struct page *page);
+
+ #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
+ static inline void flush_dcache_page(struct page *page)
+@@ -77,11 +76,6 @@ static inline void flush_anon_page(struc
+ static inline void flush_icache_page(struct vm_area_struct *vma,
+ struct page *page)
+ {
+- if (!cpu_has_ic_fills_f_dc && (vma->vm_flags & VM_EXEC) &&
+- Page_dcache_dirty(page)) {
+- __flush_icache_page(vma, page);
+- ClearPageDcacheDirty(page);
+- }
+ }
+
+ extern void (*flush_icache_range)(unsigned long start, unsigned long end);
+--- a/arch/mips/include/asm/pgtable.h
++++ b/arch/mips/include/asm/pgtable.h
+@@ -127,10 +127,14 @@ do { \
+ } \
+ } while(0)
+
++static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
++ pte_t *ptep, pte_t pteval);
++
+ #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32)
+
+ #define pte_none(pte) (!(((pte).pte_high) & ~_PAGE_GLOBAL))
+ #define pte_present(pte) ((pte).pte_low & _PAGE_PRESENT)
++#define pte_no_exec(pte) ((pte).pte_low & _PAGE_NO_EXEC)
+
+ static inline void set_pte(pte_t *ptep, pte_t pte)
+ {
+@@ -148,7 +152,6 @@ static inline void set_pte(pte_t *ptep,
+ buddy->pte_high |= _PAGE_GLOBAL;
+ }
+ }
+-#define set_pte_at(mm, addr, ptep, pteval) set_pte(ptep, pteval)
+
+ static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
+ {
+@@ -166,6 +169,7 @@ static inline void pte_clear(struct mm_s
+
+ #define pte_none(pte) (!(pte_val(pte) & ~_PAGE_GLOBAL))
+ #define pte_present(pte) (pte_val(pte) & _PAGE_PRESENT)
++#define pte_no_exec(pte) (pte_val(pte) & _PAGE_NO_EXEC)
+
+ /*
+ * Certain architectures need to do special things when pte's
+@@ -218,7 +222,6 @@ static inline void set_pte(pte_t *ptep,
+ }
+ #endif
+ }
+-#define set_pte_at(mm, addr, ptep, pteval) set_pte(ptep, pteval)
+
+ static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
+ {
+@@ -234,6 +237,22 @@ static inline void pte_clear(struct mm_s
+ }
+ #endif
+
++static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
++ pte_t *ptep, pte_t pteval)
++{
++ extern void __update_cache(unsigned long address, pte_t pte);
++
++ if (!pte_present(pteval))
++ goto cache_sync_done;
++
++ if (pte_present(*ptep) && (pte_pfn(*ptep) == pte_pfn(pteval)))
++ goto cache_sync_done;
++
++ __update_cache(addr, pteval);
++cache_sync_done:
++ set_pte(ptep, pteval);
++}
++
+ /*
+ * (pmds are folded into puds so this doesn't get actually called,
+ * but the define is needed for a generic inline function.)
+@@ -430,15 +449,12 @@ static inline pte_t pte_modify(pte_t pte
+
+ extern void __update_tlb(struct vm_area_struct *vma, unsigned long address,
+ pte_t pte);
+-extern void __update_cache(struct vm_area_struct *vma, unsigned long address,
+- pte_t pte);
+
+ static inline void update_mmu_cache(struct vm_area_struct *vma,
+ unsigned long address, pte_t *ptep)
+ {
+ pte_t pte = *ptep;
+ __update_tlb(vma, address, pte);
+- __update_cache(vma, address, pte);
+ }
+
+ static inline void update_mmu_cache_pmd(struct vm_area_struct *vma,
+--- a/arch/mips/mm/cache.c
++++ b/arch/mips/mm/cache.c
+@@ -119,30 +119,17 @@ void __flush_anon_page(struct page *page
+
+ EXPORT_SYMBOL(__flush_anon_page);
+
+-void __flush_icache_page(struct vm_area_struct *vma, struct page *page)
+-{
+- unsigned long addr;
+-
+- if (PageHighMem(page))
+- return;
+-
+- addr = (unsigned long) page_address(page);
+- flush_data_cache_page(addr);
+-}
+-EXPORT_SYMBOL_GPL(__flush_icache_page);
+-
+-void __update_cache(struct vm_area_struct *vma, unsigned long address,
+- pte_t pte)
++void __update_cache(unsigned long address, pte_t pte)
+ {
+ struct page *page;
+ unsigned long pfn, addr;
+- int exec = (vma->vm_flags & VM_EXEC) && !cpu_has_ic_fills_f_dc;
++ int exec = !pte_no_exec(pte) && !cpu_has_ic_fills_f_dc;
+
+ pfn = pte_pfn(pte);
+ if (unlikely(!pfn_valid(pfn)))
+ return;
+ page = pfn_to_page(pfn);
+- if (page_mapping(page) && Page_dcache_dirty(page)) {
++ if (Page_dcache_dirty(page)) {
+ if (PageHighMem(page))
+ addr = (unsigned long)kmap_atomic(page);
+ else
--- /dev/null
+From 8a3c8b48aca8771bff3536e40aa26ffb311699d1 Mon Sep 17 00:00:00 2001
+From: Paul Burton <paul.burton@imgtec.com>
+Date: Fri, 15 Apr 2016 10:07:23 +0100
+Subject: MIPS: Use copy_s.fmt rather than copy_u.fmt
+
+From: Paul Burton <paul.burton@imgtec.com>
+
+commit 8a3c8b48aca8771bff3536e40aa26ffb311699d1 upstream.
+
+In revision 1.12 of the MSA specification, the copy_u.w instruction has
+been removed for MIPS32 & the copy_u.d instruction has been removed for
+MIPS64. Newer toolchains (eg. Codescape SDK essentials 2015.10) will
+complain about this like so:
+
+arch/mips/kernel/r4k_fpu.S:290: Error: opcode not supported on this
+processor: mips32r2 (mips32r2) `copy_u.w $1,$w26[3]'
+
+Since we always copy to the width of a GPR, simply use copy_s instead of
+copy_u to fix this.
+
+Signed-off-by: Paul Burton <paul.burton@imgtec.com>
+Signed-off-by: James Hogan <james.hogan@imgtec.com>
+Cc: linux-mips@linux-mips.org
+Patchwork: https://patchwork.linux-mips.org/patch/13061/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/include/asm/asmmacro.h | 24 ++++++++++++------------
+ arch/mips/kernel/r4k_fpu.S | 10 +++++-----
+ 2 files changed, 17 insertions(+), 17 deletions(-)
+
+--- a/arch/mips/include/asm/asmmacro.h
++++ b/arch/mips/include/asm/asmmacro.h
+@@ -298,21 +298,21 @@
+ .set pop
+ .endm
+
+- .macro copy_u_w ws, n
++ .macro copy_s_w ws, n
+ .set push
+ .set mips32r2
+ .set fp=64
+ .set msa
+- copy_u.w $1, $w\ws[\n]
++ copy_s.w $1, $w\ws[\n]
+ .set pop
+ .endm
+
+- .macro copy_u_d ws, n
++ .macro copy_s_d ws, n
+ .set push
+ .set mips64r2
+ .set fp=64
+ .set msa
+- copy_u.d $1, $w\ws[\n]
++ copy_s.d $1, $w\ws[\n]
+ .set pop
+ .endm
+
+@@ -346,8 +346,8 @@
+ #define STH_MSA_INSN 0x5800081f
+ #define STW_MSA_INSN 0x5800082f
+ #define STD_MSA_INSN 0x5800083f
+-#define COPY_UW_MSA_INSN 0x58f00056
+-#define COPY_UD_MSA_INSN 0x58f80056
++#define COPY_SW_MSA_INSN 0x58b00056
++#define COPY_SD_MSA_INSN 0x58b80056
+ #define INSERT_W_MSA_INSN 0x59300816
+ #define INSERT_D_MSA_INSN 0x59380816
+ #else
+@@ -361,8 +361,8 @@
+ #define STH_MSA_INSN 0x78000825
+ #define STW_MSA_INSN 0x78000826
+ #define STD_MSA_INSN 0x78000827
+-#define COPY_UW_MSA_INSN 0x78f00059
+-#define COPY_UD_MSA_INSN 0x78f80059
++#define COPY_SW_MSA_INSN 0x78b00059
++#define COPY_SD_MSA_INSN 0x78b80059
+ #define INSERT_W_MSA_INSN 0x79300819
+ #define INSERT_D_MSA_INSN 0x79380819
+ #endif
+@@ -461,21 +461,21 @@
+ .set pop
+ .endm
+
+- .macro copy_u_w ws, n
++ .macro copy_s_w ws, n
+ .set push
+ .set noat
+ SET_HARDFLOAT
+ .insn
+- .word COPY_UW_MSA_INSN | (\n << 16) | (\ws << 11)
++ .word COPY_SW_MSA_INSN | (\n << 16) | (\ws << 11)
+ .set pop
+ .endm
+
+- .macro copy_u_d ws, n
++ .macro copy_s_d ws, n
+ .set push
+ .set noat
+ SET_HARDFLOAT
+ .insn
+- .word COPY_UD_MSA_INSN | (\n << 16) | (\ws << 11)
++ .word COPY_SD_MSA_INSN | (\n << 16) | (\ws << 11)
+ .set pop
+ .endm
+
+--- a/arch/mips/kernel/r4k_fpu.S
++++ b/arch/mips/kernel/r4k_fpu.S
+@@ -244,17 +244,17 @@ LEAF(\name)
+ .set push
+ .set noat
+ #ifdef CONFIG_64BIT
+- copy_u_d \wr, 1
++ copy_s_d \wr, 1
+ EX sd $1, \off(\base)
+ #elif defined(CONFIG_CPU_LITTLE_ENDIAN)
+- copy_u_w \wr, 2
++ copy_s_w \wr, 2
+ EX sw $1, \off(\base)
+- copy_u_w \wr, 3
++ copy_s_w \wr, 3
+ EX sw $1, (\off+4)(\base)
+ #else /* CONFIG_CPU_BIG_ENDIAN */
+- copy_u_w \wr, 2
++ copy_s_w \wr, 2
+ EX sw $1, (\off+4)(\base)
+- copy_u_w \wr, 3
++ copy_s_w \wr, 3
+ EX sw $1, \off(\base)
+ #endif
+ .set pop
--- /dev/null
+From 94cc36b84acc29f543b48bc5ed786011b112a666 Mon Sep 17 00:00:00 2001
+From: "Maciej W. Rozycki" <macro@imgtec.com>
+Date: Thu, 26 May 2016 12:55:45 +0100
+Subject: MIPS: VDSO: Build with `-fno-strict-aliasing'
+
+From: Maciej W. Rozycki <macro@imgtec.com>
+
+commit 94cc36b84acc29f543b48bc5ed786011b112a666 upstream.
+
+Avoid an aliasing issue causing a build error in VDSO:
+
+In file included from include/linux/srcu.h:34:0,
+ from include/linux/notifier.h:15,
+ from ./arch/mips/include/asm/uprobes.h:9,
+ from include/linux/uprobes.h:61,
+ from include/linux/mm_types.h:13,
+ from ./arch/mips/include/asm/vdso.h:14,
+ from arch/mips/vdso/vdso.h:27,
+ from arch/mips/vdso/gettimeofday.c:11:
+include/linux/workqueue.h: In function 'work_static':
+include/linux/workqueue.h:186:2: error: dereferencing type-punned pointer will break strict-aliasing rules [-Werror=strict-aliasing]
+ return *work_data_bits(work) & WORK_STRUCT_STATIC;
+ ^
+cc1: all warnings being treated as errors
+make[2]: *** [arch/mips/vdso/gettimeofday.o] Error 1
+
+with a CONFIG_DEBUG_OBJECTS_WORK configuration and GCC 5.2.0. Include
+`-fno-strict-aliasing' along with compiler options used, as required for
+kernel code, fixing a problem present since the introduction of VDSO
+with commit ebb5e78cc634 ("MIPS: Initial implementation of a VDSO").
+
+Thanks to Tejun for diagnosing this properly!
+
+Signed-off-by: Maciej W. Rozycki <macro@imgtec.com>
+Reviewed-by: James Hogan <james.hogan@imgtec.com>
+Fixes: ebb5e78cc634 ("MIPS: Initial implementation of a VDSO")
+Cc: Tejun Heo <tj@kernel.org>
+Cc: linux-mips@linux-mips.org
+Patchwork: https://patchwork.linux-mips.org/patch/13357/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/vdso/Makefile | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/arch/mips/vdso/Makefile
++++ b/arch/mips/vdso/Makefile
+@@ -9,7 +9,8 @@ ccflags-vdso := \
+ $(filter -march=%,$(KBUILD_CFLAGS))
+ cflags-vdso := $(ccflags-vdso) \
+ $(filter -W%,$(filter-out -Wa$(comma)%,$(KBUILD_CFLAGS))) \
+- -O2 -g -fPIC -fno-common -fno-builtin -G 0 -DDISABLE_BRANCH_PROFILING \
++ -O2 -g -fPIC -fno-strict-aliasing -fno-common -fno-builtin -G 0 \
++ -DDISABLE_BRANCH_PROFILING \
+ $(call cc-option, -fno-stack-protector)
+ aflags-vdso := $(ccflags-vdso) \
+ $(filter -I%,$(KBUILD_CFLAGS)) \
mips64-r6-r2-emulation-bugfix.patch
mips-math-emu-fix-jalr-emulation-when-rd-0.patch
mips-msa-fix-a-link-error-on-_init_msa_upper-with-older-gcc.patch
+mips-don-t-unwind-to-user-mode-with-eva.patch
+mips-avoid-using-unwind_stack-with-usermode.patch
+mips-fix-siginfo.h-to-use-strict-posix-types.patch
+mips-fix-uapi-include-in-exported-asm-siginfo.h.patch
+mips-fix-watchpoint-restoration.patch
+mips-handle-highmem-pages-in-__update_cache.patch
+mips-sync-icache-dcache-in-set_pte_at.patch
+mips-ath79-make-bootconsole-wait-for-both-thre-and-temt.patch
+mips-reserve-nosave-data-for-hibernation.patch
+mips-loongson-3-reserve-32mb-for-rs780e-integrated-gpu.patch
+mips-use-copy_s.fmt-rather-than-copy_u.fmt.patch
+mips-fix-msa-ld_-st_-asm-macros-to-use-ptr_addu.patch
+mips-prevent-restoration-of-msa-context-in-non-msa-kernels.patch
+mips-disable-preemption-during-prctl-pr_set_fp_mode.patch
+mips-ptrace-fix-fp-context-restoration-fcsr-regression.patch
+mips-ptrace-prevent-writes-to-read-only-fcsr-bits.patch
+mips-fix-sigreturn-via-vdso-on-micromips-kernel.patch
+mips-build-micromips-vdso-for-micromips-kernels.patch
+mips-lib-mark-intrinsics-notrace.patch
+mips-vdso-build-with-fno-strict-aliasing.patch