aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/mips/kernel/mips_ksyms.c6
-rw-r--r--arch/mips/lib/memcpy.S77
2 files changed, 83 insertions, 0 deletions
diff --git a/arch/mips/kernel/mips_ksyms.c b/arch/mips/kernel/mips_ksyms.c
index 675bd0578d3f..13e60f676b8b 100644
--- a/arch/mips/kernel/mips_ksyms.c
+++ b/arch/mips/kernel/mips_ksyms.c
@@ -51,6 +51,12 @@ EXPORT_SYMBOL(copy_page);
51 */ 51 */
52EXPORT_SYMBOL(__copy_user); 52EXPORT_SYMBOL(__copy_user);
53EXPORT_SYMBOL(__copy_user_inatomic); 53EXPORT_SYMBOL(__copy_user_inatomic);
54#ifdef CONFIG_EVA
55EXPORT_SYMBOL(__copy_from_user_eva);
56EXPORT_SYMBOL(__copy_in_user_eva);
57EXPORT_SYMBOL(__copy_to_user_eva);
58EXPORT_SYMBOL(__copy_user_inatomic_eva);
59#endif
54EXPORT_SYMBOL(__bzero); 60EXPORT_SYMBOL(__bzero);
55EXPORT_SYMBOL(__strncpy_from_kernel_nocheck_asm); 61EXPORT_SYMBOL(__strncpy_from_kernel_nocheck_asm);
56EXPORT_SYMBOL(__strncpy_from_kernel_asm); 62EXPORT_SYMBOL(__strncpy_from_kernel_asm);
diff --git a/arch/mips/lib/memcpy.S b/arch/mips/lib/memcpy.S
index d630a28a118b..c17ef80cf65a 100644
--- a/arch/mips/lib/memcpy.S
+++ b/arch/mips/lib/memcpy.S
@@ -114,7 +114,24 @@
114 .section __ex_table,"a"; \ 114 .section __ex_table,"a"; \
115 PTR 9b, handler; \ 115 PTR 9b, handler; \
116 .previous; \ 116 .previous; \
117 /* This is assembled in EVA mode */ \
118 .else; \
119 /* If loading from user or storing to user */ \
120 .if ((\from == USEROP) && (type == LD_INSN)) || \
121 ((\to == USEROP) && (type == ST_INSN)); \
1229: __BUILD_EVA_INSN(insn##e, reg, addr); \
123 .section __ex_table,"a"; \
124 PTR 9b, handler; \
125 .previous; \
126 .else; \
127 /* \
128 * Still in EVA, but no need for \
129 * exception handler or EVA insn \
130 */ \
131 insn reg, addr; \
132 .endif; \
117 .endif 133 .endif
134
118/* 135/*
119 * Only on the 64-bit kernel we can made use of 64-bit registers. 136 * Only on the 64-bit kernel we can made use of 64-bit registers.
120 */ 137 */
@@ -186,6 +203,22 @@
186#define _PREF(hint, addr, type) \ 203#define _PREF(hint, addr, type) \
187 .if \mode == LEGACY_MODE; \ 204 .if \mode == LEGACY_MODE; \
188 PREF(hint, addr); \ 205 PREF(hint, addr); \
206 .else; \
207 .if ((\from == USEROP) && (type == SRC_PREFETCH)) || \
208 ((\to == USEROP) && (type == DST_PREFETCH)); \
209 /* \
210 * PREFE has only 9 bits for the offset \
211 * compared to PREF which has 16, so it may \
212 * need to use the $at register but this \
213 * register should remain intact because it's \
214 * used later on. Therefore use $v1. \
215 */ \
216 .set at=v1; \
217 PREFE(hint, addr); \
218 .set noat; \
219 .else; \
220 PREF(hint, addr); \
221 .endif; \
189 .endif 222 .endif
190 223
191#define PREFS(hint, addr) _PREF(hint, addr, SRC_PREFETCH) 224#define PREFS(hint, addr) _PREF(hint, addr, SRC_PREFETCH)
@@ -636,3 +669,47 @@ FEXPORT(__copy_user)
636__copy_user_common: 669__copy_user_common:
637 /* Legacy Mode, user <-> user */ 670 /* Legacy Mode, user <-> user */
638 __BUILD_COPY_USER LEGACY_MODE USEROP USEROP 671 __BUILD_COPY_USER LEGACY_MODE USEROP USEROP
672
673#ifdef CONFIG_EVA
674
675/*
676 * For EVA we need distinct symbols for reading and writing to user space.
677 * This is because we need to use specific EVA instructions to perform the
678 * virtual <-> physical translation when a virtual address is actually in user
679 * space
680 */
681
682LEAF(__copy_user_inatomic_eva)
683 b __copy_from_user_common
684 li t6, 1
685 END(__copy_user_inatomic_eva)
686
687/*
688 * __copy_from_user (EVA)
689 */
690
691LEAF(__copy_from_user_eva)
692 li t6, 0 /* not inatomic */
693__copy_from_user_common:
694 __BUILD_COPY_USER EVA_MODE USEROP KERNELOP
695END(__copy_from_user_eva)
696
697
698
699/*
700 * __copy_to_user (EVA)
701 */
702
703LEAF(__copy_to_user_eva)
704__BUILD_COPY_USER EVA_MODE KERNELOP USEROP
705END(__copy_to_user_eva)
706
707/*
708 * __copy_in_user (EVA)
709 */
710
711LEAF(__copy_in_user_eva)
712__BUILD_COPY_USER EVA_MODE USEROP USEROP
713END(__copy_in_user_eva)
714
715#endif