aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarkos Chandras <markos.chandras@imgtec.com>2014-11-17 04:30:23 -0500
committerRalf Baechle <ralf@linux-mips.org>2014-11-19 12:22:08 -0500
commit58563817cfed0432e9a54476d5fc6c3aeba475e4 (patch)
tree3c0becc2bde0f5b98b7bbbe482d615247dfafa8b
parentbbaf113a481b6ce32444c125807ad3618643ce57 (diff)
MIPS: asm: uaccess: Add v1 register to clobber list on EVA
When EVA is turned on and prefetching is being used in memcpy.S, the v1 register is being used as a helper register to the PREFE instruction. However, v1 ($3) was not in the clobber list, which means that the compiler did not preserve it across function calls, and that could corrupt the value of the register leading to all sorts of userland crashes. We fix this problem by using the DADDI_SCRATCH macro to define the clobbered register when CONFIG_EVA && CONFIG_CPU_HAS_PREFETCH are enabled. Signed-off-by: Markos Chandras <markos.chandras@imgtec.com> Cc: <stable@vger.kernel.org> # v3.15+ Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/8510/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-rw-r--r--arch/mips/include/asm/uaccess.h7
1 files changed, 4 insertions, 3 deletions
diff --git a/arch/mips/include/asm/uaccess.h b/arch/mips/include/asm/uaccess.h
index a10951090234..b9ab717e3619 100644
--- a/arch/mips/include/asm/uaccess.h
+++ b/arch/mips/include/asm/uaccess.h
@@ -773,10 +773,11 @@ extern void __put_user_unaligned_unknown(void);
773 "jal\t" #destination "\n\t" 773 "jal\t" #destination "\n\t"
774#endif 774#endif
775 775
776#ifndef CONFIG_CPU_DADDI_WORKAROUNDS 776#if defined(CONFIG_CPU_DADDI_WORKAROUNDS) || (defined(CONFIG_EVA) && \
777#define DADDI_SCRATCH "$0" 777 defined(CONFIG_CPU_HAS_PREFETCH))
778#else
779#define DADDI_SCRATCH "$3" 778#define DADDI_SCRATCH "$3"
779#else
780#define DADDI_SCRATCH "$0"
780#endif 781#endif
781 782
782extern size_t __copy_user(void *__to, const void *__from, size_t __n); 783extern size_t __copy_user(void *__to, const void *__from, size_t __n);