There are some features which need this string operation for compilation,
like KASAN. So the purpose of this porting is for the features like KASAN
which cannot be compiled without it.

KASAN's string operations would replace the original string operations and
call for the architecture defined string operations. Since we don't have
this in current kernel, this patch provides the implementation.

This porting refers to the 'arch/nds32/lib/memmove.S'.

Signed-off-by: Nick Hu <nic...@andestech.com>
---
 arch/riscv/include/asm/string.h |    3 ++
 arch/riscv/kernel/riscv_ksyms.c |    1 +
 arch/riscv/lib/Makefile         |    1 +
 arch/riscv/lib/memmove.S        |   63 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 68 insertions(+), 0 deletions(-)
 create mode 100644 arch/riscv/lib/memmove.S

diff --git a/arch/riscv/include/asm/string.h b/arch/riscv/include/asm/string.h
index 1b5d445..11210f1 100644
--- a/arch/riscv/include/asm/string.h
+++ b/arch/riscv/include/asm/string.h
@@ -15,4 +15,7 @@
 #define __HAVE_ARCH_MEMCPY
 extern asmlinkage void *memcpy(void *, const void *, size_t);
 
+#define __HAVE_ARCH_MEMMOVE
+extern asmlinkage void *memmove(void *, const void *, size_t);
+
 #endif /* _ASM_RISCV_STRING_H */
diff --git a/arch/riscv/kernel/riscv_ksyms.c b/arch/riscv/kernel/riscv_ksyms.c
index 4800cf7..ffabaf1 100644
--- a/arch/riscv/kernel/riscv_ksyms.c
+++ b/arch/riscv/kernel/riscv_ksyms.c
@@ -14,3 +14,4 @@
 EXPORT_SYMBOL(__asm_copy_from_user);
 EXPORT_SYMBOL(memset);
 EXPORT_SYMBOL(memcpy);
+EXPORT_SYMBOL(memmove);
diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile
index 8e364eb..9a4d5b3 100644
--- a/arch/riscv/lib/Makefile
+++ b/arch/riscv/lib/Makefile
@@ -2,6 +2,7 @@
 lib-y  += delay.o
 lib-y  += memcpy.o
 lib-y  += memset.o
+lib-y  += memmove.o
 lib-y  += uaccess.o
 
 lib-$(CONFIG_64BIT) += tishift.o
diff --git a/arch/riscv/lib/memmove.S b/arch/riscv/lib/memmove.S
new file mode 100644
index 0000000..3657a06
--- /dev/null
+++ b/arch/riscv/lib/memmove.S
@@ -0,0 +1,63 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#include <linux/linkage.h>
+#include <asm/asm.h>
+
+ENTRY(memmove)
+       move    t0, a0
+       move    t1, a1
+
+       beq     a0, a1, exit_memcpy
+       beqz    a2, exit_memcpy
+       srli    t2, a2, 0x2
+
+       slt     t3, a0, a1
+       beqz    t3, do_reverse
+
+       andi    a2, a2, 0x3
+       li      t4, 1
+       beqz    t2, byte_copy
+
+word_copy:
+       lw      t3, 0(a1)
+       addi    t2, t2, -1
+       addi    a1, a1, 4
+       sw      t3, 0(a0)
+       addi    a0, a0, 4
+       bnez    t2, word_copy
+       beqz    a2, exit_memcpy
+       j       byte_copy
+
+do_reverse:
+       add     a0, a0, a2
+       add     a1, a1, a2
+       andi    a2, a2, 0x3
+       li      t4, -1
+       beqz    t2, reverse_byte_copy
+
+reverse_word_copy:
+       addi    a1, a1, -4
+       addi    t2, t2, -1
+       lw      t3, 0(a1)
+       addi    a0, a0, -4
+       sw      t3, 0(a0)
+       bnez    t2, reverse_word_copy
+       beqz    a2, exit_memcpy
+
+reverse_byte_copy:
+       addi    a0, a0, -1
+       addi    a1, a1, -1
+byte_copy:
+       lb      t3, 0(a1)
+       addi    a2, a2, -1
+       sb      t3, 0(a0)
+       add     a1, a1, t4
+       add     a0, a0, t4
+       bnez    a2, byte_copy
+
+exit_memcpy:
+       move a0, t0
+       move a1, t1
+       ret
+
+END(memmove)
-- 
1.7.1

Reply via email to