xref: /openbmc/linux/lib/test_bitmap.c (revision c900529f3d9161bfde5cca0754f83b4d3c3e0220)
109c434b8SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
25fd003f5SDavid Decotigny /*
3780ff33bSAndy Shevchenko  * Test cases for bitmap API.
45fd003f5SDavid Decotigny  */
55fd003f5SDavid Decotigny 
65fd003f5SDavid Decotigny #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
75fd003f5SDavid Decotigny 
85fd003f5SDavid Decotigny #include <linux/bitmap.h>
95fd003f5SDavid Decotigny #include <linux/init.h>
105fd003f5SDavid Decotigny #include <linux/kernel.h>
115fd003f5SDavid Decotigny #include <linux/module.h>
125fd003f5SDavid Decotigny #include <linux/printk.h>
135fd003f5SDavid Decotigny #include <linux/slab.h>
145fd003f5SDavid Decotigny #include <linux/string.h>
156ea86bdfSYury Norov #include <linux/uaccess.h>
165fd003f5SDavid Decotigny 
176b1a4d5bSTobin C. Harding #include "../tools/testing/selftests/kselftest_module.h"
186b1a4d5bSTobin C. Harding 
19e3783c80SYury Norov #define EXP1_IN_BITS	(sizeof(exp1) * 8)
20e3783c80SYury Norov 
214e89a787STimur Tabi KSTM_MODULE_GLOBALS();
225fd003f5SDavid Decotigny 
235fd003f5SDavid Decotigny static char pbl_buffer[PAGE_SIZE] __initdata;
24291f93caSBarry Song static char print_buf[PAGE_SIZE * 2] __initdata;
255fd003f5SDavid Decotigny 
26c21dd8a7SAndy Shevchenko static const unsigned long exp1[] __initconst = {
27c21dd8a7SAndy Shevchenko 	BITMAP_FROM_U64(1),
28c21dd8a7SAndy Shevchenko 	BITMAP_FROM_U64(2),
29c21dd8a7SAndy Shevchenko 	BITMAP_FROM_U64(0x0000ffff),
30c21dd8a7SAndy Shevchenko 	BITMAP_FROM_U64(0xffff0000),
31c21dd8a7SAndy Shevchenko 	BITMAP_FROM_U64(0x55555555),
32c21dd8a7SAndy Shevchenko 	BITMAP_FROM_U64(0xaaaaaaaa),
33c21dd8a7SAndy Shevchenko 	BITMAP_FROM_U64(0x11111111),
34c21dd8a7SAndy Shevchenko 	BITMAP_FROM_U64(0x22222222),
35c21dd8a7SAndy Shevchenko 	BITMAP_FROM_U64(0xffffffff),
36c21dd8a7SAndy Shevchenko 	BITMAP_FROM_U64(0xfffffffe),
37c21dd8a7SAndy Shevchenko 	BITMAP_FROM_U64(0x3333333311111111ULL),
38c21dd8a7SAndy Shevchenko 	BITMAP_FROM_U64(0xffffffff77777777ULL),
39c21dd8a7SAndy Shevchenko 	BITMAP_FROM_U64(0),
4097330db3SPaul Gortmaker 	BITMAP_FROM_U64(0x00008000),
4197330db3SPaul Gortmaker 	BITMAP_FROM_U64(0x80000000),
42c21dd8a7SAndy Shevchenko };
43c21dd8a7SAndy Shevchenko 
44c21dd8a7SAndy Shevchenko static const unsigned long exp2[] __initconst = {
45c21dd8a7SAndy Shevchenko 	BITMAP_FROM_U64(0x3333333311111111ULL),
46c21dd8a7SAndy Shevchenko 	BITMAP_FROM_U64(0xffffffff77777777ULL),
47c21dd8a7SAndy Shevchenko };
485fd003f5SDavid Decotigny 
4930544ed5SAndy Shevchenko /* Fibonacci sequence */
5030544ed5SAndy Shevchenko static const unsigned long exp2_to_exp3_mask[] __initconst = {
5130544ed5SAndy Shevchenko 	BITMAP_FROM_U64(0x008000020020212eULL),
5230544ed5SAndy Shevchenko };
5330544ed5SAndy Shevchenko /* exp3_0_1 = (exp2[0] & ~exp2_to_exp3_mask) | (exp2[1] & exp2_to_exp3_mask) */
5430544ed5SAndy Shevchenko static const unsigned long exp3_0_1[] __initconst = {
5530544ed5SAndy Shevchenko 	BITMAP_FROM_U64(0x33b3333311313137ULL),
5630544ed5SAndy Shevchenko };
5730544ed5SAndy Shevchenko /* exp3_1_0 = (exp2[1] & ~exp2_to_exp3_mask) | (exp2[0] & exp2_to_exp3_mask) */
5830544ed5SAndy Shevchenko static const unsigned long exp3_1_0[] __initconst = {
5930544ed5SAndy Shevchenko 	BITMAP_FROM_U64(0xff7fffff77575751ULL),
6030544ed5SAndy Shevchenko };
6130544ed5SAndy Shevchenko 
625fd003f5SDavid Decotigny static bool __init
__check_eq_uint(const char * srcfile,unsigned int line,const unsigned int exp_uint,unsigned int x)635fd003f5SDavid Decotigny __check_eq_uint(const char *srcfile, unsigned int line,
645fd003f5SDavid Decotigny 		const unsigned int exp_uint, unsigned int x)
655fd003f5SDavid Decotigny {
665fd003f5SDavid Decotigny 	if (exp_uint != x) {
673aa56885SYury Norov 		pr_err("[%s:%u] expected %u, got %u\n",
685fd003f5SDavid Decotigny 			srcfile, line, exp_uint, x);
695fd003f5SDavid Decotigny 		return false;
705fd003f5SDavid Decotigny 	}
715fd003f5SDavid Decotigny 	return true;
725fd003f5SDavid Decotigny }
735fd003f5SDavid Decotigny 
745fd003f5SDavid Decotigny 
755fd003f5SDavid Decotigny static bool __init
__check_eq_bitmap(const char * srcfile,unsigned int line,const unsigned long * exp_bmap,const unsigned long * bmap,unsigned int nbits)765fd003f5SDavid Decotigny __check_eq_bitmap(const char *srcfile, unsigned int line,
773aa56885SYury Norov 		  const unsigned long *exp_bmap, const unsigned long *bmap,
783aa56885SYury Norov 		  unsigned int nbits)
795fd003f5SDavid Decotigny {
805fd003f5SDavid Decotigny 	if (!bitmap_equal(exp_bmap, bmap, nbits)) {
815fd003f5SDavid Decotigny 		pr_warn("[%s:%u] bitmaps contents differ: expected \"%*pbl\", got \"%*pbl\"\n",
825fd003f5SDavid Decotigny 			srcfile, line,
833aa56885SYury Norov 			nbits, exp_bmap, nbits, bmap);
845fd003f5SDavid Decotigny 		return false;
855fd003f5SDavid Decotigny 	}
865fd003f5SDavid Decotigny 	return true;
875fd003f5SDavid Decotigny }
885fd003f5SDavid Decotigny 
895fd003f5SDavid Decotigny static bool __init
__check_eq_pbl(const char * srcfile,unsigned int line,const char * expected_pbl,const unsigned long * bitmap,unsigned int nbits)905fd003f5SDavid Decotigny __check_eq_pbl(const char *srcfile, unsigned int line,
915fd003f5SDavid Decotigny 	       const char *expected_pbl,
925fd003f5SDavid Decotigny 	       const unsigned long *bitmap, unsigned int nbits)
935fd003f5SDavid Decotigny {
945fd003f5SDavid Decotigny 	snprintf(pbl_buffer, sizeof(pbl_buffer), "%*pbl", nbits, bitmap);
955fd003f5SDavid Decotigny 	if (strcmp(expected_pbl, pbl_buffer)) {
965fd003f5SDavid Decotigny 		pr_warn("[%s:%u] expected \"%s\", got \"%s\"\n",
975fd003f5SDavid Decotigny 			srcfile, line,
985fd003f5SDavid Decotigny 			expected_pbl, pbl_buffer);
995fd003f5SDavid Decotigny 		return false;
1005fd003f5SDavid Decotigny 	}
1015fd003f5SDavid Decotigny 	return true;
1025fd003f5SDavid Decotigny }
1035fd003f5SDavid Decotigny 
1045fd003f5SDavid Decotigny static bool __init
1055fd003f5SDavid Decotigny __check_eq_u32_array(const char *srcfile, unsigned int line,
1065fd003f5SDavid Decotigny 		     const u32 *exp_arr, unsigned int exp_len,
1073aa56885SYury Norov 		     const u32 *arr, unsigned int len) __used;
1083aa56885SYury Norov static bool __init
__check_eq_u32_array(const char * srcfile,unsigned int line,const u32 * exp_arr,unsigned int exp_len,const u32 * arr,unsigned int len)1093aa56885SYury Norov __check_eq_u32_array(const char *srcfile, unsigned int line,
1103aa56885SYury Norov 		     const u32 *exp_arr, unsigned int exp_len,
1115fd003f5SDavid Decotigny 		     const u32 *arr, unsigned int len)
1125fd003f5SDavid Decotigny {
1135fd003f5SDavid Decotigny 	if (exp_len != len) {
1145fd003f5SDavid Decotigny 		pr_warn("[%s:%u] array length differ: expected %u, got %u\n",
1155fd003f5SDavid Decotigny 			srcfile, line,
1165fd003f5SDavid Decotigny 			exp_len, len);
1175fd003f5SDavid Decotigny 		return false;
1185fd003f5SDavid Decotigny 	}
1195fd003f5SDavid Decotigny 
1205fd003f5SDavid Decotigny 	if (memcmp(exp_arr, arr, len*sizeof(*arr))) {
1215fd003f5SDavid Decotigny 		pr_warn("[%s:%u] array contents differ\n", srcfile, line);
1225fd003f5SDavid Decotigny 		print_hex_dump(KERN_WARNING, "  exp:  ", DUMP_PREFIX_OFFSET,
1235fd003f5SDavid Decotigny 			       32, 4, exp_arr, exp_len*sizeof(*exp_arr), false);
1245fd003f5SDavid Decotigny 		print_hex_dump(KERN_WARNING, "  got:  ", DUMP_PREFIX_OFFSET,
1255fd003f5SDavid Decotigny 			       32, 4, arr, len*sizeof(*arr), false);
1265fd003f5SDavid Decotigny 		return false;
1275fd003f5SDavid Decotigny 	}
1285fd003f5SDavid Decotigny 
1295fd003f5SDavid Decotigny 	return true;
1305fd003f5SDavid Decotigny }
1315fd003f5SDavid Decotigny 
__check_eq_clump8(const char * srcfile,unsigned int line,const unsigned int offset,const unsigned int size,const unsigned char * const clump_exp,const unsigned long * const clump)132e4aa168dSWilliam Breathitt Gray static bool __init __check_eq_clump8(const char *srcfile, unsigned int line,
133e4aa168dSWilliam Breathitt Gray 				    const unsigned int offset,
134e4aa168dSWilliam Breathitt Gray 				    const unsigned int size,
135e4aa168dSWilliam Breathitt Gray 				    const unsigned char *const clump_exp,
136e4aa168dSWilliam Breathitt Gray 				    const unsigned long *const clump)
137e4aa168dSWilliam Breathitt Gray {
138e4aa168dSWilliam Breathitt Gray 	unsigned long exp;
139e4aa168dSWilliam Breathitt Gray 
140e4aa168dSWilliam Breathitt Gray 	if (offset >= size) {
141e4aa168dSWilliam Breathitt Gray 		pr_warn("[%s:%u] bit offset for clump out-of-bounds: expected less than %u, got %u\n",
142e4aa168dSWilliam Breathitt Gray 			srcfile, line, size, offset);
143e4aa168dSWilliam Breathitt Gray 		return false;
144e4aa168dSWilliam Breathitt Gray 	}
145e4aa168dSWilliam Breathitt Gray 
146e4aa168dSWilliam Breathitt Gray 	exp = clump_exp[offset / 8];
147e4aa168dSWilliam Breathitt Gray 	if (!exp) {
148e4aa168dSWilliam Breathitt Gray 		pr_warn("[%s:%u] bit offset for zero clump: expected nonzero clump, got bit offset %u with clump value 0",
149e4aa168dSWilliam Breathitt Gray 			srcfile, line, offset);
150e4aa168dSWilliam Breathitt Gray 		return false;
151e4aa168dSWilliam Breathitt Gray 	}
152e4aa168dSWilliam Breathitt Gray 
153e4aa168dSWilliam Breathitt Gray 	if (*clump != exp) {
154e4aa168dSWilliam Breathitt Gray 		pr_warn("[%s:%u] expected clump value of 0x%lX, got clump value of 0x%lX",
155e4aa168dSWilliam Breathitt Gray 			srcfile, line, exp, *clump);
156e4aa168dSWilliam Breathitt Gray 		return false;
157e4aa168dSWilliam Breathitt Gray 	}
158e4aa168dSWilliam Breathitt Gray 
159e4aa168dSWilliam Breathitt Gray 	return true;
160e4aa168dSWilliam Breathitt Gray }
161e4aa168dSWilliam Breathitt Gray 
162291f93caSBarry Song static bool __init
__check_eq_str(const char * srcfile,unsigned int line,const char * exp_str,const char * str,unsigned int len)163291f93caSBarry Song __check_eq_str(const char *srcfile, unsigned int line,
164291f93caSBarry Song 		const char *exp_str, const char *str,
165291f93caSBarry Song 		unsigned int len)
166291f93caSBarry Song {
167291f93caSBarry Song 	bool eq;
168291f93caSBarry Song 
169291f93caSBarry Song 	eq = strncmp(exp_str, str, len) == 0;
170291f93caSBarry Song 	if (!eq)
171291f93caSBarry Song 		pr_err("[%s:%u] expected %s, got %s\n", srcfile, line, exp_str, str);
172291f93caSBarry Song 
173291f93caSBarry Song 	return eq;
174291f93caSBarry Song }
175291f93caSBarry Song 
1765fd003f5SDavid Decotigny #define __expect_eq(suffix, ...)					\
1775fd003f5SDavid Decotigny 	({								\
1785fd003f5SDavid Decotigny 		int result = 0;						\
1795fd003f5SDavid Decotigny 		total_tests++;						\
1805fd003f5SDavid Decotigny 		if (!__check_eq_ ## suffix(__FILE__, __LINE__,		\
1815fd003f5SDavid Decotigny 					   ##__VA_ARGS__)) {		\
1825fd003f5SDavid Decotigny 			failed_tests++;					\
1835fd003f5SDavid Decotigny 			result = 1;					\
1845fd003f5SDavid Decotigny 		}							\
1855fd003f5SDavid Decotigny 		result;							\
1865fd003f5SDavid Decotigny 	})
1875fd003f5SDavid Decotigny 
1885fd003f5SDavid Decotigny #define expect_eq_uint(...)		__expect_eq(uint, ##__VA_ARGS__)
1895fd003f5SDavid Decotigny #define expect_eq_bitmap(...)		__expect_eq(bitmap, ##__VA_ARGS__)
1905fd003f5SDavid Decotigny #define expect_eq_pbl(...)		__expect_eq(pbl, ##__VA_ARGS__)
1915fd003f5SDavid Decotigny #define expect_eq_u32_array(...)	__expect_eq(u32_array, ##__VA_ARGS__)
192e4aa168dSWilliam Breathitt Gray #define expect_eq_clump8(...)		__expect_eq(clump8, ##__VA_ARGS__)
193291f93caSBarry Song #define expect_eq_str(...)		__expect_eq(str, ##__VA_ARGS__)
1945fd003f5SDavid Decotigny 
test_zero_clear(void)195ee3527bdSAndy Shevchenko static void __init test_zero_clear(void)
196ee3527bdSAndy Shevchenko {
197ee3527bdSAndy Shevchenko 	DECLARE_BITMAP(bmap, 1024);
198ee3527bdSAndy Shevchenko 
199ee3527bdSAndy Shevchenko 	/* Known way to set all bits */
200ee3527bdSAndy Shevchenko 	memset(bmap, 0xff, 128);
201ee3527bdSAndy Shevchenko 
202ee3527bdSAndy Shevchenko 	expect_eq_pbl("0-22", bmap, 23);
203ee3527bdSAndy Shevchenko 	expect_eq_pbl("0-1023", bmap, 1024);
204ee3527bdSAndy Shevchenko 
205ee3527bdSAndy Shevchenko 	/* single-word bitmaps */
206ee3527bdSAndy Shevchenko 	bitmap_clear(bmap, 0, 9);
207ee3527bdSAndy Shevchenko 	expect_eq_pbl("9-1023", bmap, 1024);
208ee3527bdSAndy Shevchenko 
209ee3527bdSAndy Shevchenko 	bitmap_zero(bmap, 35);
210ee3527bdSAndy Shevchenko 	expect_eq_pbl("64-1023", bmap, 1024);
211ee3527bdSAndy Shevchenko 
212ee3527bdSAndy Shevchenko 	/* cross boundaries operations */
213ee3527bdSAndy Shevchenko 	bitmap_clear(bmap, 79, 19);
214ee3527bdSAndy Shevchenko 	expect_eq_pbl("64-78,98-1023", bmap, 1024);
215ee3527bdSAndy Shevchenko 
216ee3527bdSAndy Shevchenko 	bitmap_zero(bmap, 115);
217ee3527bdSAndy Shevchenko 	expect_eq_pbl("128-1023", bmap, 1024);
218ee3527bdSAndy Shevchenko 
219ee3527bdSAndy Shevchenko 	/* Zeroing entire area */
220ee3527bdSAndy Shevchenko 	bitmap_zero(bmap, 1024);
221ee3527bdSAndy Shevchenko 	expect_eq_pbl("", bmap, 1024);
222ee3527bdSAndy Shevchenko }
223ee3527bdSAndy Shevchenko 
test_find_nth_bit(void)224e3783c80SYury Norov static void __init test_find_nth_bit(void)
225e3783c80SYury Norov {
226e3783c80SYury Norov 	unsigned long b, bit, cnt = 0;
227e3783c80SYury Norov 	DECLARE_BITMAP(bmap, 64 * 3);
228e3783c80SYury Norov 
229e3783c80SYury Norov 	bitmap_zero(bmap, 64 * 3);
230e3783c80SYury Norov 	__set_bit(10, bmap);
231e3783c80SYury Norov 	__set_bit(20, bmap);
232e3783c80SYury Norov 	__set_bit(30, bmap);
233e3783c80SYury Norov 	__set_bit(40, bmap);
234e3783c80SYury Norov 	__set_bit(50, bmap);
235e3783c80SYury Norov 	__set_bit(60, bmap);
236e3783c80SYury Norov 	__set_bit(80, bmap);
237e3783c80SYury Norov 	__set_bit(123, bmap);
238e3783c80SYury Norov 
239e3783c80SYury Norov 	expect_eq_uint(10,  find_nth_bit(bmap, 64 * 3, 0));
240e3783c80SYury Norov 	expect_eq_uint(20,  find_nth_bit(bmap, 64 * 3, 1));
241e3783c80SYury Norov 	expect_eq_uint(30,  find_nth_bit(bmap, 64 * 3, 2));
242e3783c80SYury Norov 	expect_eq_uint(40,  find_nth_bit(bmap, 64 * 3, 3));
243e3783c80SYury Norov 	expect_eq_uint(50,  find_nth_bit(bmap, 64 * 3, 4));
244e3783c80SYury Norov 	expect_eq_uint(60,  find_nth_bit(bmap, 64 * 3, 5));
245e3783c80SYury Norov 	expect_eq_uint(80,  find_nth_bit(bmap, 64 * 3, 6));
246e3783c80SYury Norov 	expect_eq_uint(123, find_nth_bit(bmap, 64 * 3, 7));
247e3783c80SYury Norov 	expect_eq_uint(64 * 3, find_nth_bit(bmap, 64 * 3, 8));
248e3783c80SYury Norov 
249e3783c80SYury Norov 	expect_eq_uint(10,  find_nth_bit(bmap, 64 * 3 - 1, 0));
250e3783c80SYury Norov 	expect_eq_uint(20,  find_nth_bit(bmap, 64 * 3 - 1, 1));
251e3783c80SYury Norov 	expect_eq_uint(30,  find_nth_bit(bmap, 64 * 3 - 1, 2));
252e3783c80SYury Norov 	expect_eq_uint(40,  find_nth_bit(bmap, 64 * 3 - 1, 3));
253e3783c80SYury Norov 	expect_eq_uint(50,  find_nth_bit(bmap, 64 * 3 - 1, 4));
254e3783c80SYury Norov 	expect_eq_uint(60,  find_nth_bit(bmap, 64 * 3 - 1, 5));
255e3783c80SYury Norov 	expect_eq_uint(80,  find_nth_bit(bmap, 64 * 3 - 1, 6));
256e3783c80SYury Norov 	expect_eq_uint(123, find_nth_bit(bmap, 64 * 3 - 1, 7));
257e3783c80SYury Norov 	expect_eq_uint(64 * 3 - 1, find_nth_bit(bmap, 64 * 3 - 1, 8));
258e3783c80SYury Norov 
259e3783c80SYury Norov 	for_each_set_bit(bit, exp1, EXP1_IN_BITS) {
260e3783c80SYury Norov 		b = find_nth_bit(exp1, EXP1_IN_BITS, cnt++);
261e3783c80SYury Norov 		expect_eq_uint(b, bit);
262e3783c80SYury Norov 	}
263e3783c80SYury Norov }
264e3783c80SYury Norov 
test_fill_set(void)265978f369cSAndy Shevchenko static void __init test_fill_set(void)
266978f369cSAndy Shevchenko {
267978f369cSAndy Shevchenko 	DECLARE_BITMAP(bmap, 1024);
268978f369cSAndy Shevchenko 
269978f369cSAndy Shevchenko 	/* Known way to clear all bits */
270978f369cSAndy Shevchenko 	memset(bmap, 0x00, 128);
271978f369cSAndy Shevchenko 
272978f369cSAndy Shevchenko 	expect_eq_pbl("", bmap, 23);
273978f369cSAndy Shevchenko 	expect_eq_pbl("", bmap, 1024);
274978f369cSAndy Shevchenko 
275978f369cSAndy Shevchenko 	/* single-word bitmaps */
276978f369cSAndy Shevchenko 	bitmap_set(bmap, 0, 9);
277978f369cSAndy Shevchenko 	expect_eq_pbl("0-8", bmap, 1024);
278978f369cSAndy Shevchenko 
279978f369cSAndy Shevchenko 	bitmap_fill(bmap, 35);
280978f369cSAndy Shevchenko 	expect_eq_pbl("0-63", bmap, 1024);
281978f369cSAndy Shevchenko 
282978f369cSAndy Shevchenko 	/* cross boundaries operations */
283978f369cSAndy Shevchenko 	bitmap_set(bmap, 79, 19);
284978f369cSAndy Shevchenko 	expect_eq_pbl("0-63,79-97", bmap, 1024);
285978f369cSAndy Shevchenko 
286978f369cSAndy Shevchenko 	bitmap_fill(bmap, 115);
287978f369cSAndy Shevchenko 	expect_eq_pbl("0-127", bmap, 1024);
288978f369cSAndy Shevchenko 
289978f369cSAndy Shevchenko 	/* Zeroing entire area */
290978f369cSAndy Shevchenko 	bitmap_fill(bmap, 1024);
291978f369cSAndy Shevchenko 	expect_eq_pbl("0-1023", bmap, 1024);
292978f369cSAndy Shevchenko }
293978f369cSAndy Shevchenko 
test_copy(void)294fe81814cSAndy Shevchenko static void __init test_copy(void)
2955fd003f5SDavid Decotigny {
2965fd003f5SDavid Decotigny 	DECLARE_BITMAP(bmap1, 1024);
2975fd003f5SDavid Decotigny 	DECLARE_BITMAP(bmap2, 1024);
2985fd003f5SDavid Decotigny 
2995fd003f5SDavid Decotigny 	bitmap_zero(bmap1, 1024);
3005fd003f5SDavid Decotigny 	bitmap_zero(bmap2, 1024);
3015fd003f5SDavid Decotigny 
3025fd003f5SDavid Decotigny 	/* single-word bitmaps */
303fe81814cSAndy Shevchenko 	bitmap_set(bmap1, 0, 19);
3045fd003f5SDavid Decotigny 	bitmap_copy(bmap2, bmap1, 23);
3055fd003f5SDavid Decotigny 	expect_eq_pbl("0-18", bmap2, 1024);
3065fd003f5SDavid Decotigny 
307fe81814cSAndy Shevchenko 	bitmap_set(bmap2, 0, 23);
3085fd003f5SDavid Decotigny 	bitmap_copy(bmap2, bmap1, 23);
3095fd003f5SDavid Decotigny 	expect_eq_pbl("0-18", bmap2, 1024);
3105fd003f5SDavid Decotigny 
3115fd003f5SDavid Decotigny 	/* multi-word bitmaps */
312fe81814cSAndy Shevchenko 	bitmap_set(bmap1, 0, 109);
3135fd003f5SDavid Decotigny 	bitmap_copy(bmap2, bmap1, 1024);
3145fd003f5SDavid Decotigny 	expect_eq_pbl("0-108", bmap2, 1024);
3155fd003f5SDavid Decotigny 
3165fd003f5SDavid Decotigny 	bitmap_fill(bmap2, 1024);
3175fd003f5SDavid Decotigny 	bitmap_copy(bmap2, bmap1, 1024);
3185fd003f5SDavid Decotigny 	expect_eq_pbl("0-108", bmap2, 1024);
3195fd003f5SDavid Decotigny 
3205fd003f5SDavid Decotigny 	/* the following tests assume a 32- or 64-bit arch (even 128b
3215fd003f5SDavid Decotigny 	 * if we care)
3225fd003f5SDavid Decotigny 	 */
3235fd003f5SDavid Decotigny 
3245fd003f5SDavid Decotigny 	bitmap_fill(bmap2, 1024);
3255fd003f5SDavid Decotigny 	bitmap_copy(bmap2, bmap1, 109);  /* ... but 0-padded til word length */
3265fd003f5SDavid Decotigny 	expect_eq_pbl("0-108,128-1023", bmap2, 1024);
3275fd003f5SDavid Decotigny 
3285fd003f5SDavid Decotigny 	bitmap_fill(bmap2, 1024);
3295fd003f5SDavid Decotigny 	bitmap_copy(bmap2, bmap1, 97);  /* ... but aligned on word length */
3305fd003f5SDavid Decotigny 	expect_eq_pbl("0-108,128-1023", bmap2, 1024);
3315fd003f5SDavid Decotigny }
3325fd003f5SDavid Decotigny 
33330544ed5SAndy Shevchenko #define EXP2_IN_BITS	(sizeof(exp2) * 8)
33430544ed5SAndy Shevchenko 
test_replace(void)33530544ed5SAndy Shevchenko static void __init test_replace(void)
33630544ed5SAndy Shevchenko {
33730544ed5SAndy Shevchenko 	unsigned int nbits = 64;
33869334ca5SAndy Shevchenko 	unsigned int nlongs = DIV_ROUND_UP(nbits, BITS_PER_LONG);
33930544ed5SAndy Shevchenko 	DECLARE_BITMAP(bmap, 1024);
34030544ed5SAndy Shevchenko 
341caa7f776SAndy Shevchenko 	BUILD_BUG_ON(EXP2_IN_BITS < nbits * 2);
342caa7f776SAndy Shevchenko 
34330544ed5SAndy Shevchenko 	bitmap_zero(bmap, 1024);
34469334ca5SAndy Shevchenko 	bitmap_replace(bmap, &exp2[0 * nlongs], &exp2[1 * nlongs], exp2_to_exp3_mask, nbits);
34530544ed5SAndy Shevchenko 	expect_eq_bitmap(bmap, exp3_0_1, nbits);
34630544ed5SAndy Shevchenko 
34730544ed5SAndy Shevchenko 	bitmap_zero(bmap, 1024);
34869334ca5SAndy Shevchenko 	bitmap_replace(bmap, &exp2[1 * nlongs], &exp2[0 * nlongs], exp2_to_exp3_mask, nbits);
34930544ed5SAndy Shevchenko 	expect_eq_bitmap(bmap, exp3_1_0, nbits);
35030544ed5SAndy Shevchenko 
35130544ed5SAndy Shevchenko 	bitmap_fill(bmap, 1024);
35269334ca5SAndy Shevchenko 	bitmap_replace(bmap, &exp2[0 * nlongs], &exp2[1 * nlongs], exp2_to_exp3_mask, nbits);
35330544ed5SAndy Shevchenko 	expect_eq_bitmap(bmap, exp3_0_1, nbits);
35430544ed5SAndy Shevchenko 
35530544ed5SAndy Shevchenko 	bitmap_fill(bmap, 1024);
35669334ca5SAndy Shevchenko 	bitmap_replace(bmap, &exp2[1 * nlongs], &exp2[0 * nlongs], exp2_to_exp3_mask, nbits);
35730544ed5SAndy Shevchenko 	expect_eq_bitmap(bmap, exp3_1_0, nbits);
35830544ed5SAndy Shevchenko }
35930544ed5SAndy Shevchenko 
3606df0d464SYury Norov #define PARSE_TIME	0x1
3617eb2e94eSYury Norov #define NO_LEN		0x2
3626df0d464SYury Norov 
3636df0d464SYury Norov struct test_bitmap_parselist{
3646df0d464SYury Norov 	const int errno;
3656df0d464SYury Norov 	const char *in;
3666df0d464SYury Norov 	const unsigned long *expected;
3676df0d464SYury Norov 	const int nbits;
3686df0d464SYury Norov 	const int flags;
3696df0d464SYury Norov };
3706df0d464SYury Norov 
3716df0d464SYury Norov static const struct test_bitmap_parselist parselist_tests[] __initconst = {
37260ef6900SYury Norov #define step (sizeof(u64) / sizeof(unsigned long))
37360ef6900SYury Norov 
3740ee312e3SAndy Shevchenko 	{0, "0",			&exp1[0], 8, 0},
3750ee312e3SAndy Shevchenko 	{0, "1",			&exp1[1 * step], 8, 0},
3760ee312e3SAndy Shevchenko 	{0, "0-15",			&exp1[2 * step], 32, 0},
3770ee312e3SAndy Shevchenko 	{0, "16-31",			&exp1[3 * step], 32, 0},
3780ee312e3SAndy Shevchenko 	{0, "0-31:1/2",			&exp1[4 * step], 32, 0},
3790ee312e3SAndy Shevchenko 	{0, "1-31:1/2",			&exp1[5 * step], 32, 0},
3800ee312e3SAndy Shevchenko 	{0, "0-31:1/4",			&exp1[6 * step], 32, 0},
3810ee312e3SAndy Shevchenko 	{0, "1-31:1/4",			&exp1[7 * step], 32, 0},
3820ee312e3SAndy Shevchenko 	{0, "0-31:4/4",			&exp1[8 * step], 32, 0},
3830ee312e3SAndy Shevchenko 	{0, "1-31:4/4",			&exp1[9 * step], 32, 0},
3840ee312e3SAndy Shevchenko 	{0, "0-31:1/4,32-63:2/4",	&exp1[10 * step], 64, 0},
3850ee312e3SAndy Shevchenko 	{0, "0-31:3/4,32-63:4/4",	&exp1[11 * step], 64, 0},
3860ee312e3SAndy Shevchenko 	{0, "  ,,  0-31:3/4  ,, 32-63:4/4  ,,  ",	&exp1[11 * step], 64, 0},
3876df0d464SYury Norov 
3886df0d464SYury Norov 	{0, "0-31:1/4,32-63:2/4,64-95:3/4,96-127:4/4",	exp2, 128, 0},
3896df0d464SYury Norov 
3906df0d464SYury Norov 	{0, "0-2047:128/256", NULL, 2048, PARSE_TIME},
3916df0d464SYury Norov 
3920ee312e3SAndy Shevchenko 	{0, "",				&exp1[12 * step], 8, 0},
3930ee312e3SAndy Shevchenko 	{0, "\n",			&exp1[12 * step], 8, 0},
3940ee312e3SAndy Shevchenko 	{0, ",,  ,,  , ,  ,",		&exp1[12 * step], 8, 0},
3950ee312e3SAndy Shevchenko 	{0, " ,  ,,  , ,   ",		&exp1[12 * step], 8, 0},
3960ee312e3SAndy Shevchenko 	{0, " ,  ,,  , ,   \n",		&exp1[12 * step], 8, 0},
397a4ab5050SYury Norov 
39897330db3SPaul Gortmaker 	{0, "0-0",			&exp1[0], 32, 0},
39997330db3SPaul Gortmaker 	{0, "1-1",			&exp1[1 * step], 32, 0},
40097330db3SPaul Gortmaker 	{0, "15-15",			&exp1[13 * step], 32, 0},
40197330db3SPaul Gortmaker 	{0, "31-31",			&exp1[14 * step], 32, 0},
40297330db3SPaul Gortmaker 
40397330db3SPaul Gortmaker 	{0, "0-0:0/1",			&exp1[12 * step], 32, 0},
40497330db3SPaul Gortmaker 	{0, "0-0:1/1",			&exp1[0], 32, 0},
40597330db3SPaul Gortmaker 	{0, "0-0:1/31",			&exp1[0], 32, 0},
40697330db3SPaul Gortmaker 	{0, "0-0:31/31",		&exp1[0], 32, 0},
40797330db3SPaul Gortmaker 	{0, "1-1:1/1",			&exp1[1 * step], 32, 0},
40897330db3SPaul Gortmaker 	{0, "0-15:16/31",		&exp1[2 * step], 32, 0},
40997330db3SPaul Gortmaker 	{0, "15-15:1/2",		&exp1[13 * step], 32, 0},
41097330db3SPaul Gortmaker 	{0, "15-15:31/31",		&exp1[13 * step], 32, 0},
41197330db3SPaul Gortmaker 	{0, "15-31:1/31",		&exp1[13 * step], 32, 0},
41297330db3SPaul Gortmaker 	{0, "16-31:16/31",		&exp1[3 * step], 32, 0},
41397330db3SPaul Gortmaker 	{0, "31-31:31/31",		&exp1[14 * step], 32, 0},
41497330db3SPaul Gortmaker 
41599c58d1aSPaul Gortmaker 	{0, "N-N",			&exp1[14 * step], 32, 0},
41699c58d1aSPaul Gortmaker 	{0, "0-0:1/N",			&exp1[0], 32, 0},
41799c58d1aSPaul Gortmaker 	{0, "0-0:N/N",			&exp1[0], 32, 0},
41899c58d1aSPaul Gortmaker 	{0, "0-15:16/N",		&exp1[2 * step], 32, 0},
41999c58d1aSPaul Gortmaker 	{0, "15-15:N/N",		&exp1[13 * step], 32, 0},
42099c58d1aSPaul Gortmaker 	{0, "15-N:1/N",			&exp1[13 * step], 32, 0},
42199c58d1aSPaul Gortmaker 	{0, "16-N:16/N",		&exp1[3 * step], 32, 0},
42299c58d1aSPaul Gortmaker 	{0, "N-N:N/N",			&exp1[14 * step], 32, 0},
42399c58d1aSPaul Gortmaker 
42499c58d1aSPaul Gortmaker 	{0, "0-N:1/3,1-N:1/3,2-N:1/3",		&exp1[8 * step], 32, 0},
42597330db3SPaul Gortmaker 	{0, "0-31:1/3,1-31:1/3,2-31:1/3",	&exp1[8 * step], 32, 0},
42697330db3SPaul Gortmaker 	{0, "1-10:8/12,8-31:24/29,0-31:0/3",	&exp1[9 * step], 32, 0},
42797330db3SPaul Gortmaker 
428b18def12SYury Norov 	{0,	  "all",		&exp1[8 * step], 32, 0},
429b18def12SYury Norov 	{0,	  "0, 1, all,  ",	&exp1[8 * step], 32, 0},
430b18def12SYury Norov 	{0,	  "all:1/2",		&exp1[4 * step], 32, 0},
431b18def12SYury Norov 	{0,	  "ALL:1/2",		&exp1[4 * step], 32, 0},
432b18def12SYury Norov 	{-EINVAL, "al", NULL, 8, 0},
433b18def12SYury Norov 	{-EINVAL, "alll", NULL, 8, 0},
434b18def12SYury Norov 
4356df0d464SYury Norov 	{-EINVAL, "-1",	NULL, 8, 0},
4366df0d464SYury Norov 	{-EINVAL, "-0",	NULL, 8, 0},
4376df0d464SYury Norov 	{-EINVAL, "10-1", NULL, 8, 0},
4386fef5905SPaul Gortmaker 	{-ERANGE, "8-8", NULL, 8, 0},
4396fef5905SPaul Gortmaker 	{-ERANGE, "0-31", NULL, 8, 0},
440494215fbSPaul Gortmaker 	{-EINVAL, "0-31:", NULL, 32, 0},
441494215fbSPaul Gortmaker 	{-EINVAL, "0-31:0", NULL, 32, 0},
442494215fbSPaul Gortmaker 	{-EINVAL, "0-31:0/", NULL, 32, 0},
443494215fbSPaul Gortmaker 	{-EINVAL, "0-31:0/0", NULL, 32, 0},
444494215fbSPaul Gortmaker 	{-EINVAL, "0-31:1/0", NULL, 32, 0},
445494215fbSPaul Gortmaker 	{-EINVAL, "0-31:10/1", NULL, 32, 0},
446a4ab5050SYury Norov 	{-EOVERFLOW, "0-98765432123456789:10/1", NULL, 8, 0},
447a4ab5050SYury Norov 
448a4ab5050SYury Norov 	{-EINVAL, "a-31", NULL, 8, 0},
449a4ab5050SYury Norov 	{-EINVAL, "0-a1", NULL, 8, 0},
450a4ab5050SYury Norov 	{-EINVAL, "a-31:10/1", NULL, 8, 0},
451a4ab5050SYury Norov 	{-EINVAL, "0-31:a/1", NULL, 8, 0},
452a4ab5050SYury Norov 	{-EINVAL, "0-\n", NULL, 8, 0},
45354224044SAndy Shevchenko 
4546df0d464SYury Norov };
4556df0d464SYury Norov 
test_bitmap_parselist(void)45681b1e242SChristoph Hellwig static void __init test_bitmap_parselist(void)
4576df0d464SYury Norov {
4586df0d464SYury Norov 	int i;
4596df0d464SYury Norov 	int err;
4600c2111a5SYury Norov 	ktime_t time;
4616df0d464SYury Norov 	DECLARE_BITMAP(bmap, 2048);
4626df0d464SYury Norov 
4636df0d464SYury Norov 	for (i = 0; i < ARRAY_SIZE(parselist_tests); i++) {
4646df0d464SYury Norov #define ptest parselist_tests[i]
4656df0d464SYury Norov 
4660c2111a5SYury Norov 		time = ktime_get();
4676df0d464SYury Norov 		err = bitmap_parselist(ptest.in, bmap, ptest.nbits);
4680c2111a5SYury Norov 		time = ktime_get() - time;
4696df0d464SYury Norov 
4706df0d464SYury Norov 		if (err != ptest.errno) {
47181b1e242SChristoph Hellwig 			pr_err("parselist: %d: input is %s, errno is %d, expected %d\n",
47281b1e242SChristoph Hellwig 					i, ptest.in, err, ptest.errno);
473c4c14c29SYury Norov 			failed_tests++;
4746df0d464SYury Norov 			continue;
4756df0d464SYury Norov 		}
4766df0d464SYury Norov 
4776df0d464SYury Norov 		if (!err && ptest.expected
4786df0d464SYury Norov 			 && !__bitmap_equal(bmap, ptest.expected, ptest.nbits)) {
47981b1e242SChristoph Hellwig 			pr_err("parselist: %d: input is %s, result is 0x%lx, expected 0x%lx\n",
48081b1e242SChristoph Hellwig 					i, ptest.in, bmap[0],
4816ea86bdfSYury Norov 					*ptest.expected);
482c4c14c29SYury Norov 			failed_tests++;
4836df0d464SYury Norov 			continue;
4846df0d464SYury Norov 		}
4856df0d464SYury Norov 
4866df0d464SYury Norov 		if (ptest.flags & PARSE_TIME)
48781b1e242SChristoph Hellwig 			pr_err("parselist: %d: input is '%s' OK, Time: %llu\n",
48881b1e242SChristoph Hellwig 					i, ptest.in, time);
48954224044SAndy Shevchenko 
49054224044SAndy Shevchenko #undef ptest
4916df0d464SYury Norov 	}
4926df0d464SYury Norov }
4936df0d464SYury Norov 
test_bitmap_printlist(void)494db731300SYury Norov static void __init test_bitmap_printlist(void)
495db731300SYury Norov {
496db731300SYury Norov 	unsigned long *bmap = kmalloc(PAGE_SIZE, GFP_KERNEL);
497db731300SYury Norov 	char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
498db731300SYury Norov 	char expected[256];
499db731300SYury Norov 	int ret, slen;
500db731300SYury Norov 	ktime_t time;
501db731300SYury Norov 
502db731300SYury Norov 	if (!buf || !bmap)
503db731300SYury Norov 		goto out;
504db731300SYury Norov 
505db731300SYury Norov 	memset(bmap, -1, PAGE_SIZE);
506db731300SYury Norov 	slen = snprintf(expected, 256, "0-%ld", PAGE_SIZE * 8 - 1);
507db731300SYury Norov 	if (slen < 0)
508db731300SYury Norov 		goto out;
509db731300SYury Norov 
510db731300SYury Norov 	time = ktime_get();
511db731300SYury Norov 	ret = bitmap_print_to_pagebuf(true, buf, bmap, PAGE_SIZE * 8);
512db731300SYury Norov 	time = ktime_get() - time;
513db731300SYury Norov 
514db731300SYury Norov 	if (ret != slen + 1) {
515db731300SYury Norov 		pr_err("bitmap_print_to_pagebuf: result is %d, expected %d\n", ret, slen);
516c4c14c29SYury Norov 		failed_tests++;
517db731300SYury Norov 		goto out;
518db731300SYury Norov 	}
519db731300SYury Norov 
520db731300SYury Norov 	if (strncmp(buf, expected, slen)) {
521db731300SYury Norov 		pr_err("bitmap_print_to_pagebuf: result is %s, expected %s\n", buf, expected);
522c4c14c29SYury Norov 		failed_tests++;
523db731300SYury Norov 		goto out;
524db731300SYury Norov 	}
525db731300SYury Norov 
526db731300SYury Norov 	pr_err("bitmap_print_to_pagebuf: input is '%s', Time: %llu\n", buf, time);
527db731300SYury Norov out:
528db731300SYury Norov 	kfree(buf);
529db731300SYury Norov 	kfree(bmap);
530db731300SYury Norov }
531db731300SYury Norov 
5327eb2e94eSYury Norov static const unsigned long parse_test[] __initconst = {
5337eb2e94eSYury Norov 	BITMAP_FROM_U64(0),
5347eb2e94eSYury Norov 	BITMAP_FROM_U64(1),
5357eb2e94eSYury Norov 	BITMAP_FROM_U64(0xdeadbeef),
5367eb2e94eSYury Norov 	BITMAP_FROM_U64(0x100000000ULL),
5377eb2e94eSYury Norov };
5387eb2e94eSYury Norov 
5397eb2e94eSYury Norov static const unsigned long parse_test2[] __initconst = {
5407eb2e94eSYury Norov 	BITMAP_FROM_U64(0x100000000ULL), BITMAP_FROM_U64(0xdeadbeef),
5417eb2e94eSYury Norov 	BITMAP_FROM_U64(0x100000000ULL), BITMAP_FROM_U64(0xbaadf00ddeadbeef),
5427eb2e94eSYury Norov 	BITMAP_FROM_U64(0x100000000ULL), BITMAP_FROM_U64(0x0badf00ddeadbeef),
5437eb2e94eSYury Norov };
5447eb2e94eSYury Norov 
5457eb2e94eSYury Norov static const struct test_bitmap_parselist parse_tests[] __initconst = {
546809e308fSYury Norov 	{0, "",				&parse_test[0 * step], 32, 0},
547809e308fSYury Norov 	{0, " ",			&parse_test[0 * step], 32, 0},
5487eb2e94eSYury Norov 	{0, "0",			&parse_test[0 * step], 32, 0},
549809e308fSYury Norov 	{0, "0\n",			&parse_test[0 * step], 32, 0},
5507eb2e94eSYury Norov 	{0, "1",			&parse_test[1 * step], 32, 0},
5517eb2e94eSYury Norov 	{0, "deadbeef",			&parse_test[2 * step], 32, 0},
5527eb2e94eSYury Norov 	{0, "1,0",			&parse_test[3 * step], 33, 0},
553809e308fSYury Norov 	{0, "deadbeef,\n,0,1",		&parse_test[2 * step], 96, 0},
5547eb2e94eSYury Norov 
5557eb2e94eSYury Norov 	{0, "deadbeef,1,0",		&parse_test2[0 * 2 * step], 96, 0},
5567eb2e94eSYury Norov 	{0, "baadf00d,deadbeef,1,0",	&parse_test2[1 * 2 * step], 128, 0},
5577eb2e94eSYury Norov 	{0, "badf00d,deadbeef,1,0",	&parse_test2[2 * 2 * step], 124, 0},
558809e308fSYury Norov 	{0, "badf00d,deadbeef,1,0",	&parse_test2[2 * 2 * step], 124, NO_LEN},
559809e308fSYury Norov 	{0, "  badf00d,deadbeef,1,0  ",	&parse_test2[2 * 2 * step], 124, 0},
560809e308fSYury Norov 	{0, " , badf00d,deadbeef,1,0 , ",	&parse_test2[2 * 2 * step], 124, 0},
561809e308fSYury Norov 	{0, " , badf00d, ,, ,,deadbeef,1,0 , ",	&parse_test2[2 * 2 * step], 124, 0},
5627eb2e94eSYury Norov 
5637eb2e94eSYury Norov 	{-EINVAL,    "goodfood,deadbeef,1,0",	NULL, 128, 0},
5647eb2e94eSYury Norov 	{-EOVERFLOW, "3,0",			NULL, 33, 0},
5657eb2e94eSYury Norov 	{-EOVERFLOW, "123badf00d,deadbeef,1,0",	NULL, 128, 0},
5667eb2e94eSYury Norov 	{-EOVERFLOW, "badf00d,deadbeef,1,0",	NULL, 90, 0},
5677eb2e94eSYury Norov 	{-EOVERFLOW, "fbadf00d,deadbeef,1,0",	NULL, 95, 0},
5687eb2e94eSYury Norov 	{-EOVERFLOW, "badf00d,deadbeef,1,0",	NULL, 100, 0},
5697eb2e94eSYury Norov #undef step
5707eb2e94eSYury Norov };
5717eb2e94eSYury Norov 
test_bitmap_parse(void)57281b1e242SChristoph Hellwig static void __init test_bitmap_parse(void)
5737eb2e94eSYury Norov {
5747eb2e94eSYury Norov 	int i;
5757eb2e94eSYury Norov 	int err;
5767eb2e94eSYury Norov 	ktime_t time;
5777eb2e94eSYury Norov 	DECLARE_BITMAP(bmap, 2048);
5787eb2e94eSYury Norov 
5797eb2e94eSYury Norov 	for (i = 0; i < ARRAY_SIZE(parse_tests); i++) {
5807eb2e94eSYury Norov 		struct test_bitmap_parselist test = parse_tests[i];
58181b1e242SChristoph Hellwig 		size_t len = test.flags & NO_LEN ? UINT_MAX : strlen(test.in);
5827eb2e94eSYury Norov 
5837eb2e94eSYury Norov 		time = ktime_get();
5847eb2e94eSYury Norov 		err = bitmap_parse(test.in, len, bmap, test.nbits);
5857eb2e94eSYury Norov 		time = ktime_get() - time;
5867eb2e94eSYury Norov 
5877eb2e94eSYury Norov 		if (err != test.errno) {
58881b1e242SChristoph Hellwig 			pr_err("parse: %d: input is %s, errno is %d, expected %d\n",
58981b1e242SChristoph Hellwig 					i, test.in, err, test.errno);
590c4c14c29SYury Norov 			failed_tests++;
5917eb2e94eSYury Norov 			continue;
5927eb2e94eSYury Norov 		}
5937eb2e94eSYury Norov 
5947eb2e94eSYury Norov 		if (!err && test.expected
5957eb2e94eSYury Norov 			 && !__bitmap_equal(bmap, test.expected, test.nbits)) {
59681b1e242SChristoph Hellwig 			pr_err("parse: %d: input is %s, result is 0x%lx, expected 0x%lx\n",
59781b1e242SChristoph Hellwig 					i, test.in, bmap[0],
5987eb2e94eSYury Norov 					*test.expected);
599c4c14c29SYury Norov 			failed_tests++;
6007eb2e94eSYury Norov 			continue;
6017eb2e94eSYury Norov 		}
6027eb2e94eSYury Norov 
6037eb2e94eSYury Norov 		if (test.flags & PARSE_TIME)
60481b1e242SChristoph Hellwig 			pr_err("parse: %d: input is '%s' OK, Time: %llu\n",
60581b1e242SChristoph Hellwig 					i, test.in, time);
6067eb2e94eSYury Norov 	}
6077eb2e94eSYury Norov }
6087eb2e94eSYury Norov 
test_bitmap_arr32(void)6093aa56885SYury Norov static void __init test_bitmap_arr32(void)
6105fd003f5SDavid Decotigny {
611f6f66c1bSKees Cook 	unsigned int nbits, next_bit;
612a4881d1cSAndy Shevchenko 	u32 arr[EXP1_IN_BITS / 32];
613a4881d1cSAndy Shevchenko 	DECLARE_BITMAP(bmap2, EXP1_IN_BITS);
6145fd003f5SDavid Decotigny 
6153aa56885SYury Norov 	memset(arr, 0xa5, sizeof(arr));
6165fd003f5SDavid Decotigny 
617a4881d1cSAndy Shevchenko 	for (nbits = 0; nbits < EXP1_IN_BITS; ++nbits) {
6180ee312e3SAndy Shevchenko 		bitmap_to_arr32(arr, exp1, nbits);
6193aa56885SYury Norov 		bitmap_from_arr32(bmap2, arr, nbits);
6200ee312e3SAndy Shevchenko 		expect_eq_bitmap(bmap2, exp1, nbits);
6215fd003f5SDavid Decotigny 
6223aa56885SYury Norov 		next_bit = find_next_bit(bmap2,
6233aa56885SYury Norov 				round_up(nbits, BITS_PER_LONG), nbits);
624c4c14c29SYury Norov 		if (next_bit < round_up(nbits, BITS_PER_LONG)) {
6253aa56885SYury Norov 			pr_err("bitmap_copy_arr32(nbits == %d:"
6263aa56885SYury Norov 				" tail is not safely cleared: %d\n",
6273aa56885SYury Norov 				nbits, next_bit);
628c4c14c29SYury Norov 			failed_tests++;
629c4c14c29SYury Norov 		}
6305fd003f5SDavid Decotigny 
631a4881d1cSAndy Shevchenko 		if (nbits < EXP1_IN_BITS - 32)
6323aa56885SYury Norov 			expect_eq_uint(arr[DIV_ROUND_UP(nbits, 32)],
6333aa56885SYury Norov 								0xa5a5a5a5);
6345fd003f5SDavid Decotigny 	}
6355fd003f5SDavid Decotigny }
6365fd003f5SDavid Decotigny 
test_bitmap_arr64(void)6372c523550SYury Norov static void __init test_bitmap_arr64(void)
6382c523550SYury Norov {
6392c523550SYury Norov 	unsigned int nbits, next_bit;
6402c523550SYury Norov 	u64 arr[EXP1_IN_BITS / 64];
6412c523550SYury Norov 	DECLARE_BITMAP(bmap2, EXP1_IN_BITS);
6422c523550SYury Norov 
6432c523550SYury Norov 	memset(arr, 0xa5, sizeof(arr));
6442c523550SYury Norov 
6452c523550SYury Norov 	for (nbits = 0; nbits < EXP1_IN_BITS; ++nbits) {
6462c523550SYury Norov 		memset(bmap2, 0xff, sizeof(arr));
6472c523550SYury Norov 		bitmap_to_arr64(arr, exp1, nbits);
6482c523550SYury Norov 		bitmap_from_arr64(bmap2, arr, nbits);
6492c523550SYury Norov 		expect_eq_bitmap(bmap2, exp1, nbits);
6502c523550SYury Norov 
6512c523550SYury Norov 		next_bit = find_next_bit(bmap2, round_up(nbits, BITS_PER_LONG), nbits);
652c4c14c29SYury Norov 		if (next_bit < round_up(nbits, BITS_PER_LONG)) {
6532c523550SYury Norov 			pr_err("bitmap_copy_arr64(nbits == %d:"
6542c523550SYury Norov 				" tail is not safely cleared: %d\n", nbits, next_bit);
655c4c14c29SYury Norov 			failed_tests++;
656c4c14c29SYury Norov 		}
6572c523550SYury Norov 
65830fd8cdfSAlexander Lobakin 		if ((nbits % 64) &&
659c4c14c29SYury Norov 		    (arr[(nbits - 1) / 64] & ~GENMASK_ULL((nbits - 1) % 64, 0))) {
66030fd8cdfSAlexander Lobakin 			pr_err("bitmap_to_arr64(nbits == %d): tail is not safely cleared: 0x%016llx (must be 0x%016llx)\n",
66130fd8cdfSAlexander Lobakin 			       nbits, arr[(nbits - 1) / 64],
66230fd8cdfSAlexander Lobakin 			       GENMASK_ULL((nbits - 1) % 64, 0));
663c4c14c29SYury Norov 			failed_tests++;
664c4c14c29SYury Norov 		}
66530fd8cdfSAlexander Lobakin 
6662c523550SYury Norov 		if (nbits < EXP1_IN_BITS - 64)
6672c523550SYury Norov 			expect_eq_uint(arr[DIV_ROUND_UP(nbits, 64)], 0xa5a5a5a5);
6682c523550SYury Norov 	}
6692c523550SYury Norov }
6702c523550SYury Norov 
test_mem_optimisations(void)6713cc78125SMatthew Wilcox static void noinline __init test_mem_optimisations(void)
6723cc78125SMatthew Wilcox {
6733cc78125SMatthew Wilcox 	DECLARE_BITMAP(bmap1, 1024);
6743cc78125SMatthew Wilcox 	DECLARE_BITMAP(bmap2, 1024);
6753cc78125SMatthew Wilcox 	unsigned int start, nbits;
6763cc78125SMatthew Wilcox 
6773cc78125SMatthew Wilcox 	for (start = 0; start < 1024; start += 8) {
6781e3054b9SMatthew Wilcox 		for (nbits = 0; nbits < 1024 - start; nbits += 8) {
6793cc78125SMatthew Wilcox 			memset(bmap1, 0x5a, sizeof(bmap1));
6803cc78125SMatthew Wilcox 			memset(bmap2, 0x5a, sizeof(bmap2));
6811e3054b9SMatthew Wilcox 
6823cc78125SMatthew Wilcox 			bitmap_set(bmap1, start, nbits);
6833cc78125SMatthew Wilcox 			__bitmap_set(bmap2, start, nbits);
6841e3054b9SMatthew Wilcox 			if (!bitmap_equal(bmap1, bmap2, 1024)) {
6853cc78125SMatthew Wilcox 				printk("set not equal %d %d\n", start, nbits);
6861e3054b9SMatthew Wilcox 				failed_tests++;
6871e3054b9SMatthew Wilcox 			}
6881e3054b9SMatthew Wilcox 			if (!__bitmap_equal(bmap1, bmap2, 1024)) {
6893cc78125SMatthew Wilcox 				printk("set not __equal %d %d\n", start, nbits);
6901e3054b9SMatthew Wilcox 				failed_tests++;
6911e3054b9SMatthew Wilcox 			}
6923cc78125SMatthew Wilcox 
6933cc78125SMatthew Wilcox 			bitmap_clear(bmap1, start, nbits);
6943cc78125SMatthew Wilcox 			__bitmap_clear(bmap2, start, nbits);
6951e3054b9SMatthew Wilcox 			if (!bitmap_equal(bmap1, bmap2, 1024)) {
6963cc78125SMatthew Wilcox 				printk("clear not equal %d %d\n", start, nbits);
6971e3054b9SMatthew Wilcox 				failed_tests++;
6981e3054b9SMatthew Wilcox 			}
6991e3054b9SMatthew Wilcox 			if (!__bitmap_equal(bmap1, bmap2, 1024)) {
7003cc78125SMatthew Wilcox 				printk("clear not __equal %d %d\n", start,
7013cc78125SMatthew Wilcox 									nbits);
7021e3054b9SMatthew Wilcox 				failed_tests++;
7031e3054b9SMatthew Wilcox 			}
7043cc78125SMatthew Wilcox 		}
7053cc78125SMatthew Wilcox 	}
7063cc78125SMatthew Wilcox }
7073cc78125SMatthew Wilcox 
708e4aa168dSWilliam Breathitt Gray static const unsigned char clump_exp[] __initconst = {
709e4aa168dSWilliam Breathitt Gray 	0x01,	/* 1 bit set */
710e4aa168dSWilliam Breathitt Gray 	0x02,	/* non-edge 1 bit set */
711e4aa168dSWilliam Breathitt Gray 	0x00,	/* zero bits set */
712e4aa168dSWilliam Breathitt Gray 	0x38,	/* 3 bits set across 4-bit boundary */
713e4aa168dSWilliam Breathitt Gray 	0x38,	/* Repeated clump */
714e4aa168dSWilliam Breathitt Gray 	0x0F,	/* 4 bits set */
715e4aa168dSWilliam Breathitt Gray 	0xFF,	/* all bits set */
716e4aa168dSWilliam Breathitt Gray 	0x05,	/* non-adjacent 2 bits set */
717e4aa168dSWilliam Breathitt Gray };
718e4aa168dSWilliam Breathitt Gray 
test_for_each_set_clump8(void)719e4aa168dSWilliam Breathitt Gray static void __init test_for_each_set_clump8(void)
720e4aa168dSWilliam Breathitt Gray {
721e4aa168dSWilliam Breathitt Gray #define CLUMP_EXP_NUMBITS 64
722e4aa168dSWilliam Breathitt Gray 	DECLARE_BITMAP(bits, CLUMP_EXP_NUMBITS);
723e4aa168dSWilliam Breathitt Gray 	unsigned int start;
724e4aa168dSWilliam Breathitt Gray 	unsigned long clump;
725e4aa168dSWilliam Breathitt Gray 
726e4aa168dSWilliam Breathitt Gray 	/* set bitmap to test case */
727e4aa168dSWilliam Breathitt Gray 	bitmap_zero(bits, CLUMP_EXP_NUMBITS);
728e4aa168dSWilliam Breathitt Gray 	bitmap_set(bits, 0, 1);		/* 0x01 */
729e4aa168dSWilliam Breathitt Gray 	bitmap_set(bits, 9, 1);		/* 0x02 */
730e4aa168dSWilliam Breathitt Gray 	bitmap_set(bits, 27, 3);	/* 0x28 */
731e4aa168dSWilliam Breathitt Gray 	bitmap_set(bits, 35, 3);	/* 0x28 */
732e4aa168dSWilliam Breathitt Gray 	bitmap_set(bits, 40, 4);	/* 0x0F */
733e4aa168dSWilliam Breathitt Gray 	bitmap_set(bits, 48, 8);	/* 0xFF */
734e4aa168dSWilliam Breathitt Gray 	bitmap_set(bits, 56, 1);	/* 0x05 - part 1 */
735e4aa168dSWilliam Breathitt Gray 	bitmap_set(bits, 58, 1);	/* 0x05 - part 2 */
736e4aa168dSWilliam Breathitt Gray 
737e4aa168dSWilliam Breathitt Gray 	for_each_set_clump8(start, clump, bits, CLUMP_EXP_NUMBITS)
738e4aa168dSWilliam Breathitt Gray 		expect_eq_clump8(start, CLUMP_EXP_NUMBITS, clump_exp, &clump);
739e4aa168dSWilliam Breathitt Gray }
740e4aa168dSWilliam Breathitt Gray 
test_for_each_set_bit_wrap(void)7418173aa26SYury Norov static void __init test_for_each_set_bit_wrap(void)
7428173aa26SYury Norov {
7438173aa26SYury Norov 	DECLARE_BITMAP(orig, 500);
7448173aa26SYury Norov 	DECLARE_BITMAP(copy, 500);
7458173aa26SYury Norov 	unsigned int wr, bit;
7468173aa26SYury Norov 
7478173aa26SYury Norov 	bitmap_zero(orig, 500);
7488173aa26SYury Norov 
7498173aa26SYury Norov 	/* Set individual bits */
7508173aa26SYury Norov 	for (bit = 0; bit < 500; bit += 10)
7518173aa26SYury Norov 		bitmap_set(orig, bit, 1);
7528173aa26SYury Norov 
7538173aa26SYury Norov 	/* Set range of bits */
7548173aa26SYury Norov 	bitmap_set(orig, 100, 50);
7558173aa26SYury Norov 
7568173aa26SYury Norov 	for (wr = 0; wr < 500; wr++) {
7578173aa26SYury Norov 		bitmap_zero(copy, 500);
7588173aa26SYury Norov 
7598173aa26SYury Norov 		for_each_set_bit_wrap(bit, orig, 500, wr)
7608173aa26SYury Norov 			bitmap_set(copy, bit, 1);
7618173aa26SYury Norov 
7628173aa26SYury Norov 		expect_eq_bitmap(orig, copy, 500);
7638173aa26SYury Norov 	}
7648173aa26SYury Norov }
7658173aa26SYury Norov 
test_for_each_set_bit(void)7668173aa26SYury Norov static void __init test_for_each_set_bit(void)
7678173aa26SYury Norov {
7688173aa26SYury Norov 	DECLARE_BITMAP(orig, 500);
7698173aa26SYury Norov 	DECLARE_BITMAP(copy, 500);
7708173aa26SYury Norov 	unsigned int bit;
7718173aa26SYury Norov 
7728173aa26SYury Norov 	bitmap_zero(orig, 500);
7738173aa26SYury Norov 	bitmap_zero(copy, 500);
7748173aa26SYury Norov 
7758173aa26SYury Norov 	/* Set individual bits */
7768173aa26SYury Norov 	for (bit = 0; bit < 500; bit += 10)
7778173aa26SYury Norov 		bitmap_set(orig, bit, 1);
7788173aa26SYury Norov 
7798173aa26SYury Norov 	/* Set range of bits */
7808173aa26SYury Norov 	bitmap_set(orig, 100, 50);
7818173aa26SYury Norov 
7828173aa26SYury Norov 	for_each_set_bit(bit, orig, 500)
7838173aa26SYury Norov 		bitmap_set(copy, bit, 1);
7848173aa26SYury Norov 
7858173aa26SYury Norov 	expect_eq_bitmap(orig, copy, 500);
7868173aa26SYury Norov }
7878173aa26SYury Norov 
test_for_each_set_bit_from(void)7888173aa26SYury Norov static void __init test_for_each_set_bit_from(void)
7898173aa26SYury Norov {
7908173aa26SYury Norov 	DECLARE_BITMAP(orig, 500);
7918173aa26SYury Norov 	DECLARE_BITMAP(copy, 500);
7928173aa26SYury Norov 	unsigned int wr, bit;
7938173aa26SYury Norov 
7948173aa26SYury Norov 	bitmap_zero(orig, 500);
7958173aa26SYury Norov 
7968173aa26SYury Norov 	/* Set individual bits */
7978173aa26SYury Norov 	for (bit = 0; bit < 500; bit += 10)
7988173aa26SYury Norov 		bitmap_set(orig, bit, 1);
7998173aa26SYury Norov 
8008173aa26SYury Norov 	/* Set range of bits */
8018173aa26SYury Norov 	bitmap_set(orig, 100, 50);
8028173aa26SYury Norov 
8038173aa26SYury Norov 	for (wr = 0; wr < 500; wr++) {
8048173aa26SYury Norov 		DECLARE_BITMAP(tmp, 500);
8058173aa26SYury Norov 
8068173aa26SYury Norov 		bitmap_zero(copy, 500);
8078173aa26SYury Norov 		bit = wr;
8088173aa26SYury Norov 
8098173aa26SYury Norov 		for_each_set_bit_from(bit, orig, 500)
8108173aa26SYury Norov 			bitmap_set(copy, bit, 1);
8118173aa26SYury Norov 
8128173aa26SYury Norov 		bitmap_copy(tmp, orig, 500);
8138173aa26SYury Norov 		bitmap_clear(tmp, 0, wr);
8148173aa26SYury Norov 		expect_eq_bitmap(tmp, copy, 500);
8158173aa26SYury Norov 	}
8168173aa26SYury Norov }
8178173aa26SYury Norov 
test_for_each_clear_bit(void)8188173aa26SYury Norov static void __init test_for_each_clear_bit(void)
8198173aa26SYury Norov {
8208173aa26SYury Norov 	DECLARE_BITMAP(orig, 500);
8218173aa26SYury Norov 	DECLARE_BITMAP(copy, 500);
8228173aa26SYury Norov 	unsigned int bit;
8238173aa26SYury Norov 
8248173aa26SYury Norov 	bitmap_fill(orig, 500);
8258173aa26SYury Norov 	bitmap_fill(copy, 500);
8268173aa26SYury Norov 
8278173aa26SYury Norov 	/* Set individual bits */
8288173aa26SYury Norov 	for (bit = 0; bit < 500; bit += 10)
8298173aa26SYury Norov 		bitmap_clear(orig, bit, 1);
8308173aa26SYury Norov 
8318173aa26SYury Norov 	/* Set range of bits */
8328173aa26SYury Norov 	bitmap_clear(orig, 100, 50);
8338173aa26SYury Norov 
8348173aa26SYury Norov 	for_each_clear_bit(bit, orig, 500)
8358173aa26SYury Norov 		bitmap_clear(copy, bit, 1);
8368173aa26SYury Norov 
8378173aa26SYury Norov 	expect_eq_bitmap(orig, copy, 500);
8388173aa26SYury Norov }
8398173aa26SYury Norov 
test_for_each_clear_bit_from(void)8408173aa26SYury Norov static void __init test_for_each_clear_bit_from(void)
8418173aa26SYury Norov {
8428173aa26SYury Norov 	DECLARE_BITMAP(orig, 500);
8438173aa26SYury Norov 	DECLARE_BITMAP(copy, 500);
8448173aa26SYury Norov 	unsigned int wr, bit;
8458173aa26SYury Norov 
8468173aa26SYury Norov 	bitmap_fill(orig, 500);
8478173aa26SYury Norov 
8488173aa26SYury Norov 	/* Set individual bits */
8498173aa26SYury Norov 	for (bit = 0; bit < 500; bit += 10)
8508173aa26SYury Norov 		bitmap_clear(orig, bit, 1);
8518173aa26SYury Norov 
8528173aa26SYury Norov 	/* Set range of bits */
8538173aa26SYury Norov 	bitmap_clear(orig, 100, 50);
8548173aa26SYury Norov 
8558173aa26SYury Norov 	for (wr = 0; wr < 500; wr++) {
8568173aa26SYury Norov 		DECLARE_BITMAP(tmp, 500);
8578173aa26SYury Norov 
8588173aa26SYury Norov 		bitmap_fill(copy, 500);
8598173aa26SYury Norov 		bit = wr;
8608173aa26SYury Norov 
8618173aa26SYury Norov 		for_each_clear_bit_from(bit, orig, 500)
8628173aa26SYury Norov 			bitmap_clear(copy, bit, 1);
8638173aa26SYury Norov 
8648173aa26SYury Norov 		bitmap_copy(tmp, orig, 500);
8658173aa26SYury Norov 		bitmap_set(tmp, 0, wr);
8668173aa26SYury Norov 		expect_eq_bitmap(tmp, copy, 500);
8678173aa26SYury Norov 	}
8688173aa26SYury Norov }
8698173aa26SYury Norov 
test_for_each_set_bitrange(void)8708173aa26SYury Norov static void __init test_for_each_set_bitrange(void)
8718173aa26SYury Norov {
8728173aa26SYury Norov 	DECLARE_BITMAP(orig, 500);
8738173aa26SYury Norov 	DECLARE_BITMAP(copy, 500);
8748173aa26SYury Norov 	unsigned int s, e;
8758173aa26SYury Norov 
8768173aa26SYury Norov 	bitmap_zero(orig, 500);
8778173aa26SYury Norov 	bitmap_zero(copy, 500);
8788173aa26SYury Norov 
8798173aa26SYury Norov 	/* Set individual bits */
8808173aa26SYury Norov 	for (s = 0; s < 500; s += 10)
8818173aa26SYury Norov 		bitmap_set(orig, s, 1);
8828173aa26SYury Norov 
8838173aa26SYury Norov 	/* Set range of bits */
8848173aa26SYury Norov 	bitmap_set(orig, 100, 50);
8858173aa26SYury Norov 
8868173aa26SYury Norov 	for_each_set_bitrange(s, e, orig, 500)
8878173aa26SYury Norov 		bitmap_set(copy, s, e-s);
8888173aa26SYury Norov 
8898173aa26SYury Norov 	expect_eq_bitmap(orig, copy, 500);
8908173aa26SYury Norov }
8918173aa26SYury Norov 
test_for_each_clear_bitrange(void)8928173aa26SYury Norov static void __init test_for_each_clear_bitrange(void)
8938173aa26SYury Norov {
8948173aa26SYury Norov 	DECLARE_BITMAP(orig, 500);
8958173aa26SYury Norov 	DECLARE_BITMAP(copy, 500);
8968173aa26SYury Norov 	unsigned int s, e;
8978173aa26SYury Norov 
8988173aa26SYury Norov 	bitmap_fill(orig, 500);
8998173aa26SYury Norov 	bitmap_fill(copy, 500);
9008173aa26SYury Norov 
9018173aa26SYury Norov 	/* Set individual bits */
9028173aa26SYury Norov 	for (s = 0; s < 500; s += 10)
9038173aa26SYury Norov 		bitmap_clear(orig, s, 1);
9048173aa26SYury Norov 
9058173aa26SYury Norov 	/* Set range of bits */
9068173aa26SYury Norov 	bitmap_clear(orig, 100, 50);
9078173aa26SYury Norov 
9088173aa26SYury Norov 	for_each_clear_bitrange(s, e, orig, 500)
9098173aa26SYury Norov 		bitmap_clear(copy, s, e-s);
9108173aa26SYury Norov 
9118173aa26SYury Norov 	expect_eq_bitmap(orig, copy, 500);
9128173aa26SYury Norov }
9138173aa26SYury Norov 
test_for_each_set_bitrange_from(void)9148173aa26SYury Norov static void __init test_for_each_set_bitrange_from(void)
9158173aa26SYury Norov {
9168173aa26SYury Norov 	DECLARE_BITMAP(orig, 500);
9178173aa26SYury Norov 	DECLARE_BITMAP(copy, 500);
9188173aa26SYury Norov 	unsigned int wr, s, e;
9198173aa26SYury Norov 
9208173aa26SYury Norov 	bitmap_zero(orig, 500);
9218173aa26SYury Norov 
9228173aa26SYury Norov 	/* Set individual bits */
9238173aa26SYury Norov 	for (s = 0; s < 500; s += 10)
9248173aa26SYury Norov 		bitmap_set(orig, s, 1);
9258173aa26SYury Norov 
9268173aa26SYury Norov 	/* Set range of bits */
9278173aa26SYury Norov 	bitmap_set(orig, 100, 50);
9288173aa26SYury Norov 
9298173aa26SYury Norov 	for (wr = 0; wr < 500; wr++) {
9308173aa26SYury Norov 		DECLARE_BITMAP(tmp, 500);
9318173aa26SYury Norov 
9328173aa26SYury Norov 		bitmap_zero(copy, 500);
9338173aa26SYury Norov 		s = wr;
9348173aa26SYury Norov 
9358173aa26SYury Norov 		for_each_set_bitrange_from(s, e, orig, 500)
9368173aa26SYury Norov 			bitmap_set(copy, s, e - s);
9378173aa26SYury Norov 
9388173aa26SYury Norov 		bitmap_copy(tmp, orig, 500);
9398173aa26SYury Norov 		bitmap_clear(tmp, 0, wr);
9408173aa26SYury Norov 		expect_eq_bitmap(tmp, copy, 500);
9418173aa26SYury Norov 	}
9428173aa26SYury Norov }
9438173aa26SYury Norov 
test_for_each_clear_bitrange_from(void)9448173aa26SYury Norov static void __init test_for_each_clear_bitrange_from(void)
9458173aa26SYury Norov {
9468173aa26SYury Norov 	DECLARE_BITMAP(orig, 500);
9478173aa26SYury Norov 	DECLARE_BITMAP(copy, 500);
9488173aa26SYury Norov 	unsigned int wr, s, e;
9498173aa26SYury Norov 
9508173aa26SYury Norov 	bitmap_fill(orig, 500);
9518173aa26SYury Norov 
9528173aa26SYury Norov 	/* Set individual bits */
9538173aa26SYury Norov 	for (s = 0; s < 500; s += 10)
9548173aa26SYury Norov 		bitmap_clear(orig, s, 1);
9558173aa26SYury Norov 
9568173aa26SYury Norov 	/* Set range of bits */
9578173aa26SYury Norov 	bitmap_set(orig, 100, 50);
9588173aa26SYury Norov 
9598173aa26SYury Norov 	for (wr = 0; wr < 500; wr++) {
9608173aa26SYury Norov 		DECLARE_BITMAP(tmp, 500);
9618173aa26SYury Norov 
9628173aa26SYury Norov 		bitmap_fill(copy, 500);
9638173aa26SYury Norov 		s = wr;
9648173aa26SYury Norov 
9658173aa26SYury Norov 		for_each_clear_bitrange_from(s, e, orig, 500)
9668173aa26SYury Norov 			bitmap_clear(copy, s, e - s);
9678173aa26SYury Norov 
9688173aa26SYury Norov 		bitmap_copy(tmp, orig, 500);
9698173aa26SYury Norov 		bitmap_set(tmp, 0, wr);
9708173aa26SYury Norov 		expect_eq_bitmap(tmp, copy, 500);
9718173aa26SYury Norov 	}
9728173aa26SYury Norov }
9738173aa26SYury Norov 
974bcb32a1dSStefano Brivio struct test_bitmap_cut {
975bcb32a1dSStefano Brivio 	unsigned int first;
976bcb32a1dSStefano Brivio 	unsigned int cut;
977bcb32a1dSStefano Brivio 	unsigned int nbits;
978bcb32a1dSStefano Brivio 	unsigned long in[4];
979bcb32a1dSStefano Brivio 	unsigned long expected[4];
980bcb32a1dSStefano Brivio };
981bcb32a1dSStefano Brivio 
982bcb32a1dSStefano Brivio static struct test_bitmap_cut test_cut[] = {
983bcb32a1dSStefano Brivio 	{  0,  0,  8, { 0x0000000aUL, }, { 0x0000000aUL, }, },
984bcb32a1dSStefano Brivio 	{  0,  0, 32, { 0xdadadeadUL, }, { 0xdadadeadUL, }, },
985bcb32a1dSStefano Brivio 	{  0,  3,  8, { 0x000000aaUL, }, { 0x00000015UL, }, },
986bcb32a1dSStefano Brivio 	{  3,  3,  8, { 0x000000aaUL, }, { 0x00000012UL, }, },
987bcb32a1dSStefano Brivio 	{  0,  1, 32, { 0xa5a5a5a5UL, }, { 0x52d2d2d2UL, }, },
988bcb32a1dSStefano Brivio 	{  0,  8, 32, { 0xdeadc0deUL, }, { 0x00deadc0UL, }, },
989bcb32a1dSStefano Brivio 	{  1,  1, 32, { 0x5a5a5a5aUL, }, { 0x2d2d2d2cUL, }, },
990bcb32a1dSStefano Brivio 	{  0, 15, 32, { 0xa5a5a5a5UL, }, { 0x00014b4bUL, }, },
991bcb32a1dSStefano Brivio 	{  0, 16, 32, { 0xa5a5a5a5UL, }, { 0x0000a5a5UL, }, },
992bcb32a1dSStefano Brivio 	{ 15, 15, 32, { 0xa5a5a5a5UL, }, { 0x000125a5UL, }, },
993bcb32a1dSStefano Brivio 	{ 15, 16, 32, { 0xa5a5a5a5UL, }, { 0x0000a5a5UL, }, },
994bcb32a1dSStefano Brivio 	{ 16, 15, 32, { 0xa5a5a5a5UL, }, { 0x0001a5a5UL, }, },
995bcb32a1dSStefano Brivio 
996bcb32a1dSStefano Brivio 	{ BITS_PER_LONG, BITS_PER_LONG, BITS_PER_LONG,
997bcb32a1dSStefano Brivio 		{ 0xa5a5a5a5UL, 0xa5a5a5a5UL, },
998bcb32a1dSStefano Brivio 		{ 0xa5a5a5a5UL, 0xa5a5a5a5UL, },
999bcb32a1dSStefano Brivio 	},
1000bcb32a1dSStefano Brivio 	{ 1, BITS_PER_LONG - 1, BITS_PER_LONG,
1001bcb32a1dSStefano Brivio 		{ 0xa5a5a5a5UL, 0xa5a5a5a5UL, },
1002bcb32a1dSStefano Brivio 		{ 0x00000001UL, 0x00000001UL, },
1003bcb32a1dSStefano Brivio 	},
1004bcb32a1dSStefano Brivio 
1005bcb32a1dSStefano Brivio 	{ 0, BITS_PER_LONG * 2, BITS_PER_LONG * 2 + 1,
1006bcb32a1dSStefano Brivio 		{ 0xa5a5a5a5UL, 0x00000001UL, 0x00000001UL, 0x00000001UL },
1007bcb32a1dSStefano Brivio 		{ 0x00000001UL, },
1008bcb32a1dSStefano Brivio 	},
1009bcb32a1dSStefano Brivio 	{ 16, BITS_PER_LONG * 2 + 1, BITS_PER_LONG * 2 + 1 + 16,
1010bcb32a1dSStefano Brivio 		{ 0x0000ffffUL, 0x5a5a5a5aUL, 0x5a5a5a5aUL, 0x5a5a5a5aUL },
1011bcb32a1dSStefano Brivio 		{ 0x2d2dffffUL, },
1012bcb32a1dSStefano Brivio 	},
1013bcb32a1dSStefano Brivio };
1014bcb32a1dSStefano Brivio 
test_bitmap_cut(void)1015bcb32a1dSStefano Brivio static void __init test_bitmap_cut(void)
1016bcb32a1dSStefano Brivio {
1017bcb32a1dSStefano Brivio 	unsigned long b[5], *in = &b[1], *out = &b[0];	/* Partial overlap */
1018bcb32a1dSStefano Brivio 	int i;
1019bcb32a1dSStefano Brivio 
1020bcb32a1dSStefano Brivio 	for (i = 0; i < ARRAY_SIZE(test_cut); i++) {
1021bcb32a1dSStefano Brivio 		struct test_bitmap_cut *t = &test_cut[i];
1022bcb32a1dSStefano Brivio 
1023bcb32a1dSStefano Brivio 		memcpy(in, t->in, sizeof(t->in));
1024bcb32a1dSStefano Brivio 
1025bcb32a1dSStefano Brivio 		bitmap_cut(out, in, t->first, t->cut, t->nbits);
1026bcb32a1dSStefano Brivio 
1027bcb32a1dSStefano Brivio 		expect_eq_bitmap(t->expected, out, t->nbits);
1028bcb32a1dSStefano Brivio 	}
1029bcb32a1dSStefano Brivio }
1030bcb32a1dSStefano Brivio 
1031291f93caSBarry Song struct test_bitmap_print {
1032291f93caSBarry Song 	const unsigned long *bitmap;
1033291f93caSBarry Song 	unsigned long nbits;
1034291f93caSBarry Song 	const char *mask;
1035291f93caSBarry Song 	const char *list;
1036291f93caSBarry Song };
1037291f93caSBarry Song 
1038291f93caSBarry Song static const unsigned long small_bitmap[] __initconst = {
1039291f93caSBarry Song 	BITMAP_FROM_U64(0x3333333311111111ULL),
1040291f93caSBarry Song };
1041291f93caSBarry Song 
1042291f93caSBarry Song static const char small_mask[] __initconst = "33333333,11111111\n";
1043291f93caSBarry Song static const char small_list[] __initconst = "0,4,8,12,16,20,24,28,32-33,36-37,40-41,44-45,48-49,52-53,56-57,60-61\n";
1044291f93caSBarry Song 
1045291f93caSBarry Song static const unsigned long large_bitmap[] __initconst = {
1046291f93caSBarry Song 	BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
1047291f93caSBarry Song 	BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
1048291f93caSBarry Song 	BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
1049291f93caSBarry Song 	BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
1050291f93caSBarry Song 	BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
1051291f93caSBarry Song 	BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
1052291f93caSBarry Song 	BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
1053291f93caSBarry Song 	BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
1054291f93caSBarry Song 	BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
1055291f93caSBarry Song 	BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
1056291f93caSBarry Song 	BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
1057291f93caSBarry Song 	BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
1058291f93caSBarry Song 	BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
1059291f93caSBarry Song 	BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
1060291f93caSBarry Song 	BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
1061291f93caSBarry Song 	BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
1062291f93caSBarry Song 	BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
1063291f93caSBarry Song 	BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
1064291f93caSBarry Song 	BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
1065291f93caSBarry Song 	BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
1066291f93caSBarry Song };
1067291f93caSBarry Song 
1068291f93caSBarry Song static const char large_mask[] __initconst = "33333333,11111111,33333333,11111111,"
1069291f93caSBarry Song 					"33333333,11111111,33333333,11111111,"
1070291f93caSBarry Song 					"33333333,11111111,33333333,11111111,"
1071291f93caSBarry Song 					"33333333,11111111,33333333,11111111,"
1072291f93caSBarry Song 					"33333333,11111111,33333333,11111111,"
1073291f93caSBarry Song 					"33333333,11111111,33333333,11111111,"
1074291f93caSBarry Song 					"33333333,11111111,33333333,11111111,"
1075291f93caSBarry Song 					"33333333,11111111,33333333,11111111,"
1076291f93caSBarry Song 					"33333333,11111111,33333333,11111111,"
1077291f93caSBarry Song 					"33333333,11111111,33333333,11111111,"
1078291f93caSBarry Song 					"33333333,11111111,33333333,11111111,"
1079291f93caSBarry Song 					"33333333,11111111,33333333,11111111,"
1080291f93caSBarry Song 					"33333333,11111111,33333333,11111111,"
1081291f93caSBarry Song 					"33333333,11111111,33333333,11111111,"
1082291f93caSBarry Song 					"33333333,11111111,33333333,11111111,"
1083291f93caSBarry Song 					"33333333,11111111,33333333,11111111,"
1084291f93caSBarry Song 					"33333333,11111111,33333333,11111111,"
1085291f93caSBarry Song 					"33333333,11111111,33333333,11111111,"
1086291f93caSBarry Song 					"33333333,11111111,33333333,11111111,"
1087291f93caSBarry Song 					"33333333,11111111,33333333,11111111\n";
1088291f93caSBarry Song 
1089291f93caSBarry Song static const char large_list[] __initconst = /* more than 4KB */
1090291f93caSBarry Song 	"0,4,8,12,16,20,24,28,32-33,36-37,40-41,44-45,48-49,52-53,56-57,60-61,64,68,72,76,80,84,88,92,96-97,100-101,104-1"
1091291f93caSBarry Song 	"05,108-109,112-113,116-117,120-121,124-125,128,132,136,140,144,148,152,156,160-161,164-165,168-169,172-173,176-1"
1092291f93caSBarry Song 	"77,180-181,184-185,188-189,192,196,200,204,208,212,216,220,224-225,228-229,232-233,236-237,240-241,244-245,248-2"
1093291f93caSBarry Song 	"49,252-253,256,260,264,268,272,276,280,284,288-289,292-293,296-297,300-301,304-305,308-309,312-313,316-317,320,3"
1094291f93caSBarry Song 	"24,328,332,336,340,344,348,352-353,356-357,360-361,364-365,368-369,372-373,376-377,380-381,384,388,392,396,400,4"
1095291f93caSBarry Song 	"04,408,412,416-417,420-421,424-425,428-429,432-433,436-437,440-441,444-445,448,452,456,460,464,468,472,476,480-4"
1096291f93caSBarry Song 	"81,484-485,488-489,492-493,496-497,500-501,504-505,508-509,512,516,520,524,528,532,536,540,544-545,548-549,552-5"
1097291f93caSBarry Song 	"53,556-557,560-561,564-565,568-569,572-573,576,580,584,588,592,596,600,604,608-609,612-613,616-617,620-621,624-6"
1098291f93caSBarry Song 	"25,628-629,632-633,636-637,640,644,648,652,656,660,664,668,672-673,676-677,680-681,684-685,688-689,692-693,696-6"
1099291f93caSBarry Song 	"97,700-701,704,708,712,716,720,724,728,732,736-737,740-741,744-745,748-749,752-753,756-757,760-761,764-765,768,7"
1100291f93caSBarry Song 	"72,776,780,784,788,792,796,800-801,804-805,808-809,812-813,816-817,820-821,824-825,828-829,832,836,840,844,848,8"
1101291f93caSBarry Song 	"52,856,860,864-865,868-869,872-873,876-877,880-881,884-885,888-889,892-893,896,900,904,908,912,916,920,924,928-9"
1102291f93caSBarry Song 	"29,932-933,936-937,940-941,944-945,948-949,952-953,956-957,960,964,968,972,976,980,984,988,992-993,996-997,1000-"
1103291f93caSBarry Song 	"1001,1004-1005,1008-1009,1012-1013,1016-1017,1020-1021,1024,1028,1032,1036,1040,1044,1048,1052,1056-1057,1060-10"
1104291f93caSBarry Song 	"61,1064-1065,1068-1069,1072-1073,1076-1077,1080-1081,1084-1085,1088,1092,1096,1100,1104,1108,1112,1116,1120-1121"
1105291f93caSBarry Song 	",1124-1125,1128-1129,1132-1133,1136-1137,1140-1141,1144-1145,1148-1149,1152,1156,1160,1164,1168,1172,1176,1180,1"
1106291f93caSBarry Song 	"184-1185,1188-1189,1192-1193,1196-1197,1200-1201,1204-1205,1208-1209,1212-1213,1216,1220,1224,1228,1232,1236,124"
1107291f93caSBarry Song 	"0,1244,1248-1249,1252-1253,1256-1257,1260-1261,1264-1265,1268-1269,1272-1273,1276-1277,1280,1284,1288,1292,1296,"
1108291f93caSBarry Song 	"1300,1304,1308,1312-1313,1316-1317,1320-1321,1324-1325,1328-1329,1332-1333,1336-1337,1340-1341,1344,1348,1352,13"
1109291f93caSBarry Song 	"56,1360,1364,1368,1372,1376-1377,1380-1381,1384-1385,1388-1389,1392-1393,1396-1397,1400-1401,1404-1405,1408,1412"
1110291f93caSBarry Song 	",1416,1420,1424,1428,1432,1436,1440-1441,1444-1445,1448-1449,1452-1453,1456-1457,1460-1461,1464-1465,1468-1469,1"
1111291f93caSBarry Song 	"472,1476,1480,1484,1488,1492,1496,1500,1504-1505,1508-1509,1512-1513,1516-1517,1520-1521,1524-1525,1528-1529,153"
1112291f93caSBarry Song 	"2-1533,1536,1540,1544,1548,1552,1556,1560,1564,1568-1569,1572-1573,1576-1577,1580-1581,1584-1585,1588-1589,1592-"
1113291f93caSBarry Song 	"1593,1596-1597,1600,1604,1608,1612,1616,1620,1624,1628,1632-1633,1636-1637,1640-1641,1644-1645,1648-1649,1652-16"
1114291f93caSBarry Song 	"53,1656-1657,1660-1661,1664,1668,1672,1676,1680,1684,1688,1692,1696-1697,1700-1701,1704-1705,1708-1709,1712-1713"
1115291f93caSBarry Song 	",1716-1717,1720-1721,1724-1725,1728,1732,1736,1740,1744,1748,1752,1756,1760-1761,1764-1765,1768-1769,1772-1773,1"
1116291f93caSBarry Song 	"776-1777,1780-1781,1784-1785,1788-1789,1792,1796,1800,1804,1808,1812,1816,1820,1824-1825,1828-1829,1832-1833,183"
1117291f93caSBarry Song 	"6-1837,1840-1841,1844-1845,1848-1849,1852-1853,1856,1860,1864,1868,1872,1876,1880,1884,1888-1889,1892-1893,1896-"
1118291f93caSBarry Song 	"1897,1900-1901,1904-1905,1908-1909,1912-1913,1916-1917,1920,1924,1928,1932,1936,1940,1944,1948,1952-1953,1956-19"
1119291f93caSBarry Song 	"57,1960-1961,1964-1965,1968-1969,1972-1973,1976-1977,1980-1981,1984,1988,1992,1996,2000,2004,2008,2012,2016-2017"
1120291f93caSBarry Song 	",2020-2021,2024-2025,2028-2029,2032-2033,2036-2037,2040-2041,2044-2045,2048,2052,2056,2060,2064,2068,2072,2076,2"
1121291f93caSBarry Song 	"080-2081,2084-2085,2088-2089,2092-2093,2096-2097,2100-2101,2104-2105,2108-2109,2112,2116,2120,2124,2128,2132,213"
1122291f93caSBarry Song 	"6,2140,2144-2145,2148-2149,2152-2153,2156-2157,2160-2161,2164-2165,2168-2169,2172-2173,2176,2180,2184,2188,2192,"
1123291f93caSBarry Song 	"2196,2200,2204,2208-2209,2212-2213,2216-2217,2220-2221,2224-2225,2228-2229,2232-2233,2236-2237,2240,2244,2248,22"
1124291f93caSBarry Song 	"52,2256,2260,2264,2268,2272-2273,2276-2277,2280-2281,2284-2285,2288-2289,2292-2293,2296-2297,2300-2301,2304,2308"
1125291f93caSBarry Song 	",2312,2316,2320,2324,2328,2332,2336-2337,2340-2341,2344-2345,2348-2349,2352-2353,2356-2357,2360-2361,2364-2365,2"
1126291f93caSBarry Song 	"368,2372,2376,2380,2384,2388,2392,2396,2400-2401,2404-2405,2408-2409,2412-2413,2416-2417,2420-2421,2424-2425,242"
1127291f93caSBarry Song 	"8-2429,2432,2436,2440,2444,2448,2452,2456,2460,2464-2465,2468-2469,2472-2473,2476-2477,2480-2481,2484-2485,2488-"
1128291f93caSBarry Song 	"2489,2492-2493,2496,2500,2504,2508,2512,2516,2520,2524,2528-2529,2532-2533,2536-2537,2540-2541,2544-2545,2548-25"
1129291f93caSBarry Song 	"49,2552-2553,2556-2557\n";
1130291f93caSBarry Song 
1131291f93caSBarry Song static const struct test_bitmap_print test_print[] __initconst = {
1132291f93caSBarry Song 	{ small_bitmap, sizeof(small_bitmap) * BITS_PER_BYTE, small_mask, small_list },
1133291f93caSBarry Song 	{ large_bitmap, sizeof(large_bitmap) * BITS_PER_BYTE, large_mask, large_list },
1134291f93caSBarry Song };
1135291f93caSBarry Song 
test_bitmap_print_buf(void)1136291f93caSBarry Song static void __init test_bitmap_print_buf(void)
1137291f93caSBarry Song {
1138291f93caSBarry Song 	int i;
1139291f93caSBarry Song 
1140291f93caSBarry Song 	for (i = 0; i < ARRAY_SIZE(test_print); i++) {
1141291f93caSBarry Song 		const struct test_bitmap_print *t = &test_print[i];
1142291f93caSBarry Song 		int n;
1143291f93caSBarry Song 
1144291f93caSBarry Song 		n = bitmap_print_bitmask_to_buf(print_buf, t->bitmap, t->nbits,
1145291f93caSBarry Song 						0, 2 * PAGE_SIZE);
1146291f93caSBarry Song 		expect_eq_uint(strlen(t->mask) + 1, n);
1147291f93caSBarry Song 		expect_eq_str(t->mask, print_buf, n);
1148291f93caSBarry Song 
1149291f93caSBarry Song 		n = bitmap_print_list_to_buf(print_buf, t->bitmap, t->nbits,
1150291f93caSBarry Song 					     0, 2 * PAGE_SIZE);
1151291f93caSBarry Song 		expect_eq_uint(strlen(t->list) + 1, n);
1152291f93caSBarry Song 		expect_eq_str(t->list, print_buf, n);
1153291f93caSBarry Song 
1154291f93caSBarry Song 		/* test by non-zero offset */
1155291f93caSBarry Song 		if (strlen(t->list) > PAGE_SIZE) {
1156291f93caSBarry Song 			n = bitmap_print_list_to_buf(print_buf, t->bitmap, t->nbits,
1157291f93caSBarry Song 						     PAGE_SIZE, PAGE_SIZE);
1158291f93caSBarry Song 			expect_eq_uint(strlen(t->list) + 1 - PAGE_SIZE, n);
1159291f93caSBarry Song 			expect_eq_str(t->list + PAGE_SIZE, print_buf, n);
1160291f93caSBarry Song 		}
1161291f93caSBarry Song 	}
1162291f93caSBarry Song }
1163291f93caSBarry Song 
1164*2356d198SYury Norov /*
1165*2356d198SYury Norov  * FIXME: Clang breaks compile-time evaluations when KASAN and GCOV are enabled.
1166*2356d198SYury Norov  * To workaround it, GCOV is force-disabled in Makefile for this configuration.
1167*2356d198SYury Norov  */
test_bitmap_const_eval(void)1168dc34d503SAlexander Lobakin static void __init test_bitmap_const_eval(void)
1169dc34d503SAlexander Lobakin {
1170dc34d503SAlexander Lobakin 	DECLARE_BITMAP(bitmap, BITS_PER_LONG);
1171dc34d503SAlexander Lobakin 	unsigned long initvar = BIT(2);
1172dc34d503SAlexander Lobakin 	unsigned long bitopvar = 0;
1173dc34d503SAlexander Lobakin 	unsigned long var = 0;
1174dc34d503SAlexander Lobakin 	int res;
1175dc34d503SAlexander Lobakin 
1176dc34d503SAlexander Lobakin 	/*
1177dc34d503SAlexander Lobakin 	 * Compilers must be able to optimize all of those to compile-time
1178dc34d503SAlexander Lobakin 	 * constants on any supported optimization level (-O2, -Os) and any
1179dc34d503SAlexander Lobakin 	 * architecture. Otherwise, trigger a build bug.
1180dc34d503SAlexander Lobakin 	 * The whole function gets optimized out then, there's nothing to do
1181dc34d503SAlexander Lobakin 	 * in runtime.
1182dc34d503SAlexander Lobakin 	 */
1183dc34d503SAlexander Lobakin 
1184dc34d503SAlexander Lobakin 	/*
1185dc34d503SAlexander Lobakin 	 * Equals to `unsigned long bitmap[1] = { GENMASK(6, 5), }`.
1186dc34d503SAlexander Lobakin 	 * Clang on s390 optimizes bitops at compile-time as intended, but at
1187dc34d503SAlexander Lobakin 	 * the same time stops treating @bitmap and @bitopvar as compile-time
1188dc34d503SAlexander Lobakin 	 * constants after regular test_bit() is executed, thus triggering the
1189dc34d503SAlexander Lobakin 	 * build bugs below. So, call const_test_bit() there directly until
1190dc34d503SAlexander Lobakin 	 * the compiler is fixed.
1191dc34d503SAlexander Lobakin 	 */
1192dc34d503SAlexander Lobakin 	bitmap_clear(bitmap, 0, BITS_PER_LONG);
1193dc34d503SAlexander Lobakin 	if (!test_bit(7, bitmap))
1194dc34d503SAlexander Lobakin 		bitmap_set(bitmap, 5, 2);
1195dc34d503SAlexander Lobakin 
1196dc34d503SAlexander Lobakin 	/* Equals to `unsigned long bitopvar = BIT(20)` */
1197dc34d503SAlexander Lobakin 	__change_bit(31, &bitopvar);
1198dc34d503SAlexander Lobakin 	bitmap_shift_right(&bitopvar, &bitopvar, 11, BITS_PER_LONG);
1199dc34d503SAlexander Lobakin 
1200dc34d503SAlexander Lobakin 	/* Equals to `unsigned long var = BIT(25)` */
1201dc34d503SAlexander Lobakin 	var |= BIT(25);
1202dc34d503SAlexander Lobakin 	if (var & BIT(0))
1203dc34d503SAlexander Lobakin 		var ^= GENMASK(9, 6);
1204dc34d503SAlexander Lobakin 
1205dc34d503SAlexander Lobakin 	/* __const_hweight<32|64>(GENMASK(6, 5)) == 2 */
1206dc34d503SAlexander Lobakin 	res = bitmap_weight(bitmap, 20);
1207dc34d503SAlexander Lobakin 	BUILD_BUG_ON(!__builtin_constant_p(res));
1208dc34d503SAlexander Lobakin 	BUILD_BUG_ON(res != 2);
1209dc34d503SAlexander Lobakin 
1210dc34d503SAlexander Lobakin 	/* !(BIT(31) & BIT(18)) == 1 */
1211dc34d503SAlexander Lobakin 	res = !test_bit(18, &bitopvar);
1212dc34d503SAlexander Lobakin 	BUILD_BUG_ON(!__builtin_constant_p(res));
1213dc34d503SAlexander Lobakin 	BUILD_BUG_ON(!res);
1214dc34d503SAlexander Lobakin 
1215dc34d503SAlexander Lobakin 	/* BIT(2) & GENMASK(14, 8) == 0 */
1216dc34d503SAlexander Lobakin 	res = initvar & GENMASK(14, 8);
1217dc34d503SAlexander Lobakin 	BUILD_BUG_ON(!__builtin_constant_p(res));
1218dc34d503SAlexander Lobakin 	BUILD_BUG_ON(res);
1219dc34d503SAlexander Lobakin 
1220dc34d503SAlexander Lobakin 	/* ~BIT(25) */
1221dc34d503SAlexander Lobakin 	BUILD_BUG_ON(!__builtin_constant_p(~var));
1222dc34d503SAlexander Lobakin 	BUILD_BUG_ON(~var != ~BIT(25));
1223dc34d503SAlexander Lobakin }
1224dc34d503SAlexander Lobakin 
selftest(void)12256b1a4d5bSTobin C. Harding static void __init selftest(void)
12265fd003f5SDavid Decotigny {
1227ee3527bdSAndy Shevchenko 	test_zero_clear();
1228978f369cSAndy Shevchenko 	test_fill_set();
1229fe81814cSAndy Shevchenko 	test_copy();
123030544ed5SAndy Shevchenko 	test_replace();
12313aa56885SYury Norov 	test_bitmap_arr32();
12322c523550SYury Norov 	test_bitmap_arr64();
12337eb2e94eSYury Norov 	test_bitmap_parse();
12346df0d464SYury Norov 	test_bitmap_parselist();
1235db731300SYury Norov 	test_bitmap_printlist();
12363cc78125SMatthew Wilcox 	test_mem_optimisations();
1237bcb32a1dSStefano Brivio 	test_bitmap_cut();
1238291f93caSBarry Song 	test_bitmap_print_buf();
1239dc34d503SAlexander Lobakin 	test_bitmap_const_eval();
1240e3783c80SYury Norov 
1241e3783c80SYury Norov 	test_find_nth_bit();
12428173aa26SYury Norov 	test_for_each_set_bit();
12438173aa26SYury Norov 	test_for_each_set_bit_from();
12448173aa26SYury Norov 	test_for_each_clear_bit();
12458173aa26SYury Norov 	test_for_each_clear_bit_from();
12468173aa26SYury Norov 	test_for_each_set_bitrange();
12478173aa26SYury Norov 	test_for_each_clear_bitrange();
12488173aa26SYury Norov 	test_for_each_set_bitrange_from();
12498173aa26SYury Norov 	test_for_each_clear_bitrange_from();
12508173aa26SYury Norov 	test_for_each_set_clump8();
12518173aa26SYury Norov 	test_for_each_set_bit_wrap();
12525fd003f5SDavid Decotigny }
12535fd003f5SDavid Decotigny 
12546b1a4d5bSTobin C. Harding KSTM_MODULE_LOADERS(test_bitmap);
12555fd003f5SDavid Decotigny MODULE_AUTHOR("david decotigny <david.decotigny@googlers.com>");
12565fd003f5SDavid Decotigny MODULE_LICENSE("GPL");
1257