^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * arch/alpha/lib/copy_user.S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copy to/from user space, handling exceptions as we go.. This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * isn't exactly pretty.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * This is essentially the same as "memcpy()", but with a few twists.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Notably, we have to make sure that $0 is always up-to-date and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * contains the right "bytes left to copy" value (and that it is updated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * only _after_ a successful copy). There is also some rather minor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * exception setup stuff..
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <asm/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) /* Allow an exception for an insn; exit if we get one. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define EXI(x,y...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) 99: x,##y; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) .section __ex_table,"a"; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) .long 99b - .; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) lda $31, $exitin-99b($31); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) .previous
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define EXO(x,y...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) 99: x,##y; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) .section __ex_table,"a"; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) .long 99b - .; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) lda $31, $exitout-99b($31); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) .previous
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) .set noat
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) .align 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) .globl __copy_user
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) .ent __copy_user
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) __copy_user:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) .prologue 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) mov $18,$0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) and $16,7,$3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) beq $0,$35
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) beq $3,$36
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) subq $3,8,$3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) .align 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) $37:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) EXI( ldq_u $1,0($17) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) EXO( ldq_u $2,0($16) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) extbl $1,$17,$1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) mskbl $2,$16,$2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) insbl $1,$16,$1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) addq $3,1,$3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) bis $1,$2,$1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) EXO( stq_u $1,0($16) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) subq $0,1,$0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) addq $16,1,$16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) addq $17,1,$17
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) beq $0,$41
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) bne $3,$37
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) $36:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) and $17,7,$1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) bic $0,7,$4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) beq $1,$43
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) beq $4,$48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) EXI( ldq_u $3,0($17) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) .align 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) $50:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) EXI( ldq_u $2,8($17) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) subq $4,8,$4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) extql $3,$17,$3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) extqh $2,$17,$1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) bis $3,$1,$1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) EXO( stq $1,0($16) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) addq $17,8,$17
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) subq $0,8,$0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) addq $16,8,$16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) bis $2,$2,$3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) bne $4,$50
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) $48:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) beq $0,$41
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) .align 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) $57:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) EXI( ldq_u $1,0($17) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) EXO( ldq_u $2,0($16) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) extbl $1,$17,$1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) mskbl $2,$16,$2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) insbl $1,$16,$1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) bis $1,$2,$1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) EXO( stq_u $1,0($16) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) subq $0,1,$0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) addq $16,1,$16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) addq $17,1,$17
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) bne $0,$57
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) br $31,$41
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) .align 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) $43:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) beq $4,$65
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) .align 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) $66:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) EXI( ldq $1,0($17) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) subq $4,8,$4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) EXO( stq $1,0($16) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) addq $17,8,$17
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) subq $0,8,$0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) addq $16,8,$16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) bne $4,$66
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) $65:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) beq $0,$41
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) EXI( ldq $2,0($17) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) EXO( ldq $1,0($16) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) mskql $2,$0,$2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) mskqh $1,$0,$1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) bis $2,$1,$2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) EXO( stq $2,0($16) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) bis $31,$31,$0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) $41:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) $35:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) $exitin:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) $exitout:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) ret $31,($26),1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) .end __copy_user
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) EXPORT_SYMBOL(__copy_user)