Merge branch 'acpi-pm'
[platform/kernel/linux-rpi.git] / lib / test_string.c
1 // SPDX-License-Identifier: GPL-2.0-only
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)
39                 return (i << 24) | (j << 16) | k | 0x8000;
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)
75                 return (i << 24) | (j << 16) | k | 0x8000;
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)
111                 return (i << 24) | (j << 16) | k | 0x8000;
112         return 0;
113 }
114
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
182 static __init int string_selftest_init(void)
183 {
184         int test, subtest;
185
186         test = 1;
187         subtest = memset16_selftest();
188         if (subtest)
189                 goto fail;
190
191         test = 2;
192         subtest = memset32_selftest();
193         if (subtest)
194                 goto fail;
195
196         test = 3;
197         subtest = memset64_selftest();
198         if (subtest)
199                 goto fail;
200
201         test = 4;
202         subtest = strchr_selftest();
203         if (subtest)
204                 goto fail;
205
206         test = 5;
207         subtest = strnchr_selftest();
208         if (subtest)
209                 goto fail;
210
211         pr_info("String selftests succeeded\n");
212         return 0;
213 fail:
214         pr_crit("String selftest failure %d.%08x\n", test, subtest);
215         return 0;
216 }
217
218 module_init(string_selftest_init);
219 MODULE_LICENSE("GPL v2");