1559671e0SHuacai Chen/* SPDX-License-Identifier: GPL-2.0 */ 2559671e0SHuacai Chen/* 3559671e0SHuacai Chen * Copyright (C) 2020-2022 Loongson Technology Corporation Limited 4559671e0SHuacai Chen */ 5559671e0SHuacai Chen 655b46ff9SMasahiro Yamada#include <linux/export.h> 7a275a82dSHuacai Chen#include <asm/alternative-asm.h> 8559671e0SHuacai Chen#include <asm/asm.h> 9559671e0SHuacai Chen#include <asm/asmmacro.h> 10508f28c6SYouling Tang#include <asm/asm-extable.h> 11a275a82dSHuacai Chen#include <asm/cpu.h> 12559671e0SHuacai Chen#include <asm/regdef.h> 13559671e0SHuacai Chen 14a275a82dSHuacai ChenSYM_FUNC_START(__copy_user) 15559671e0SHuacai Chen /* 16a275a82dSHuacai Chen * Some CPUs support hardware unaligned access 17a275a82dSHuacai Chen */ 18a275a82dSHuacai Chen ALTERNATIVE "b __copy_user_generic", \ 19a275a82dSHuacai Chen "b __copy_user_fast", CPU_FEATURE_UAL 20a275a82dSHuacai ChenSYM_FUNC_END(__copy_user) 21a275a82dSHuacai Chen 22a275a82dSHuacai ChenEXPORT_SYMBOL(__copy_user) 23a275a82dSHuacai Chen 24a275a82dSHuacai Chen/* 25a275a82dSHuacai Chen * unsigned long __copy_user_generic(void *to, const void *from, size_t n) 26559671e0SHuacai Chen * 27559671e0SHuacai Chen * a0: to 28559671e0SHuacai Chen * a1: from 29559671e0SHuacai Chen * a2: n 30559671e0SHuacai Chen */ 31a275a82dSHuacai ChenSYM_FUNC_START(__copy_user_generic) 32559671e0SHuacai Chen beqz a2, 3f 33559671e0SHuacai Chen 34559671e0SHuacai Chen1: ld.b t0, a1, 0 35559671e0SHuacai Chen2: st.b t0, a0, 0 36559671e0SHuacai Chen addi.d a0, a0, 1 37559671e0SHuacai Chen addi.d a1, a1, 1 38559671e0SHuacai Chen addi.d a2, a2, -1 391fdb9a92SWANG Xuerui bgtz a2, 1b 40559671e0SHuacai Chen 41559671e0SHuacai Chen3: move a0, a2 42559671e0SHuacai Chen jr ra 43559671e0SHuacai Chen 44*937f6593SWeihao Li _asm_extable 1b, 3b 45*937f6593SWeihao Li _asm_extable 2b, 3b 46a275a82dSHuacai ChenSYM_FUNC_END(__copy_user_generic) 47559671e0SHuacai Chen 48a275a82dSHuacai Chen/* 49a275a82dSHuacai Chen * unsigned long __copy_user_fast(void *to, const void *from, unsigned long n) 50a275a82dSHuacai Chen * 51a275a82dSHuacai Chen * a0: to 52a275a82dSHuacai Chen * a1: from 53a275a82dSHuacai Chen * a2: n 54a275a82dSHuacai Chen */ 55a275a82dSHuacai ChenSYM_FUNC_START(__copy_user_fast) 568941e93cSWANG Rui sltui t0, a2, 9 578941e93cSWANG Rui bnez t0, .Lsmall 58a275a82dSHuacai Chen 598941e93cSWANG Rui0: ld.d t0, a1, 0 608941e93cSWANG Rui1: st.d t0, a0, 0 61*937f6593SWeihao Li add.d a3, a1, a2 62*937f6593SWeihao Li add.d a2, a0, a2 638941e93cSWANG Rui 648941e93cSWANG Rui /* align up destination address */ 658941e93cSWANG Rui andi t1, a0, 7 668941e93cSWANG Rui sub.d t0, zero, t1 678941e93cSWANG Rui addi.d t0, t0, 8 688941e93cSWANG Rui add.d a1, a1, t0 698941e93cSWANG Rui add.d a0, a0, t0 708941e93cSWANG Rui 718941e93cSWANG Rui addi.d a4, a3, -64 728941e93cSWANG Rui bgeu a1, a4, .Llt64 73a275a82dSHuacai Chen 74a275a82dSHuacai Chen /* copy 64 bytes at a time */ 758941e93cSWANG Rui.Lloop64: 768941e93cSWANG Rui2: ld.d t0, a1, 0 778941e93cSWANG Rui3: ld.d t1, a1, 8 788941e93cSWANG Rui4: ld.d t2, a1, 16 798941e93cSWANG Rui5: ld.d t3, a1, 24 808941e93cSWANG Rui6: ld.d t4, a1, 32 818941e93cSWANG Rui7: ld.d t5, a1, 40 828941e93cSWANG Rui8: ld.d t6, a1, 48 838941e93cSWANG Rui9: ld.d t7, a1, 56 848941e93cSWANG Rui10: st.d t0, a0, 0 858941e93cSWANG Rui11: st.d t1, a0, 8 868941e93cSWANG Rui12: st.d t2, a0, 16 878941e93cSWANG Rui13: st.d t3, a0, 24 888941e93cSWANG Rui14: st.d t4, a0, 32 898941e93cSWANG Rui15: st.d t5, a0, 40 908941e93cSWANG Rui16: st.d t6, a0, 48 918941e93cSWANG Rui17: st.d t7, a0, 56 92*937f6593SWeihao Li addi.d a1, a1, 64 938941e93cSWANG Rui addi.d a0, a0, 64 948941e93cSWANG Rui bltu a1, a4, .Lloop64 95a275a82dSHuacai Chen 96a275a82dSHuacai Chen /* copy the remaining bytes */ 978941e93cSWANG Rui.Llt64: 988941e93cSWANG Rui addi.d a4, a3, -32 998941e93cSWANG Rui bgeu a1, a4, .Llt32 1008941e93cSWANG Rui18: ld.d t0, a1, 0 1018941e93cSWANG Rui19: ld.d t1, a1, 8 1028941e93cSWANG Rui20: ld.d t2, a1, 16 1038941e93cSWANG Rui21: ld.d t3, a1, 24 1048941e93cSWANG Rui22: st.d t0, a0, 0 1058941e93cSWANG Rui23: st.d t1, a0, 8 1068941e93cSWANG Rui24: st.d t2, a0, 16 1078941e93cSWANG Rui25: st.d t3, a0, 24 108*937f6593SWeihao Li addi.d a1, a1, 32 1098941e93cSWANG Rui addi.d a0, a0, 32 1108941e93cSWANG Rui 1118941e93cSWANG Rui.Llt32: 1128941e93cSWANG Rui addi.d a4, a3, -16 1138941e93cSWANG Rui bgeu a1, a4, .Llt16 1148941e93cSWANG Rui26: ld.d t0, a1, 0 1158941e93cSWANG Rui27: ld.d t1, a1, 8 1168941e93cSWANG Rui28: st.d t0, a0, 0 1178941e93cSWANG Rui29: st.d t1, a0, 8 118*937f6593SWeihao Li addi.d a1, a1, 16 1198941e93cSWANG Rui addi.d a0, a0, 16 1208941e93cSWANG Rui 1218941e93cSWANG Rui.Llt16: 1228941e93cSWANG Rui addi.d a4, a3, -8 1238941e93cSWANG Rui bgeu a1, a4, .Llt8 1248941e93cSWANG Rui30: ld.d t0, a1, 0 1258941e93cSWANG Rui31: st.d t0, a0, 0 126*937f6593SWeihao Li addi.d a1, a1, 8 127e66d511fSWANG Rui addi.d a0, a0, 8 1288941e93cSWANG Rui 1298941e93cSWANG Rui.Llt8: 1308941e93cSWANG Rui32: ld.d t0, a3, -8 1318941e93cSWANG Rui33: st.d t0, a2, -8 132a275a82dSHuacai Chen 133a275a82dSHuacai Chen /* return */ 1348941e93cSWANG Rui move a0, zero 1358941e93cSWANG Rui jr ra 1368941e93cSWANG Rui 1378941e93cSWANG Rui .align 5 1388941e93cSWANG Rui.Lsmall: 1398941e93cSWANG Rui pcaddi t0, 8 1408941e93cSWANG Rui slli.d a3, a2, 5 1418941e93cSWANG Rui add.d t0, t0, a3 1428941e93cSWANG Rui jr t0 1438941e93cSWANG Rui 1448941e93cSWANG Rui .align 5 1458941e93cSWANG Rui move a0, zero 1468941e93cSWANG Rui jr ra 1478941e93cSWANG Rui 1488941e93cSWANG Rui .align 5 1498941e93cSWANG Rui34: ld.b t0, a1, 0 1508941e93cSWANG Rui35: st.b t0, a0, 0 1518941e93cSWANG Rui move a0, zero 1528941e93cSWANG Rui jr ra 1538941e93cSWANG Rui 1548941e93cSWANG Rui .align 5 1558941e93cSWANG Rui36: ld.h t0, a1, 0 1568941e93cSWANG Rui37: st.h t0, a0, 0 1578941e93cSWANG Rui move a0, zero 1588941e93cSWANG Rui jr ra 1598941e93cSWANG Rui 1608941e93cSWANG Rui .align 5 1618941e93cSWANG Rui38: ld.h t0, a1, 0 1628941e93cSWANG Rui39: ld.b t1, a1, 2 1638941e93cSWANG Rui40: st.h t0, a0, 0 1648941e93cSWANG Rui41: st.b t1, a0, 2 1658941e93cSWANG Rui move a0, zero 1668941e93cSWANG Rui jr ra 1678941e93cSWANG Rui 1688941e93cSWANG Rui .align 5 1698941e93cSWANG Rui42: ld.w t0, a1, 0 1708941e93cSWANG Rui43: st.w t0, a0, 0 1718941e93cSWANG Rui move a0, zero 1728941e93cSWANG Rui jr ra 1738941e93cSWANG Rui 1748941e93cSWANG Rui .align 5 1758941e93cSWANG Rui44: ld.w t0, a1, 0 1768941e93cSWANG Rui45: ld.b t1, a1, 4 1778941e93cSWANG Rui46: st.w t0, a0, 0 1788941e93cSWANG Rui47: st.b t1, a0, 4 1798941e93cSWANG Rui move a0, zero 1808941e93cSWANG Rui jr ra 1818941e93cSWANG Rui 1828941e93cSWANG Rui .align 5 1838941e93cSWANG Rui48: ld.w t0, a1, 0 1848941e93cSWANG Rui49: ld.h t1, a1, 4 1858941e93cSWANG Rui50: st.w t0, a0, 0 1868941e93cSWANG Rui51: st.h t1, a0, 4 1878941e93cSWANG Rui move a0, zero 1888941e93cSWANG Rui jr ra 1898941e93cSWANG Rui 1908941e93cSWANG Rui .align 5 1918941e93cSWANG Rui52: ld.w t0, a1, 0 1928941e93cSWANG Rui53: ld.w t1, a1, 3 1938941e93cSWANG Rui54: st.w t0, a0, 0 1948941e93cSWANG Rui55: st.w t1, a0, 3 1958941e93cSWANG Rui move a0, zero 1968941e93cSWANG Rui jr ra 1978941e93cSWANG Rui 1988941e93cSWANG Rui .align 5 1998941e93cSWANG Rui56: ld.d t0, a1, 0 2008941e93cSWANG Rui57: st.d t0, a0, 0 2018941e93cSWANG Rui move a0, zero 202a275a82dSHuacai Chen jr ra 203a275a82dSHuacai Chen 204a275a82dSHuacai Chen /* fixup and ex_table */ 205*937f6593SWeihao Li.Llarge_fixup: 206*937f6593SWeihao Li sub.d a2, a2, a0 207*937f6593SWeihao Li 208*937f6593SWeihao Li.Lsmall_fixup: 209*937f6593SWeihao Li58: ld.b t0, a1, 0 210*937f6593SWeihao Li59: st.b t0, a0, 0 211*937f6593SWeihao Li addi.d a0, a0, 1 212*937f6593SWeihao Li addi.d a1, a1, 1 213*937f6593SWeihao Li addi.d a2, a2, -1 214*937f6593SWeihao Li bgt a2, zero, 58b 215*937f6593SWeihao Li 216*937f6593SWeihao Li.Lexit: 217*937f6593SWeihao Li move a0, a2 218*937f6593SWeihao Li jr ra 219*937f6593SWeihao Li 220*937f6593SWeihao Li _asm_extable 0b, .Lsmall_fixup 221*937f6593SWeihao Li _asm_extable 1b, .Lsmall_fixup 222*937f6593SWeihao Li _asm_extable 2b, .Llarge_fixup 223*937f6593SWeihao Li _asm_extable 3b, .Llarge_fixup 224*937f6593SWeihao Li _asm_extable 4b, .Llarge_fixup 225*937f6593SWeihao Li _asm_extable 5b, .Llarge_fixup 226*937f6593SWeihao Li _asm_extable 6b, .Llarge_fixup 227*937f6593SWeihao Li _asm_extable 7b, .Llarge_fixup 228*937f6593SWeihao Li _asm_extable 8b, .Llarge_fixup 229*937f6593SWeihao Li _asm_extable 9b, .Llarge_fixup 230*937f6593SWeihao Li _asm_extable 10b, .Llarge_fixup 231*937f6593SWeihao Li _asm_extable 11b, .Llarge_fixup 232*937f6593SWeihao Li _asm_extable 12b, .Llarge_fixup 233*937f6593SWeihao Li _asm_extable 13b, .Llarge_fixup 234*937f6593SWeihao Li _asm_extable 14b, .Llarge_fixup 235*937f6593SWeihao Li _asm_extable 15b, .Llarge_fixup 236*937f6593SWeihao Li _asm_extable 16b, .Llarge_fixup 237*937f6593SWeihao Li _asm_extable 17b, .Llarge_fixup 238*937f6593SWeihao Li _asm_extable 18b, .Llarge_fixup 239*937f6593SWeihao Li _asm_extable 19b, .Llarge_fixup 240*937f6593SWeihao Li _asm_extable 20b, .Llarge_fixup 241*937f6593SWeihao Li _asm_extable 21b, .Llarge_fixup 242*937f6593SWeihao Li _asm_extable 22b, .Llarge_fixup 243*937f6593SWeihao Li _asm_extable 23b, .Llarge_fixup 244*937f6593SWeihao Li _asm_extable 24b, .Llarge_fixup 245*937f6593SWeihao Li _asm_extable 25b, .Llarge_fixup 246*937f6593SWeihao Li _asm_extable 26b, .Llarge_fixup 247*937f6593SWeihao Li _asm_extable 27b, .Llarge_fixup 248*937f6593SWeihao Li _asm_extable 28b, .Llarge_fixup 249*937f6593SWeihao Li _asm_extable 29b, .Llarge_fixup 250*937f6593SWeihao Li _asm_extable 30b, .Llarge_fixup 251*937f6593SWeihao Li _asm_extable 31b, .Llarge_fixup 252*937f6593SWeihao Li _asm_extable 32b, .Llarge_fixup 253*937f6593SWeihao Li _asm_extable 33b, .Llarge_fixup 254*937f6593SWeihao Li _asm_extable 34b, .Lexit 255*937f6593SWeihao Li _asm_extable 35b, .Lexit 256*937f6593SWeihao Li _asm_extable 36b, .Lsmall_fixup 257*937f6593SWeihao Li _asm_extable 37b, .Lsmall_fixup 258*937f6593SWeihao Li _asm_extable 38b, .Lsmall_fixup 259*937f6593SWeihao Li _asm_extable 39b, .Lsmall_fixup 260*937f6593SWeihao Li _asm_extable 40b, .Lsmall_fixup 261*937f6593SWeihao Li _asm_extable 41b, .Lsmall_fixup 262*937f6593SWeihao Li _asm_extable 42b, .Lsmall_fixup 263*937f6593SWeihao Li _asm_extable 43b, .Lsmall_fixup 264*937f6593SWeihao Li _asm_extable 44b, .Lsmall_fixup 265*937f6593SWeihao Li _asm_extable 45b, .Lsmall_fixup 266*937f6593SWeihao Li _asm_extable 46b, .Lsmall_fixup 267*937f6593SWeihao Li _asm_extable 47b, .Lsmall_fixup 268*937f6593SWeihao Li _asm_extable 48b, .Lsmall_fixup 269*937f6593SWeihao Li _asm_extable 49b, .Lsmall_fixup 270*937f6593SWeihao Li _asm_extable 50b, .Lsmall_fixup 271*937f6593SWeihao Li _asm_extable 51b, .Lsmall_fixup 272*937f6593SWeihao Li _asm_extable 52b, .Lsmall_fixup 273*937f6593SWeihao Li _asm_extable 53b, .Lsmall_fixup 274*937f6593SWeihao Li _asm_extable 54b, .Lsmall_fixup 275*937f6593SWeihao Li _asm_extable 55b, .Lsmall_fixup 276*937f6593SWeihao Li _asm_extable 56b, .Lsmall_fixup 277*937f6593SWeihao Li _asm_extable 57b, .Lsmall_fixup 278*937f6593SWeihao Li _asm_extable 58b, .Lexit 279*937f6593SWeihao Li _asm_extable 59b, .Lexit 280a275a82dSHuacai ChenSYM_FUNC_END(__copy_user_fast) 281