]>
Commit | Line | Data |
---|---|---|
09c434b8 | 1 | // SPDX-License-Identifier: GPL-2.0-only |
d6b28e09 GU |
2 | #include <linux/module.h> |
3 | #include <linux/printk.h> | |
4 | #include <linux/slab.h> | |
5 | #include <linux/string.h> | |
6 | ||
7 | static __init int memset16_selftest(void) | |
8 | { | |
9 | unsigned i, j, k; | |
10 | u16 v, *p; | |
11 | ||
12 | p = kmalloc(256 * 2 * 2, GFP_KERNEL); | |
13 | if (!p) | |
14 | return -1; | |
15 | ||
16 | for (i = 0; i < 256; i++) { | |
17 | for (j = 0; j < 256; j++) { | |
18 | memset(p, 0xa1, 256 * 2 * sizeof(v)); | |
19 | memset16(p + i, 0xb1b2, j); | |
20 | for (k = 0; k < 512; k++) { | |
21 | v = p[k]; | |
22 | if (k < i) { | |
23 | if (v != 0xa1a1) | |
24 | goto fail; | |
25 | } else if (k < i + j) { | |
26 | if (v != 0xb1b2) | |
27 | goto fail; | |
28 | } else { | |
29 | if (v != 0xa1a1) | |
30 | goto fail; | |
31 | } | |
32 | } | |
33 | } | |
34 | } | |
35 | ||
36 | fail: | |
37 | kfree(p); | |
38 | if (i < 256) | |
33d6e0ff | 39 | return (i << 24) | (j << 16) | k | 0x8000; |
d6b28e09 GU |
40 | return 0; |
41 | } | |
42 | ||
43 | static __init int memset32_selftest(void) | |
44 | { | |
45 | unsigned i, j, k; | |
46 | u32 v, *p; | |
47 | ||
48 | p = kmalloc(256 * 2 * 4, GFP_KERNEL); | |
49 | if (!p) | |
50 | return -1; | |
51 | ||
52 | for (i = 0; i < 256; i++) { | |
53 | for (j = 0; j < 256; j++) { | |
54 | memset(p, 0xa1, 256 * 2 * sizeof(v)); | |
55 | memset32(p + i, 0xb1b2b3b4, j); | |
56 | for (k = 0; k < 512; k++) { | |
57 | v = p[k]; | |
58 | if (k < i) { | |
59 | if (v != 0xa1a1a1a1) | |
60 | goto fail; | |
61 | } else if (k < i + j) { | |
62 | if (v != 0xb1b2b3b4) | |
63 | goto fail; | |
64 | } else { | |
65 | if (v != 0xa1a1a1a1) | |
66 | goto fail; | |
67 | } | |
68 | } | |
69 | } | |
70 | } | |
71 | ||
72 | fail: | |
73 | kfree(p); | |
74 | if (i < 256) | |
33d6e0ff | 75 | return (i << 24) | (j << 16) | k | 0x8000; |
d6b28e09 GU |
76 | return 0; |
77 | } | |
78 | ||
79 | static __init int memset64_selftest(void) | |
80 | { | |
81 | unsigned i, j, k; | |
82 | u64 v, *p; | |
83 | ||
84 | p = kmalloc(256 * 2 * 8, GFP_KERNEL); | |
85 | if (!p) | |
86 | return -1; | |
87 | ||
88 | for (i = 0; i < 256; i++) { | |
89 | for (j = 0; j < 256; j++) { | |
90 | memset(p, 0xa1, 256 * 2 * sizeof(v)); | |
91 | memset64(p + i, 0xb1b2b3b4b5b6b7b8ULL, j); | |
92 | for (k = 0; k < 512; k++) { | |
93 | v = p[k]; | |
94 | if (k < i) { | |
95 | if (v != 0xa1a1a1a1a1a1a1a1ULL) | |
96 | goto fail; | |
97 | } else if (k < i + j) { | |
98 | if (v != 0xb1b2b3b4b5b6b7b8ULL) | |
99 | goto fail; | |
100 | } else { | |
101 | if (v != 0xa1a1a1a1a1a1a1a1ULL) | |
102 | goto fail; | |
103 | } | |
104 | } | |
105 | } | |
106 | } | |
107 | ||
108 | fail: | |
109 | kfree(p); | |
110 | if (i < 256) | |
33d6e0ff | 111 | return (i << 24) | (j << 16) | k | 0x8000; |
d6b28e09 GU |
112 | return 0; |
113 | } | |
114 | ||
d1a5dc5e PR |
115 | static __init int strchr_selftest(void) |
116 | { | |
117 | const char *test_string = "abcdefghijkl"; | |
118 | const char *empty_string = ""; | |
119 | char *result; | |
120 | int i; | |
121 | ||
122 | for (i = 0; i < strlen(test_string) + 1; i++) { | |
123 | result = strchr(test_string, test_string[i]); | |
124 | if (result - test_string != i) | |
125 | return i + 'a'; | |
126 | } | |
127 | ||
128 | result = strchr(empty_string, '\0'); | |
129 | if (result != empty_string) | |
130 | return 0x101; | |
131 | ||
132 | result = strchr(empty_string, 'a'); | |
133 | if (result) | |
134 | return 0x102; | |
135 | ||
136 | result = strchr(test_string, 'z'); | |
137 | if (result) | |
138 | return 0x103; | |
139 | ||
140 | return 0; | |
141 | } | |
142 | ||
143 | static __init int strnchr_selftest(void) | |
144 | { | |
145 | const char *test_string = "abcdefghijkl"; | |
146 | const char *empty_string = ""; | |
147 | char *result; | |
148 | int i, j; | |
149 | ||
150 | for (i = 0; i < strlen(test_string) + 1; i++) { | |
151 | for (j = 0; j < strlen(test_string) + 2; j++) { | |
152 | result = strnchr(test_string, j, test_string[i]); | |
153 | if (j <= i) { | |
154 | if (!result) | |
155 | continue; | |
156 | return ((i + 'a') << 8) | j; | |
157 | } | |
158 | if (result - test_string != i) | |
159 | return ((i + 'a') << 8) | j; | |
160 | } | |
161 | } | |
162 | ||
163 | result = strnchr(empty_string, 0, '\0'); | |
164 | if (result) | |
165 | return 0x10001; | |
166 | ||
167 | result = strnchr(empty_string, 1, '\0'); | |
168 | if (result != empty_string) | |
169 | return 0x10002; | |
170 | ||
171 | result = strnchr(empty_string, 1, 'a'); | |
172 | if (result) | |
173 | return 0x10003; | |
174 | ||
175 | result = strnchr(NULL, 0, '\0'); | |
176 | if (result) | |
177 | return 0x10004; | |
178 | ||
179 | return 0; | |
180 | } | |
181 | ||
e0fa2ab3 RV |
182 | static __init int strspn_selftest(void) |
183 | { | |
184 | static const struct strspn_test { | |
185 | const char str[16]; | |
186 | const char accept[16]; | |
187 | const char reject[16]; | |
188 | unsigned a; | |
189 | unsigned r; | |
190 | } tests[] __initconst = { | |
191 | { "foobar", "", "", 0, 6 }, | |
192 | { "abba", "abc", "ABBA", 4, 4 }, | |
193 | { "abba", "a", "b", 1, 1 }, | |
194 | { "", "abc", "abc", 0, 0}, | |
195 | }; | |
196 | const struct strspn_test *s = tests; | |
197 | size_t i, res; | |
198 | ||
199 | for (i = 0; i < ARRAY_SIZE(tests); ++i, ++s) { | |
200 | res = strspn(s->str, s->accept); | |
201 | if (res != s->a) | |
202 | return 0x100 + 2*i; | |
203 | res = strcspn(s->str, s->reject); | |
204 | if (res != s->r) | |
205 | return 0x100 + 2*i + 1; | |
206 | } | |
207 | return 0; | |
208 | } | |
209 | ||
ce71efd0 MC |
210 | static __exit void string_selftest_remove(void) |
211 | { | |
212 | } | |
213 | ||
d6b28e09 GU |
214 | static __init int string_selftest_init(void) |
215 | { | |
216 | int test, subtest; | |
217 | ||
218 | test = 1; | |
219 | subtest = memset16_selftest(); | |
220 | if (subtest) | |
221 | goto fail; | |
222 | ||
223 | test = 2; | |
224 | subtest = memset32_selftest(); | |
225 | if (subtest) | |
226 | goto fail; | |
227 | ||
228 | test = 3; | |
229 | subtest = memset64_selftest(); | |
230 | if (subtest) | |
231 | goto fail; | |
232 | ||
d1a5dc5e PR |
233 | test = 4; |
234 | subtest = strchr_selftest(); | |
235 | if (subtest) | |
236 | goto fail; | |
237 | ||
238 | test = 5; | |
239 | subtest = strnchr_selftest(); | |
240 | if (subtest) | |
241 | goto fail; | |
242 | ||
e0fa2ab3 RV |
243 | test = 6; |
244 | subtest = strspn_selftest(); | |
245 | if (subtest) | |
246 | goto fail; | |
247 | ||
d6b28e09 GU |
248 | pr_info("String selftests succeeded\n"); |
249 | return 0; | |
250 | fail: | |
251 | pr_crit("String selftest failure %d.%08x\n", test, subtest); | |
252 | return 0; | |
253 | } | |
254 | ||
255 | module_init(string_selftest_init); | |
ce71efd0 | 256 | module_exit(string_selftest_remove); |
d6b28e09 | 257 | MODULE_LICENSE("GPL v2"); |