diff options
author | David S. Miller <davem@davemloft.net> | 2016-08-15 18:08:18 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-10-24 14:31:58 -0400 |
commit | 0096ac9f47b1a2e851b3165d44065d18e5f13d58 (patch) | |
tree | ac30018b208a8236dac7f0d2b54262767e3cc18e /arch/sparc/lib | |
parent | 83a17d2661674d8c198adc0e183418f72aabab79 (diff) |
sparc64: Convert copy_in_user to accurate exception reporting.
Report the exact number of bytes which have not been successfully
copied when an exception occurs, using the running remaining length.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc/lib')
-rw-r--r-- | arch/sparc/lib/copy_in_user.S | 35 |
1 files changed, 25 insertions, 10 deletions
diff --git a/arch/sparc/lib/copy_in_user.S b/arch/sparc/lib/copy_in_user.S index 86e6663dd4e0..0252b218de45 100644 --- a/arch/sparc/lib/copy_in_user.S +++ b/arch/sparc/lib/copy_in_user.S | |||
@@ -9,18 +9,33 @@ | |||
9 | 9 | ||
10 | #define XCC xcc | 10 | #define XCC xcc |
11 | 11 | ||
12 | #define EX(x,y) \ | 12 | #define EX(x,y,z) \ |
13 | 98: x,y; \ | 13 | 98: x,y; \ |
14 | .section __ex_table,"a";\ | 14 | .section __ex_table,"a";\ |
15 | .align 4; \ | 15 | .align 4; \ |
16 | .word 98b, __retl_mone; \ | 16 | .word 98b, z; \ |
17 | .text; \ | 17 | .text; \ |
18 | .align 4; | 18 | .align 4; |
19 | 19 | ||
20 | #define EX_O4(x,y) EX(x,y,__retl_o4_plus_8) | ||
21 | #define EX_O2_4(x,y) EX(x,y,__retl_o2_plus_4) | ||
22 | #define EX_O2_1(x,y) EX(x,y,__retl_o2_plus_1) | ||
23 | |||
20 | .register %g2,#scratch | 24 | .register %g2,#scratch |
21 | .register %g3,#scratch | 25 | .register %g3,#scratch |
22 | 26 | ||
23 | .text | 27 | .text |
28 | __retl_o4_plus_8: | ||
29 | add %o4, %o2, %o4 | ||
30 | retl | ||
31 | add %o4, 8, %o0 | ||
32 | __retl_o2_plus_4: | ||
33 | retl | ||
34 | add %o2, 4, %o0 | ||
35 | __retl_o2_plus_1: | ||
36 | retl | ||
37 | add %o2, 1, %o0 | ||
38 | |||
24 | .align 32 | 39 | .align 32 |
25 | 40 | ||
26 | /* Don't try to get too fancy here, just nice and | 41 | /* Don't try to get too fancy here, just nice and |
@@ -45,8 +60,8 @@ ENTRY(___copy_in_user) /* %o0=dst, %o1=src, %o2=len */ | |||
45 | andn %o2, 0x7, %o4 | 60 | andn %o2, 0x7, %o4 |
46 | and %o2, 0x7, %o2 | 61 | and %o2, 0x7, %o2 |
47 | 1: subcc %o4, 0x8, %o4 | 62 | 1: subcc %o4, 0x8, %o4 |
48 | EX(ldxa [%o1] %asi, %o5) | 63 | EX_O4(ldxa [%o1] %asi, %o5) |
49 | EX(stxa %o5, [%o0] %asi) | 64 | EX_O4(stxa %o5, [%o0] %asi) |
50 | add %o1, 0x8, %o1 | 65 | add %o1, 0x8, %o1 |
51 | bgu,pt %XCC, 1b | 66 | bgu,pt %XCC, 1b |
52 | add %o0, 0x8, %o0 | 67 | add %o0, 0x8, %o0 |
@@ -54,8 +69,8 @@ ENTRY(___copy_in_user) /* %o0=dst, %o1=src, %o2=len */ | |||
54 | be,pt %XCC, 1f | 69 | be,pt %XCC, 1f |
55 | nop | 70 | nop |
56 | sub %o2, 0x4, %o2 | 71 | sub %o2, 0x4, %o2 |
57 | EX(lduwa [%o1] %asi, %o5) | 72 | EX_O2_4(lduwa [%o1] %asi, %o5) |
58 | EX(stwa %o5, [%o0] %asi) | 73 | EX_O2_4(stwa %o5, [%o0] %asi) |
59 | add %o1, 0x4, %o1 | 74 | add %o1, 0x4, %o1 |
60 | add %o0, 0x4, %o0 | 75 | add %o0, 0x4, %o0 |
61 | 1: cmp %o2, 0 | 76 | 1: cmp %o2, 0 |
@@ -71,8 +86,8 @@ ENTRY(___copy_in_user) /* %o0=dst, %o1=src, %o2=len */ | |||
71 | 86 | ||
72 | 82: | 87 | 82: |
73 | subcc %o2, 4, %o2 | 88 | subcc %o2, 4, %o2 |
74 | EX(lduwa [%o1] %asi, %g1) | 89 | EX_O2_4(lduwa [%o1] %asi, %g1) |
75 | EX(stwa %g1, [%o0] %asi) | 90 | EX_O2_4(stwa %g1, [%o0] %asi) |
76 | add %o1, 4, %o1 | 91 | add %o1, 4, %o1 |
77 | bgu,pt %XCC, 82b | 92 | bgu,pt %XCC, 82b |
78 | add %o0, 4, %o0 | 93 | add %o0, 4, %o0 |
@@ -83,8 +98,8 @@ ENTRY(___copy_in_user) /* %o0=dst, %o1=src, %o2=len */ | |||
83 | .align 32 | 98 | .align 32 |
84 | 90: | 99 | 90: |
85 | subcc %o2, 1, %o2 | 100 | subcc %o2, 1, %o2 |
86 | EX(lduba [%o1] %asi, %g1) | 101 | EX_O2_1(lduba [%o1] %asi, %g1) |
87 | EX(stba %g1, [%o0] %asi) | 102 | EX_O2_1(stba %g1, [%o0] %asi) |
88 | add %o1, 1, %o1 | 103 | add %o1, 1, %o1 |
89 | bgu,pt %XCC, 90b | 104 | bgu,pt %XCC, 90b |
90 | add %o0, 1, %o0 | 105 | add %o0, 1, %o0 |