--- a/arch/mips/kernel/ptrace.c
+++ b/arch/mips/kernel/ptrace.c
-@@ -416,6 +416,7 @@ static int fpr_get(struct task_struct *t
- &target->thread.fpu,
- 0, sizeof(elf_fpregset_t));
+@@ -428,6 +428,7 @@ static int fpr_get_msa(struct task_struc
+ u64 fpr_val;
+ int err;
+ BUILD_BUG_ON(sizeof(fpr_val) != sizeof(elf_fpreg_t));
for (i = 0; i < NUM_FPU_REGS; i++) {
fpr_val = get_fpr64(&target->thread.fpu.fpr[i], 0);
- err = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+ err = user_regset_copyout(pos, count, kbuf, ubuf,
--- /dev/null
+From 80b3ffce0196ea50068885d085ff981e4b8396f4 Mon Sep 17 00:00:00 2001
+From: "Maciej W. Rozycki" <macro@mips.com>
+Date: Mon, 11 Dec 2017 22:53:14 +0000
+Subject: MIPS: Consistently handle buffer counter with PTRACE_SETREGSET
+
+From: Maciej W. Rozycki <macro@mips.com>
+
+commit 80b3ffce0196ea50068885d085ff981e4b8396f4 upstream.
+
+Update commit d614fd58a283 ("mips/ptrace: Preserve previous registers
+for short regset write") bug and consistently consume all data supplied
+to `fpr_set_msa' with the ptrace(2) PTRACE_SETREGSET request, such that
+a zero data buffer counter is returned where insufficient data has been
+given to fill a whole number of FP general registers.
+
+In reality this is not going to happen, as the caller is supposed to
+only supply data covering a whole number of registers and it is verified
+in `ptrace_regset' and again asserted in `fpr_set', however structuring
+code such that the presence of trailing partial FP general register data
+causes `fpr_set_msa' to return with a non-zero data buffer counter makes
+it appear that this trailing data will be used if there are subsequent
+writes made to FP registers, which is going to be the case with the FCSR
+once the missing write to that register has been fixed.
+
+Fixes: d614fd58a283 ("mips/ptrace: Preserve previous registers for short regset write")
+Signed-off-by: Maciej W. Rozycki <macro@mips.com>
+Cc: James Hogan <james.hogan@mips.com>
+Cc: Paul Burton <Paul.Burton@mips.com>
+Cc: Alex Smith <alex@alex-smith.me.uk>
+Cc: Dave Martin <Dave.Martin@arm.com>
+Cc: linux-mips@linux-mips.org
+Cc: linux-kernel@vger.kernel.org
+Cc: stable@vger.kernel.org # v4.11+
+Patchwork: https://patchwork.linux-mips.org/patch/17927/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/kernel/ptrace.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/mips/kernel/ptrace.c
++++ b/arch/mips/kernel/ptrace.c
+@@ -485,7 +485,7 @@ static int fpr_set_msa(struct task_struc
+ int err;
+
+ BUILD_BUG_ON(sizeof(fpr_val) != sizeof(elf_fpreg_t));
+- for (i = 0; i < NUM_FPU_REGS && *count >= sizeof(elf_fpreg_t); i++) {
++ for (i = 0; i < NUM_FPU_REGS && *count > 0; i++) {
+ err = user_regset_copyin(pos, count, kbuf, ubuf,
+ &fpr_val, i * sizeof(elf_fpreg_t),
+ (i + 1) * sizeof(elf_fpreg_t));
--- /dev/null
+From c8c5a3a24d395b14447a9a89d61586a913840a3b Mon Sep 17 00:00:00 2001
+From: "Maciej W. Rozycki" <macro@mips.com>
+Date: Mon, 11 Dec 2017 22:56:54 +0000
+Subject: MIPS: Disallow outsized PTRACE_SETREGSET NT_PRFPREG regset accesses
+
+From: Maciej W. Rozycki <macro@mips.com>
+
+commit c8c5a3a24d395b14447a9a89d61586a913840a3b upstream.
+
+Complement commit c23b3d1a5311 ("MIPS: ptrace: Change GP regset to use
+correct core dump register layout") and also reject outsized
+PTRACE_SETREGSET requests to the NT_PRFPREG regset, like with the
+NT_PRSTATUS regset.
+
+Signed-off-by: Maciej W. Rozycki <macro@mips.com>
+Fixes: c23b3d1a5311 ("MIPS: ptrace: Change GP regset to use correct core dump register layout")
+Cc: James Hogan <james.hogan@mips.com>
+Cc: Paul Burton <Paul.Burton@mips.com>
+Cc: Alex Smith <alex@alex-smith.me.uk>
+Cc: Dave Martin <Dave.Martin@arm.com>
+Cc: linux-mips@linux-mips.org
+Cc: linux-kernel@vger.kernel.org
+Patchwork: https://patchwork.linux-mips.org/patch/17930/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/kernel/ptrace.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/arch/mips/kernel/ptrace.c
++++ b/arch/mips/kernel/ptrace.c
+@@ -530,6 +530,9 @@ static int fpr_set(struct task_struct *t
+
+ BUG_ON(count % sizeof(elf_fpreg_t));
+
++ if (pos + count > sizeof(elf_fpregset_t))
++ return -EIO;
++
+ if (sizeof(target->thread.fpu.fpr[0]) == sizeof(elf_fpreg_t))
+ err = fpr_set_fpa(target, &pos, &count, &kbuf, &ubuf);
+ else
--- /dev/null
+From a03fe72572c12e98f4173f8a535f32468e48b6ec Mon Sep 17 00:00:00 2001
+From: "Maciej W. Rozycki" <macro@mips.com>
+Date: Mon, 11 Dec 2017 22:51:35 +0000
+Subject: MIPS: Factor out NT_PRFPREG regset access helpers
+
+From: Maciej W. Rozycki <macro@mips.com>
+
+commit a03fe72572c12e98f4173f8a535f32468e48b6ec upstream.
+
+In preparation to fix a commit 72b22bbad1e7 ("MIPS: Don't assume 64-bit
+FP registers for FP regset") FCSR access regression factor out
+NT_PRFPREG regset access helpers for the non-MSA and the MSA variants
+respectively, to avoid having to deal with excessive indentation in the
+actual fix.
+
+No functional change, however use `target->thread.fpu.fpr[0]' rather
+than `target->thread.fpu.fpr[i]' for FGR holding type size determination
+as there's no `i' variable to refer to anymore, and for the factored out
+`i' variable declaration use `unsigned int' rather than `unsigned' as
+its type, following the common style.
+
+Signed-off-by: Maciej W. Rozycki <macro@mips.com>
+Fixes: 72b22bbad1e7 ("MIPS: Don't assume 64-bit FP registers for FP regset")
+Cc: James Hogan <james.hogan@mips.com>
+Cc: Paul Burton <Paul.Burton@mips.com>
+Cc: Alex Smith <alex@alex-smith.me.uk>
+Cc: Dave Martin <Dave.Martin@arm.com>
+Cc: linux-mips@linux-mips.org
+Cc: linux-kernel@vger.kernel.org
+Patchwork: https://patchwork.linux-mips.org/patch/17925/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/kernel/ptrace.c | 106 +++++++++++++++++++++++++++++++++++-----------
+ 1 file changed, 82 insertions(+), 24 deletions(-)
+
+--- a/arch/mips/kernel/ptrace.c
++++ b/arch/mips/kernel/ptrace.c
+@@ -400,25 +400,36 @@ static int gpr64_set(struct task_struct
+
+ #endif /* CONFIG_64BIT */
+
+-static int fpr_get(struct task_struct *target,
+- const struct user_regset *regset,
+- unsigned int pos, unsigned int count,
+- void *kbuf, void __user *ubuf)
++/*
++ * Copy the floating-point context to the supplied NT_PRFPREG buffer,
++ * !CONFIG_CPU_HAS_MSA variant. FP context's general register slots
++ * correspond 1:1 to buffer slots.
++ */
++static int fpr_get_fpa(struct task_struct *target,
++ unsigned int *pos, unsigned int *count,
++ void **kbuf, void __user **ubuf)
+ {
+- unsigned i;
+- int err;
+- u64 fpr_val;
+-
+- /* XXX fcr31 */
++ return user_regset_copyout(pos, count, kbuf, ubuf,
++ &target->thread.fpu,
++ 0, sizeof(elf_fpregset_t));
++}
+
+- if (sizeof(target->thread.fpu.fpr[i]) == sizeof(elf_fpreg_t))
+- return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+- &target->thread.fpu,
+- 0, sizeof(elf_fpregset_t));
++/*
++ * Copy the floating-point context to the supplied NT_PRFPREG buffer,
++ * CONFIG_CPU_HAS_MSA variant. Only lower 64 bits of FP context's
++ * general register slots are copied to buffer slots.
++ */
++static int fpr_get_msa(struct task_struct *target,
++ unsigned int *pos, unsigned int *count,
++ void **kbuf, void __user **ubuf)
++{
++ unsigned int i;
++ u64 fpr_val;
++ int err;
+
+ for (i = 0; i < NUM_FPU_REGS; i++) {
+ fpr_val = get_fpr64(&target->thread.fpu.fpr[i], 0);
+- err = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
++ err = user_regset_copyout(pos, count, kbuf, ubuf,
+ &fpr_val, i * sizeof(elf_fpreg_t),
+ (i + 1) * sizeof(elf_fpreg_t));
+ if (err)
+@@ -428,25 +439,54 @@ static int fpr_get(struct task_struct *t
+ return 0;
+ }
+
+-static int fpr_set(struct task_struct *target,
++/* Copy the floating-point context to the supplied NT_PRFPREG buffer. */
++static int fpr_get(struct task_struct *target,
+ const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+- const void *kbuf, const void __user *ubuf)
++ void *kbuf, void __user *ubuf)
+ {
+- unsigned i;
+ int err;
+- u64 fpr_val;
+
+ /* XXX fcr31 */
+
+- if (sizeof(target->thread.fpu.fpr[i]) == sizeof(elf_fpreg_t))
+- return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+- &target->thread.fpu,
+- 0, sizeof(elf_fpregset_t));
++ if (sizeof(target->thread.fpu.fpr[0]) == sizeof(elf_fpreg_t))
++ err = fpr_get_fpa(target, &pos, &count, &kbuf, &ubuf);
++ else
++ err = fpr_get_msa(target, &pos, &count, &kbuf, &ubuf);
++
++ return err;
++}
++
++/*
++ * Copy the supplied NT_PRFPREG buffer to the floating-point context,
++ * !CONFIG_CPU_HAS_MSA variant. Buffer slots correspond 1:1 to FP
++ * context's general register slots.
++ */
++static int fpr_set_fpa(struct task_struct *target,
++ unsigned int *pos, unsigned int *count,
++ const void **kbuf, const void __user **ubuf)
++{
++ return user_regset_copyin(pos, count, kbuf, ubuf,
++ &target->thread.fpu,
++ 0, sizeof(elf_fpregset_t));
++}
++
++/*
++ * Copy the supplied NT_PRFPREG buffer to the floating-point context,
++ * CONFIG_CPU_HAS_MSA variant. Buffer slots are copied to lower 64
++ * bits only of FP context's general register slots.
++ */
++static int fpr_set_msa(struct task_struct *target,
++ unsigned int *pos, unsigned int *count,
++ const void **kbuf, const void __user **ubuf)
++{
++ unsigned int i;
++ u64 fpr_val;
++ int err;
+
+ BUILD_BUG_ON(sizeof(fpr_val) != sizeof(elf_fpreg_t));
+- for (i = 0; i < NUM_FPU_REGS && count >= sizeof(elf_fpreg_t); i++) {
+- err = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
++ for (i = 0; i < NUM_FPU_REGS && *count >= sizeof(elf_fpreg_t); i++) {
++ err = user_regset_copyin(pos, count, kbuf, ubuf,
+ &fpr_val, i * sizeof(elf_fpreg_t),
+ (i + 1) * sizeof(elf_fpreg_t));
+ if (err)
+@@ -457,6 +497,24 @@ static int fpr_set(struct task_struct *t
+ return 0;
+ }
+
++/* Copy the supplied NT_PRFPREG buffer to the floating-point context. */
++static int fpr_set(struct task_struct *target,
++ const struct user_regset *regset,
++ unsigned int pos, unsigned int count,
++ const void *kbuf, const void __user *ubuf)
++{
++ int err;
++
++ /* XXX fcr31 */
++
++ if (sizeof(target->thread.fpu.fpr[0]) == sizeof(elf_fpreg_t))
++ err = fpr_set_fpa(target, &pos, &count, &kbuf, &ubuf);
++ else
++ err = fpr_set_msa(target, &pos, &count, &kbuf, &ubuf);
++
++ return err;
++}
++
+ enum mips_regset {
+ REGSET_GPR,
+ REGSET_FPR,
--- /dev/null
+From be07a6a1188372b6d19a3307ec33211fc9c9439d Mon Sep 17 00:00:00 2001
+From: "Maciej W. Rozycki" <macro@mips.com>
+Date: Mon, 11 Dec 2017 22:54:33 +0000
+Subject: MIPS: Fix an FCSR access API regression with NT_PRFPREG and MSA
+
+From: Maciej W. Rozycki <macro@mips.com>
+
+commit be07a6a1188372b6d19a3307ec33211fc9c9439d upstream.
+
+Fix a commit 72b22bbad1e7 ("MIPS: Don't assume 64-bit FP registers for
+FP regset") public API regression, then activated by commit 1db1af84d6df
+("MIPS: Basic MSA context switching support"), that caused the FCSR
+register not to be read or written for CONFIG_CPU_HAS_MSA kernel
+configurations (regardless of actual presence or absence of the MSA
+feature in a given processor) with ptrace(2) PTRACE_GETREGSET and
+PTRACE_SETREGSET requests nor recorded in core dumps.
+
+This is because with !CONFIG_CPU_HAS_MSA configurations the whole of
+`elf_fpregset_t' array is bulk-copied as it is, which includes the FCSR
+in one half of the last, 33rd slot, whereas with CONFIG_CPU_HAS_MSA
+configurations array elements are copied individually, and then only the
+leading 32 FGR slots while the remaining slot is ignored.
+
+Correct the code then such that only FGR slots are copied in the
+respective !MSA and MSA helpers an then the FCSR slot is handled
+separately in common code. Use `ptrace_setfcr31' to update the FCSR
+too, so that the read-only mask is respected.
+
+Retrieving a correct value of FCSR is important in debugging not only
+for the human to be able to get the right interpretation of the
+situation, but for correct operation of GDB as well. This is because
+the condition code bits in FSCR are used by GDB to determine the
+location to place a breakpoint at when single-stepping through an FPU
+branch instruction. If such a breakpoint is placed incorrectly (i.e.
+with the condition reversed), then it will be missed, likely causing the
+debuggee to run away from the control of GDB and consequently breaking
+the process of investigation.
+
+Fortunately GDB continues using the older PTRACE_GETFPREGS ptrace(2)
+request which is unaffected, so the regression only really hits with
+post-mortem debug sessions using a core dump file, in which case
+execution, and consequently single-stepping through branches is not
+possible. Of course core files created by buggy kernels out there will
+have the value of FCSR recorded clobbered, but such core files cannot be
+corrected and the person using them simply will have to be aware that
+the value of FCSR retrieved is not reliable.
+
+Which also means we can likely get away without defining a replacement
+API which would ensure a correct value of FSCR to be retrieved, or none
+at all.
+
+This is based on previous work by Alex Smith, extensively rewritten.
+
+Signed-off-by: Alex Smith <alex@alex-smith.me.uk>
+Signed-off-by: James Hogan <james.hogan@mips.com>
+Signed-off-by: Maciej W. Rozycki <macro@mips.com>
+Fixes: 72b22bbad1e7 ("MIPS: Don't assume 64-bit FP registers for FP regset")
+Cc: Paul Burton <Paul.Burton@mips.com>
+Cc: Dave Martin <Dave.Martin@arm.com>
+Cc: linux-mips@linux-mips.org
+Cc: linux-kernel@vger.kernel.org
+Patchwork: https://patchwork.linux-mips.org/patch/17928/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/kernel/ptrace.c | 47 +++++++++++++++++++++++++++++++++++-----------
+ 1 file changed, 36 insertions(+), 11 deletions(-)
+
+--- a/arch/mips/kernel/ptrace.c
++++ b/arch/mips/kernel/ptrace.c
+@@ -403,7 +403,7 @@ static int gpr64_set(struct task_struct
+ /*
+ * Copy the floating-point context to the supplied NT_PRFPREG buffer,
+ * !CONFIG_CPU_HAS_MSA variant. FP context's general register slots
+- * correspond 1:1 to buffer slots.
++ * correspond 1:1 to buffer slots. Only general registers are copied.
+ */
+ static int fpr_get_fpa(struct task_struct *target,
+ unsigned int *pos, unsigned int *count,
+@@ -411,13 +411,14 @@ static int fpr_get_fpa(struct task_struc
+ {
+ return user_regset_copyout(pos, count, kbuf, ubuf,
+ &target->thread.fpu,
+- 0, sizeof(elf_fpregset_t));
++ 0, NUM_FPU_REGS * sizeof(elf_fpreg_t));
+ }
+
+ /*
+ * Copy the floating-point context to the supplied NT_PRFPREG buffer,
+ * CONFIG_CPU_HAS_MSA variant. Only lower 64 bits of FP context's
+- * general register slots are copied to buffer slots.
++ * general register slots are copied to buffer slots. Only general
++ * registers are copied.
+ */
+ static int fpr_get_msa(struct task_struct *target,
+ unsigned int *pos, unsigned int *count,
+@@ -439,20 +440,29 @@ static int fpr_get_msa(struct task_struc
+ return 0;
+ }
+
+-/* Copy the floating-point context to the supplied NT_PRFPREG buffer. */
++/*
++ * Copy the floating-point context to the supplied NT_PRFPREG buffer.
++ * Choose the appropriate helper for general registers, and then copy
++ * the FCSR register separately.
++ */
+ static int fpr_get(struct task_struct *target,
+ const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ void *kbuf, void __user *ubuf)
+ {
++ const int fcr31_pos = NUM_FPU_REGS * sizeof(elf_fpreg_t);
+ int err;
+
+- /* XXX fcr31 */
+-
+ if (sizeof(target->thread.fpu.fpr[0]) == sizeof(elf_fpreg_t))
+ err = fpr_get_fpa(target, &pos, &count, &kbuf, &ubuf);
+ else
+ err = fpr_get_msa(target, &pos, &count, &kbuf, &ubuf);
++ if (err)
++ return err;
++
++ err = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
++ &target->thread.fpu.fcr31,
++ fcr31_pos, fcr31_pos + sizeof(u32));
+
+ return err;
+ }
+@@ -460,7 +470,7 @@ static int fpr_get(struct task_struct *t
+ /*
+ * Copy the supplied NT_PRFPREG buffer to the floating-point context,
+ * !CONFIG_CPU_HAS_MSA variant. Buffer slots correspond 1:1 to FP
+- * context's general register slots.
++ * context's general register slots. Only general registers are copied.
+ */
+ static int fpr_set_fpa(struct task_struct *target,
+ unsigned int *pos, unsigned int *count,
+@@ -468,13 +478,14 @@ static int fpr_set_fpa(struct task_struc
+ {
+ return user_regset_copyin(pos, count, kbuf, ubuf,
+ &target->thread.fpu,
+- 0, sizeof(elf_fpregset_t));
++ 0, NUM_FPU_REGS * sizeof(elf_fpreg_t));
+ }
+
+ /*
+ * Copy the supplied NT_PRFPREG buffer to the floating-point context,
+ * CONFIG_CPU_HAS_MSA variant. Buffer slots are copied to lower 64
+- * bits only of FP context's general register slots.
++ * bits only of FP context's general register slots. Only general
++ * registers are copied.
+ */
+ static int fpr_set_msa(struct task_struct *target,
+ unsigned int *pos, unsigned int *count,
+@@ -499,6 +510,8 @@ static int fpr_set_msa(struct task_struc
+
+ /*
+ * Copy the supplied NT_PRFPREG buffer to the floating-point context.
++ * Choose the appropriate helper for general registers, and then copy
++ * the FCSR register separately.
+ *
+ * We optimize for the case where `count % sizeof(elf_fpreg_t) == 0',
+ * which is supposed to have been guaranteed by the kernel before
+@@ -511,16 +524,28 @@ static int fpr_set(struct task_struct *t
+ unsigned int pos, unsigned int count,
+ const void *kbuf, const void __user *ubuf)
+ {
++ const int fcr31_pos = NUM_FPU_REGS * sizeof(elf_fpreg_t);
++ u32 fcr31;
+ int err;
+
+ BUG_ON(count % sizeof(elf_fpreg_t));
+
+- /* XXX fcr31 */
+-
+ if (sizeof(target->thread.fpu.fpr[0]) == sizeof(elf_fpreg_t))
+ err = fpr_set_fpa(target, &pos, &count, &kbuf, &ubuf);
+ else
+ err = fpr_set_msa(target, &pos, &count, &kbuf, &ubuf);
++ if (err)
++ return err;
++
++ if (count > 0) {
++ err = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
++ &fcr31,
++ fcr31_pos, fcr31_pos + sizeof(u32));
++ if (err)
++ return err;
++
++ target->thread.fpu.fcr31 = fcr31 & ~FPU_CSR_ALL_X;
++ }
+
+ return err;
+ }
--- /dev/null
+From dc24d0edf33c3e15099688b6bbdf7bdc24bf6e91 Mon Sep 17 00:00:00 2001
+From: "Maciej W. Rozycki" <macro@mips.com>
+Date: Mon, 11 Dec 2017 22:52:15 +0000
+Subject: MIPS: Guard against any partial write attempt with PTRACE_SETREGSET
+
+From: Maciej W. Rozycki <macro@mips.com>
+
+commit dc24d0edf33c3e15099688b6bbdf7bdc24bf6e91 upstream.
+
+Complement commit d614fd58a283 ("mips/ptrace: Preserve previous
+registers for short regset write") and ensure that no partial register
+write attempt is made with PTRACE_SETREGSET, as we do not preinitialize
+any temporaries used to hold incoming register data and consequently
+random data could be written.
+
+It is the responsibility of the caller, such as `ptrace_regset', to
+arrange for writes to span whole registers only, so here we only assert
+that it has indeed happened.
+
+Signed-off-by: Maciej W. Rozycki <macro@mips.com>
+Fixes: 72b22bbad1e7 ("MIPS: Don't assume 64-bit FP registers for FP regset")
+Cc: James Hogan <james.hogan@mips.com>
+Cc: Paul Burton <Paul.Burton@mips.com>
+Cc: Alex Smith <alex@alex-smith.me.uk>
+Cc: Dave Martin <Dave.Martin@arm.com>
+Cc: linux-mips@linux-mips.org
+Cc: linux-kernel@vger.kernel.org
+Patchwork: https://patchwork.linux-mips.org/patch/17926/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/kernel/ptrace.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+--- a/arch/mips/kernel/ptrace.c
++++ b/arch/mips/kernel/ptrace.c
+@@ -497,7 +497,15 @@ static int fpr_set_msa(struct task_struc
+ return 0;
+ }
+
+-/* Copy the supplied NT_PRFPREG buffer to the floating-point context. */
++/*
++ * Copy the supplied NT_PRFPREG buffer to the floating-point context.
++ *
++ * We optimize for the case where `count % sizeof(elf_fpreg_t) == 0',
++ * which is supposed to have been guaranteed by the kernel before
++ * calling us, e.g. in `ptrace_regset'. We enforce that requirement,
++ * so that we can safely avoid preinitializing temporaries for
++ * partial register writes.
++ */
+ static int fpr_set(struct task_struct *target,
+ const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+@@ -505,6 +513,8 @@ static int fpr_set(struct task_struct *t
+ {
+ int err;
+
++ BUG_ON(count % sizeof(elf_fpreg_t));
++
+ /* XXX fcr31 */
+
+ if (sizeof(target->thread.fpu.fpr[0]) == sizeof(elf_fpreg_t))
input-elantech-add-new-icbody-type-15.patch
can-gs_usb-fix-return-value-of-the-set_bittiming-callback.patch
ib-srpt-disable-rdma-access-by-the-initiator.patch
+mips-factor-out-nt_prfpreg-regset-access-helpers.patch
+mips-guard-against-any-partial-write-attempt-with-ptrace_setregset.patch
+mips-consistently-handle-buffer-counter-with-ptrace_setregset.patch
+mips-fix-an-fcsr-access-api-regression-with-nt_prfpreg-and-msa.patch
+mips-disallow-outsized-ptrace_setregset-nt_prfpreg-regset-accesses.patch
mips-also-verify-sizeof-elf_fpreg_t-with-ptrace_setregset.patch
perf-core-fix-concurrent-sys_perf_event_open-vs.-move_group-race.patch
kvm-vmx-scrub-hardware-gprs-at-vm-exit.patch