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> 13*cb8a2ef0STiezhu Yang#include <asm/unwind_hints.h> 14559671e0SHuacai Chen 15a275a82dSHuacai ChenSYM_FUNC_START(__clear_user) 16559671e0SHuacai Chen /* 17a275a82dSHuacai Chen * Some CPUs support hardware unaligned access 18a275a82dSHuacai Chen */ 19a275a82dSHuacai Chen ALTERNATIVE "b __clear_user_generic", \ 20a275a82dSHuacai Chen "b __clear_user_fast", CPU_FEATURE_UAL 21a275a82dSHuacai ChenSYM_FUNC_END(__clear_user) 22a275a82dSHuacai Chen 23a275a82dSHuacai ChenEXPORT_SYMBOL(__clear_user) 24a275a82dSHuacai Chen 25a275a82dSHuacai Chen/* 26a275a82dSHuacai Chen * unsigned long __clear_user_generic(void *addr, size_t size) 27559671e0SHuacai Chen * 28559671e0SHuacai Chen * a0: addr 29559671e0SHuacai Chen * a1: size 30559671e0SHuacai Chen */ 31a275a82dSHuacai ChenSYM_FUNC_START(__clear_user_generic) 32559671e0SHuacai Chen beqz a1, 2f 33559671e0SHuacai Chen 34559671e0SHuacai Chen1: st.b zero, a0, 0 35559671e0SHuacai Chen addi.d a0, a0, 1 36559671e0SHuacai Chen addi.d a1, a1, -1 371fdb9a92SWANG Xuerui bgtz a1, 1b 38559671e0SHuacai Chen 39559671e0SHuacai Chen2: move a0, a1 40559671e0SHuacai Chen jr ra 41559671e0SHuacai Chen 42937f6593SWeihao Li _asm_extable 1b, 2b 43a275a82dSHuacai ChenSYM_FUNC_END(__clear_user_generic) 44559671e0SHuacai Chen 45a275a82dSHuacai Chen/* 46a275a82dSHuacai Chen * unsigned long __clear_user_fast(void *addr, unsigned long size) 47a275a82dSHuacai Chen * 48a275a82dSHuacai Chen * a0: addr 49a275a82dSHuacai Chen * a1: size 50a275a82dSHuacai Chen */ 51a275a82dSHuacai ChenSYM_FUNC_START(__clear_user_fast) 528941e93cSWANG Rui sltui t0, a1, 9 538941e93cSWANG Rui bnez t0, .Lsmall 54a275a82dSHuacai Chen 558941e93cSWANG Rui add.d a2, a0, a1 568941e93cSWANG Rui0: st.d zero, a0, 0 578941e93cSWANG Rui 588941e93cSWANG Rui /* align up address */ 598941e93cSWANG Rui addi.d a0, a0, 8 608941e93cSWANG Rui bstrins.d a0, zero, 2, 0 618941e93cSWANG Rui 628941e93cSWANG Rui addi.d a3, a2, -64 638941e93cSWANG Rui bgeu a0, a3, .Llt64 64a275a82dSHuacai Chen 65a275a82dSHuacai Chen /* set 64 bytes at a time */ 668941e93cSWANG Rui.Lloop64: 67a275a82dSHuacai Chen1: st.d zero, a0, 0 68a275a82dSHuacai Chen2: st.d zero, a0, 8 69a275a82dSHuacai Chen3: st.d zero, a0, 16 70a275a82dSHuacai Chen4: st.d zero, a0, 24 71a275a82dSHuacai Chen5: st.d zero, a0, 32 72a275a82dSHuacai Chen6: st.d zero, a0, 40 73a275a82dSHuacai Chen7: st.d zero, a0, 48 74a275a82dSHuacai Chen8: st.d zero, a0, 56 75a275a82dSHuacai Chen addi.d a0, a0, 64 768941e93cSWANG Rui bltu a0, a3, .Lloop64 77a275a82dSHuacai Chen 78a275a82dSHuacai Chen /* set the remaining bytes */ 798941e93cSWANG Rui.Llt64: 808941e93cSWANG Rui addi.d a3, a2, -32 818941e93cSWANG Rui bgeu a0, a3, .Llt32 828941e93cSWANG Rui9: st.d zero, a0, 0 838941e93cSWANG Rui10: st.d zero, a0, 8 848941e93cSWANG Rui11: st.d zero, a0, 16 858941e93cSWANG Rui12: st.d zero, a0, 24 868941e93cSWANG Rui addi.d a0, a0, 32 878941e93cSWANG Rui 888941e93cSWANG Rui.Llt32: 898941e93cSWANG Rui addi.d a3, a2, -16 908941e93cSWANG Rui bgeu a0, a3, .Llt16 918941e93cSWANG Rui13: st.d zero, a0, 0 928941e93cSWANG Rui14: st.d zero, a0, 8 938941e93cSWANG Rui addi.d a0, a0, 16 948941e93cSWANG Rui 958941e93cSWANG Rui.Llt16: 968941e93cSWANG Rui addi.d a3, a2, -8 978941e93cSWANG Rui bgeu a0, a3, .Llt8 988941e93cSWANG Rui15: st.d zero, a0, 0 99e66d511fSWANG Rui addi.d a0, a0, 8 1008941e93cSWANG Rui 1018941e93cSWANG Rui.Llt8: 1028941e93cSWANG Rui16: st.d zero, a2, -8 103a275a82dSHuacai Chen 104a275a82dSHuacai Chen /* return */ 1058941e93cSWANG Rui move a0, zero 1068941e93cSWANG Rui jr ra 1078941e93cSWANG Rui 1088941e93cSWANG Rui .align 4 1098941e93cSWANG Rui.Lsmall: 1108941e93cSWANG Rui pcaddi t0, 4 1118941e93cSWANG Rui slli.d a2, a1, 4 1128941e93cSWANG Rui add.d t0, t0, a2 1138941e93cSWANG Rui jr t0 1148941e93cSWANG Rui 1158941e93cSWANG Rui .align 4 1168941e93cSWANG Rui move a0, zero 1178941e93cSWANG Rui jr ra 1188941e93cSWANG Rui 1198941e93cSWANG Rui .align 4 1208941e93cSWANG Rui17: st.b zero, a0, 0 1218941e93cSWANG Rui move a0, zero 1228941e93cSWANG Rui jr ra 1238941e93cSWANG Rui 1248941e93cSWANG Rui .align 4 1258941e93cSWANG Rui18: st.h zero, a0, 0 1268941e93cSWANG Rui move a0, zero 1278941e93cSWANG Rui jr ra 1288941e93cSWANG Rui 1298941e93cSWANG Rui .align 4 1308941e93cSWANG Rui19: st.h zero, a0, 0 1318941e93cSWANG Rui20: st.b zero, a0, 2 1328941e93cSWANG Rui move a0, zero 1338941e93cSWANG Rui jr ra 1348941e93cSWANG Rui 1358941e93cSWANG Rui .align 4 1368941e93cSWANG Rui21: st.w zero, a0, 0 1378941e93cSWANG Rui move a0, zero 1388941e93cSWANG Rui jr ra 1398941e93cSWANG Rui 1408941e93cSWANG Rui .align 4 1418941e93cSWANG Rui22: st.w zero, a0, 0 1428941e93cSWANG Rui23: st.b zero, a0, 4 1438941e93cSWANG Rui move a0, zero 1448941e93cSWANG Rui jr ra 1458941e93cSWANG Rui 1468941e93cSWANG Rui .align 4 1478941e93cSWANG Rui24: st.w zero, a0, 0 1488941e93cSWANG Rui25: st.h zero, a0, 4 1498941e93cSWANG Rui move a0, zero 1508941e93cSWANG Rui jr ra 1518941e93cSWANG Rui 1528941e93cSWANG Rui .align 4 1538941e93cSWANG Rui26: st.w zero, a0, 0 1548941e93cSWANG Rui27: st.w zero, a0, 3 1558941e93cSWANG Rui move a0, zero 1568941e93cSWANG Rui jr ra 1578941e93cSWANG Rui 1588941e93cSWANG Rui .align 4 1598941e93cSWANG Rui28: st.d zero, a0, 0 1608941e93cSWANG Rui move a0, zero 161a275a82dSHuacai Chen jr ra 162a275a82dSHuacai Chen 163a275a82dSHuacai Chen /* fixup and ex_table */ 164937f6593SWeihao Li.Llarge_fixup: 165937f6593SWeihao Li sub.d a1, a2, a0 166937f6593SWeihao Li 167937f6593SWeihao Li.Lsmall_fixup: 168937f6593SWeihao Li29: st.b zero, a0, 0 169937f6593SWeihao Li addi.d a0, a0, 1 170937f6593SWeihao Li addi.d a1, a1, -1 171937f6593SWeihao Li bgt a1, zero, 29b 172937f6593SWeihao Li 173937f6593SWeihao Li.Lexit: 174937f6593SWeihao Li move a0, a1 175937f6593SWeihao Li jr ra 176937f6593SWeihao Li 177937f6593SWeihao Li _asm_extable 0b, .Lsmall_fixup 178937f6593SWeihao Li _asm_extable 1b, .Llarge_fixup 179937f6593SWeihao Li _asm_extable 2b, .Llarge_fixup 180937f6593SWeihao Li _asm_extable 3b, .Llarge_fixup 181937f6593SWeihao Li _asm_extable 4b, .Llarge_fixup 182937f6593SWeihao Li _asm_extable 5b, .Llarge_fixup 183937f6593SWeihao Li _asm_extable 6b, .Llarge_fixup 184937f6593SWeihao Li _asm_extable 7b, .Llarge_fixup 185937f6593SWeihao Li _asm_extable 8b, .Llarge_fixup 186937f6593SWeihao Li _asm_extable 9b, .Llarge_fixup 187937f6593SWeihao Li _asm_extable 10b, .Llarge_fixup 188937f6593SWeihao Li _asm_extable 11b, .Llarge_fixup 189937f6593SWeihao Li _asm_extable 12b, .Llarge_fixup 190937f6593SWeihao Li _asm_extable 13b, .Llarge_fixup 191937f6593SWeihao Li _asm_extable 14b, .Llarge_fixup 192937f6593SWeihao Li _asm_extable 15b, .Llarge_fixup 193937f6593SWeihao Li _asm_extable 16b, .Llarge_fixup 194937f6593SWeihao Li _asm_extable 17b, .Lexit 195937f6593SWeihao Li _asm_extable 18b, .Lsmall_fixup 196937f6593SWeihao Li _asm_extable 19b, .Lsmall_fixup 197937f6593SWeihao Li _asm_extable 20b, .Lsmall_fixup 198937f6593SWeihao Li _asm_extable 21b, .Lsmall_fixup 199937f6593SWeihao Li _asm_extable 22b, .Lsmall_fixup 200937f6593SWeihao Li _asm_extable 23b, .Lsmall_fixup 201937f6593SWeihao Li _asm_extable 24b, .Lsmall_fixup 202937f6593SWeihao Li _asm_extable 25b, .Lsmall_fixup 203937f6593SWeihao Li _asm_extable 26b, .Lsmall_fixup 204937f6593SWeihao Li _asm_extable 27b, .Lsmall_fixup 205937f6593SWeihao Li _asm_extable 28b, .Lsmall_fixup 206937f6593SWeihao Li _asm_extable 29b, .Lexit 207a275a82dSHuacai ChenSYM_FUNC_END(__clear_user_fast) 208*cb8a2ef0STiezhu Yang 209*cb8a2ef0STiezhu YangSTACK_FRAME_NON_STANDARD __clear_user_fast 210