Commit | Line | Data |
---|---|---|
b2441318 | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
51533b61 MS |
2 | /* |
3 | * Add-on to transform csum_partial_copy_nocheck in checksumcopy.S into | |
4 | * csum_partial_copy_from_user by adding exception records. | |
5 | * | |
6 | * Copyright (C) 2001, 2003 Axis Communications AB. | |
7 | * | |
8 | * Author: Hans-Peter Nilsson. | |
9 | */ | |
10 | ||
11 | #include <asm/errno.h> | |
12 | ||
13 | /* Same function body, but a different name. If we just added exception | |
14 | records to _csum_partial_copy_nocheck and made it generic, we wouldn't | |
15 | know a user fault from a kernel fault and we would have overhead in | |
16 | each kernel caller for the error-pointer argument. | |
17 | ||
18 | unsigned int csum_partial_copy_from_user | |
19 | (const char *src, char *dst, int len, unsigned int sum, int *errptr); | |
20 | ||
21 | Note that the errptr argument is only set if we encounter an error. | |
22 | It is conveniently located on the stack, so the normal function body | |
23 | does not have to handle it. */ | |
24 | ||
25 | #define csum_partial_copy_nocheck csum_partial_copy_from_user | |
26 | ||
27 | /* There are local labels numbered 1, 2 and 3 present to mark the | |
28 | different from-user accesses. */ | |
29 | #include "checksumcopy.S" | |
30 | ||
31 | .section .fixup,"ax" | |
32 | ||
33 | ;; Here from the movem loop; restore stack. | |
34 | 4: | |
35 | movem [$sp+],$r8 | |
36 | ;; r12 is already decremented. Add back chunk_size-2. | |
37 | addq 40-2,$r12 | |
38 | ||
39 | ;; Here from the word loop; r12 is off by 2; add it back. | |
40 | 5: | |
41 | addq 2,$r12 | |
42 | ||
43 | ;; Here from a failing single byte. | |
44 | 6: | |
45 | ||
46 | ;; Signal in *errptr that we had a failing access. | |
47 | move.d [$sp],$acr | |
48 | moveq -EFAULT,$r9 | |
49 | subq 4,$sp | |
50 | move.d $r9,[$acr] | |
51 | ||
52 | ;; Clear the rest of the destination area using memset. Preserve the | |
53 | ;; checksum for the readable bytes. | |
54 | move.d $r13,[$sp] | |
55 | subq 4,$sp | |
56 | move.d $r11,$r10 | |
57 | move $srp,[$sp] | |
58 | jsr memset | |
59 | clear.d $r11 | |
60 | ||
61 | move [$sp+],$srp | |
62 | ret | |
63 | move.d [$sp+],$r10 | |
64 | ||
65 | .previous | |
66 | .section __ex_table,"a" | |
67 | .dword 1b,4b | |
68 | .dword 2b,5b | |
69 | .dword 3b,6b | |
70 | .previous |