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