1 /* SPDX-License-Identifier: GPL-2.0-only */ !! 1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 2 /* 3 * Copyright (C) 2021 Arm Ltd. !! 3 * arch/alpha/lib/clear_user.S 4 */ !! 4 * Contributed by Richard Henderson <rth@tamu.edu> 5 !! 5 * 6 #include <linux/linkage.h> !! 6 * Zero user space, handling exceptions as we go. 7 #include <asm/asm-uaccess.h> << 8 << 9 .text << 10 << 11 /* Prototype: int __arch_clear_user(void *addr << 12 * Purpose : clear some user memory << 13 * Params : addr - user memory address to cl << 14 * : sz - number of bytes to clear << 15 * Returns : number of bytes NOT cleared << 16 * 7 * 17 * Alignment fixed up by hardware. !! 8 * We have to make sure that $0 is always up-to-date and contains the >> 9 * right "bytes left to zero" value (and that it is updated only _after_ >> 10 * a successful copy). There is also some rather minor exception setup >> 11 * stuff. 18 */ 12 */ >> 13 #include <linux/export.h> >> 14 >> 15 /* Allow an exception for an insn; exit if we get one. */ >> 16 #define EX(x,y...) \ >> 17 99: x,##y; \ >> 18 .section __ex_table,"a"; \ >> 19 .long 99b - .; \ >> 20 lda $31, $exception-99b($31); \ >> 21 .previous >> 22 >> 23 .set noat >> 24 .set noreorder >> 25 .align 4 >> 26 >> 27 .globl __clear_user >> 28 .ent __clear_user >> 29 .frame $30, 0, $26 >> 30 .prologue 0 >> 31 >> 32 $loop: >> 33 and $1, 3, $4 # e0 : >> 34 beq $4, 1f # .. e1 : >> 35 >> 36 0: EX( stq_u $31, 0($16) ) # e0 : zero one word >> 37 subq $0, 8, $0 # .. e1 : >> 38 subq $4, 1, $4 # e0 : >> 39 addq $16, 8, $16 # .. e1 : >> 40 bne $4, 0b # e1 : >> 41 unop # : >> 42 >> 43 1: bic $1, 3, $1 # e0 : >> 44 beq $1, $tail # .. e1 : >> 45 >> 46 2: EX( stq_u $31, 0($16) ) # e0 : zero four words >> 47 subq $0, 8, $0 # .. e1 : >> 48 EX( stq_u $31, 8($16) ) # e0 : >> 49 subq $0, 8, $0 # .. e1 : >> 50 EX( stq_u $31, 16($16) ) # e0 : >> 51 subq $0, 8, $0 # .. e1 : >> 52 EX( stq_u $31, 24($16) ) # e0 : >> 53 subq $0, 8, $0 # .. e1 : >> 54 subq $1, 4, $1 # e0 : >> 55 addq $16, 32, $16 # .. e1 : >> 56 bne $1, 2b # e1 : >> 57 >> 58 $tail: >> 59 bne $2, 1f # e1 : is there a tail to do? >> 60 ret $31, ($26), 1 # .. e1 : >> 61 >> 62 1: EX( ldq_u $5, 0($16) ) # e0 : >> 63 clr $0 # .. e1 : >> 64 nop # e1 : >> 65 mskqh $5, $0, $5 # e0 : >> 66 EX( stq_u $5, 0($16) ) # e0 : >> 67 ret $31, ($26), 1 # .. e1 : >> 68 >> 69 __clear_user: >> 70 and $17, $17, $0 >> 71 and $16, 7, $4 # e0 : find dest misalignment >> 72 beq $0, $zerolength # .. e1 : >> 73 addq $0, $4, $1 # e0 : bias counter >> 74 and $1, 7, $2 # e1 : number of bytes in tail >> 75 srl $1, 3, $1 # e0 : >> 76 beq $4, $loop # .. e1 : >> 77 >> 78 EX( ldq_u $5, 0($16) ) # e0 : load dst word to mask back in >> 79 beq $1, $oneword # .. e1 : sub-word store? >> 80 >> 81 mskql $5, $16, $5 # e0 : take care of misaligned head >> 82 addq $16, 8, $16 # .. e1 : >> 83 EX( stq_u $5, -8($16) ) # e0 : >> 84 addq $0, $4, $0 # .. e1 : bytes left -= 8 - misalignment >> 85 subq $1, 1, $1 # e0 : >> 86 subq $0, 8, $0 # .. e1 : >> 87 br $loop # e1 : >> 88 unop # : >> 89 >> 90 $oneword: >> 91 mskql $5, $16, $4 # e0 : >> 92 mskqh $5, $2, $5 # e0 : >> 93 or $5, $4, $5 # e1 : >> 94 EX( stq_u $5, 0($16) ) # e0 : >> 95 clr $0 # .. e1 : >> 96 >> 97 $zerolength: >> 98 $exception: >> 99 ret $31, ($26), 1 # .. e1 : 19 100 20 .p2align 4 !! 101 .end __clear_user 21 // Alignment is for the loop, but sinc !! 102 EXPORT_SYMBOL(__clear_user) 22 // is also 16 bytes we can keep any pa << 23 SYM_FUNC_START(__arch_clear_user) << 24 add x2, x0, x1 << 25 subs x1, x1, #8 << 26 b.mi 2f << 27 1: << 28 USER(9f, sttr xzr, [x0]) << 29 add x0, x0, #8 << 30 subs x1, x1, #8 << 31 b.hi 1b << 32 USER(9f, sttr xzr, [x2, #-8]) << 33 mov x0, #0 << 34 ret << 35 << 36 2: tbz x1, #2, 3f << 37 USER(9f, sttr wzr, [x0]) << 38 USER(8f, sttr wzr, [x2, #-4]) << 39 mov x0, #0 << 40 ret << 41 << 42 3: tbz x1, #1, 4f << 43 USER(9f, sttrh wzr, [x0]) << 44 4: tbz x1, #0, 5f << 45 USER(7f, sttrb wzr, [x2, #-1]) << 46 5: mov x0, #0 << 47 ret << 48 << 49 // Exception fixups << 50 7: sub x0, x2, #5 // Adjust for << 51 8: add x0, x0, #4 // ...or the s << 52 9: sub x0, x2, x0 << 53 ret << 54 SYM_FUNC_END(__arch_clear_user) << 55 EXPORT_SYMBOL(__arch_clear_user) <<
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.