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