1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Test cases for printf facility. 4 */ 5 6 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 7 8 #include <linux/bitmap.h> 9 #include <linux/init.h> 10 #include <linux/kernel.h> 11 #include <linux/module.h> 12 #include <linux/printk.h> 13 #include <linux/slab.h> 14 #include <linux/string.h> 15 #include <linux/uaccess.h> 16 17 #include "../tools/testing/selftests/kselftest_module.h" 18 19 static unsigned total_tests __initdata; 20 static unsigned failed_tests __initdata; 21 22 static char pbl_buffer[PAGE_SIZE] __initdata; 23 24 25 static bool __init 26 __check_eq_uint(const char *srcfile, unsigned int line, 27 const unsigned int exp_uint, unsigned int x) 28 { 29 if (exp_uint != x) { 30 pr_err("[%s:%u] expected %u, got %u\n", 31 srcfile, line, exp_uint, x); 32 return false; 33 } 34 return true; 35 } 36 37 38 static bool __init 39 __check_eq_bitmap(const char *srcfile, unsigned int line, 40 const unsigned long *exp_bmap, const unsigned long *bmap, 41 unsigned int nbits) 42 { 43 if (!bitmap_equal(exp_bmap, bmap, nbits)) { 44 pr_warn("[%s:%u] bitmaps contents differ: expected \"%*pbl\", got \"%*pbl\"\n", 45 srcfile, line, 46 nbits, exp_bmap, nbits, bmap); 47 return false; 48 } 49 return true; 50 } 51 52 static bool __init 53 __check_eq_pbl(const char *srcfile, unsigned int line, 54 const char *expected_pbl, 55 const unsigned long *bitmap, unsigned int nbits) 56 { 57 snprintf(pbl_buffer, sizeof(pbl_buffer), "%*pbl", nbits, bitmap); 58 if (strcmp(expected_pbl, pbl_buffer)) { 59 pr_warn("[%s:%u] expected \"%s\", got \"%s\"\n", 60 srcfile, line, 61 expected_pbl, pbl_buffer); 62 return false; 63 } 64 return true; 65 } 66 67 static bool __init 68 __check_eq_u32_array(const char *srcfile, unsigned int line, 69 const u32 *exp_arr, unsigned int exp_len, 70 const u32 *arr, unsigned int len) __used; 71 static bool __init 72 __check_eq_u32_array(const char *srcfile, unsigned int line, 73 const u32 *exp_arr, unsigned int exp_len, 74 const u32 *arr, unsigned int len) 75 { 76 if (exp_len != len) { 77 pr_warn("[%s:%u] array length differ: expected %u, got %u\n", 78 srcfile, line, 79 exp_len, len); 80 return false; 81 } 82 83 if (memcmp(exp_arr, arr, len*sizeof(*arr))) { 84 pr_warn("[%s:%u] array contents differ\n", srcfile, line); 85 print_hex_dump(KERN_WARNING, " exp: ", DUMP_PREFIX_OFFSET, 86 32, 4, exp_arr, exp_len*sizeof(*exp_arr), false); 87 print_hex_dump(KERN_WARNING, " got: ", DUMP_PREFIX_OFFSET, 88 32, 4, arr, len*sizeof(*arr), false); 89 return false; 90 } 91 92 return true; 93 } 94 95 #define __expect_eq(suffix, ...) \ 96 ({ \ 97 int result = 0; \ 98 total_tests++; \ 99 if (!__check_eq_ ## suffix(__FILE__, __LINE__, \ 100 ##__VA_ARGS__)) { \ 101 failed_tests++; \ 102 result = 1; \ 103 } \ 104 result; \ 105 }) 106 107 #define expect_eq_uint(...) __expect_eq(uint, ##__VA_ARGS__) 108 #define expect_eq_bitmap(...) __expect_eq(bitmap, ##__VA_ARGS__) 109 #define expect_eq_pbl(...) __expect_eq(pbl, ##__VA_ARGS__) 110 #define expect_eq_u32_array(...) __expect_eq(u32_array, ##__VA_ARGS__) 111 112 static void __init test_zero_clear(void) 113 { 114 DECLARE_BITMAP(bmap, 1024); 115 116 /* Known way to set all bits */ 117 memset(bmap, 0xff, 128); 118 119 expect_eq_pbl("0-22", bmap, 23); 120 expect_eq_pbl("0-1023", bmap, 1024); 121 122 /* single-word bitmaps */ 123 bitmap_clear(bmap, 0, 9); 124 expect_eq_pbl("9-1023", bmap, 1024); 125 126 bitmap_zero(bmap, 35); 127 expect_eq_pbl("64-1023", bmap, 1024); 128 129 /* cross boundaries operations */ 130 bitmap_clear(bmap, 79, 19); 131 expect_eq_pbl("64-78,98-1023", bmap, 1024); 132 133 bitmap_zero(bmap, 115); 134 expect_eq_pbl("128-1023", bmap, 1024); 135 136 /* Zeroing entire area */ 137 bitmap_zero(bmap, 1024); 138 expect_eq_pbl("", bmap, 1024); 139 } 140 141 static void __init test_fill_set(void) 142 { 143 DECLARE_BITMAP(bmap, 1024); 144 145 /* Known way to clear all bits */ 146 memset(bmap, 0x00, 128); 147 148 expect_eq_pbl("", bmap, 23); 149 expect_eq_pbl("", bmap, 1024); 150 151 /* single-word bitmaps */ 152 bitmap_set(bmap, 0, 9); 153 expect_eq_pbl("0-8", bmap, 1024); 154 155 bitmap_fill(bmap, 35); 156 expect_eq_pbl("0-63", bmap, 1024); 157 158 /* cross boundaries operations */ 159 bitmap_set(bmap, 79, 19); 160 expect_eq_pbl("0-63,79-97", bmap, 1024); 161 162 bitmap_fill(bmap, 115); 163 expect_eq_pbl("0-127", bmap, 1024); 164 165 /* Zeroing entire area */ 166 bitmap_fill(bmap, 1024); 167 expect_eq_pbl("0-1023", bmap, 1024); 168 } 169 170 static void __init test_copy(void) 171 { 172 DECLARE_BITMAP(bmap1, 1024); 173 DECLARE_BITMAP(bmap2, 1024); 174 175 bitmap_zero(bmap1, 1024); 176 bitmap_zero(bmap2, 1024); 177 178 /* single-word bitmaps */ 179 bitmap_set(bmap1, 0, 19); 180 bitmap_copy(bmap2, bmap1, 23); 181 expect_eq_pbl("0-18", bmap2, 1024); 182 183 bitmap_set(bmap2, 0, 23); 184 bitmap_copy(bmap2, bmap1, 23); 185 expect_eq_pbl("0-18", bmap2, 1024); 186 187 /* multi-word bitmaps */ 188 bitmap_set(bmap1, 0, 109); 189 bitmap_copy(bmap2, bmap1, 1024); 190 expect_eq_pbl("0-108", bmap2, 1024); 191 192 bitmap_fill(bmap2, 1024); 193 bitmap_copy(bmap2, bmap1, 1024); 194 expect_eq_pbl("0-108", bmap2, 1024); 195 196 /* the following tests assume a 32- or 64-bit arch (even 128b 197 * if we care) 198 */ 199 200 bitmap_fill(bmap2, 1024); 201 bitmap_copy(bmap2, bmap1, 109); /* ... but 0-padded til word length */ 202 expect_eq_pbl("0-108,128-1023", bmap2, 1024); 203 204 bitmap_fill(bmap2, 1024); 205 bitmap_copy(bmap2, bmap1, 97); /* ... but aligned on word length */ 206 expect_eq_pbl("0-108,128-1023", bmap2, 1024); 207 } 208 209 #define PARSE_TIME 0x1 210 211 struct test_bitmap_parselist{ 212 const int errno; 213 const char *in; 214 const unsigned long *expected; 215 const int nbits; 216 const int flags; 217 }; 218 219 static const unsigned long exp[] __initconst = { 220 BITMAP_FROM_U64(1), 221 BITMAP_FROM_U64(2), 222 BITMAP_FROM_U64(0x0000ffff), 223 BITMAP_FROM_U64(0xffff0000), 224 BITMAP_FROM_U64(0x55555555), 225 BITMAP_FROM_U64(0xaaaaaaaa), 226 BITMAP_FROM_U64(0x11111111), 227 BITMAP_FROM_U64(0x22222222), 228 BITMAP_FROM_U64(0xffffffff), 229 BITMAP_FROM_U64(0xfffffffe), 230 BITMAP_FROM_U64(0x3333333311111111ULL), 231 BITMAP_FROM_U64(0xffffffff77777777ULL), 232 BITMAP_FROM_U64(0), 233 }; 234 235 static const unsigned long exp2[] __initconst = { 236 BITMAP_FROM_U64(0x3333333311111111ULL), 237 BITMAP_FROM_U64(0xffffffff77777777ULL) 238 }; 239 240 static const struct test_bitmap_parselist parselist_tests[] __initconst = { 241 #define step (sizeof(u64) / sizeof(unsigned long)) 242 243 {0, "0", &exp[0], 8, 0}, 244 {0, "1", &exp[1 * step], 8, 0}, 245 {0, "0-15", &exp[2 * step], 32, 0}, 246 {0, "16-31", &exp[3 * step], 32, 0}, 247 {0, "0-31:1/2", &exp[4 * step], 32, 0}, 248 {0, "1-31:1/2", &exp[5 * step], 32, 0}, 249 {0, "0-31:1/4", &exp[6 * step], 32, 0}, 250 {0, "1-31:1/4", &exp[7 * step], 32, 0}, 251 {0, "0-31:4/4", &exp[8 * step], 32, 0}, 252 {0, "1-31:4/4", &exp[9 * step], 32, 0}, 253 {0, "0-31:1/4,32-63:2/4", &exp[10 * step], 64, 0}, 254 {0, "0-31:3/4,32-63:4/4", &exp[11 * step], 64, 0}, 255 {0, " ,, 0-31:3/4 ,, 32-63:4/4 ,, ", &exp[11 * step], 64, 0}, 256 257 {0, "0-31:1/4,32-63:2/4,64-95:3/4,96-127:4/4", exp2, 128, 0}, 258 259 {0, "0-2047:128/256", NULL, 2048, PARSE_TIME}, 260 261 {0, "", &exp[12 * step], 8, 0}, 262 {0, "\n", &exp[12 * step], 8, 0}, 263 {0, ",, ,, , , ,", &exp[12 * step], 8, 0}, 264 {0, " , ,, , , ", &exp[12 * step], 8, 0}, 265 {0, " , ,, , , \n", &exp[12 * step], 8, 0}, 266 267 {-EINVAL, "-1", NULL, 8, 0}, 268 {-EINVAL, "-0", NULL, 8, 0}, 269 {-EINVAL, "10-1", NULL, 8, 0}, 270 {-EINVAL, "0-31:", NULL, 8, 0}, 271 {-EINVAL, "0-31:0", NULL, 8, 0}, 272 {-EINVAL, "0-31:0/", NULL, 8, 0}, 273 {-EINVAL, "0-31:0/0", NULL, 8, 0}, 274 {-EINVAL, "0-31:1/0", NULL, 8, 0}, 275 {-EINVAL, "0-31:10/1", NULL, 8, 0}, 276 {-EOVERFLOW, "0-98765432123456789:10/1", NULL, 8, 0}, 277 278 {-EINVAL, "a-31", NULL, 8, 0}, 279 {-EINVAL, "0-a1", NULL, 8, 0}, 280 {-EINVAL, "a-31:10/1", NULL, 8, 0}, 281 {-EINVAL, "0-31:a/1", NULL, 8, 0}, 282 {-EINVAL, "0-\n", NULL, 8, 0}, 283 }; 284 285 static void __init __test_bitmap_parselist(int is_user) 286 { 287 int i; 288 int err; 289 ktime_t time; 290 DECLARE_BITMAP(bmap, 2048); 291 char *mode = is_user ? "_user" : ""; 292 293 for (i = 0; i < ARRAY_SIZE(parselist_tests); i++) { 294 #define ptest parselist_tests[i] 295 296 if (is_user) { 297 mm_segment_t orig_fs = get_fs(); 298 size_t len = strlen(ptest.in); 299 300 set_fs(KERNEL_DS); 301 time = ktime_get(); 302 err = bitmap_parselist_user(ptest.in, len, 303 bmap, ptest.nbits); 304 time = ktime_get() - time; 305 set_fs(orig_fs); 306 } else { 307 time = ktime_get(); 308 err = bitmap_parselist(ptest.in, bmap, ptest.nbits); 309 time = ktime_get() - time; 310 } 311 312 if (err != ptest.errno) { 313 pr_err("parselist%s: %d: input is %s, errno is %d, expected %d\n", 314 mode, i, ptest.in, err, ptest.errno); 315 continue; 316 } 317 318 if (!err && ptest.expected 319 && !__bitmap_equal(bmap, ptest.expected, ptest.nbits)) { 320 pr_err("parselist%s: %d: input is %s, result is 0x%lx, expected 0x%lx\n", 321 mode, i, ptest.in, bmap[0], 322 *ptest.expected); 323 continue; 324 } 325 326 if (ptest.flags & PARSE_TIME) 327 pr_err("parselist%s: %d: input is '%s' OK, Time: %llu\n", 328 mode, i, ptest.in, time); 329 } 330 } 331 332 static void __init test_bitmap_parselist(void) 333 { 334 __test_bitmap_parselist(0); 335 } 336 337 static void __init test_bitmap_parselist_user(void) 338 { 339 __test_bitmap_parselist(1); 340 } 341 342 #define EXP_BYTES (sizeof(exp) * 8) 343 344 static void __init test_bitmap_arr32(void) 345 { 346 unsigned int nbits, next_bit; 347 u32 arr[sizeof(exp) / 4]; 348 DECLARE_BITMAP(bmap2, EXP_BYTES); 349 350 memset(arr, 0xa5, sizeof(arr)); 351 352 for (nbits = 0; nbits < EXP_BYTES; ++nbits) { 353 bitmap_to_arr32(arr, exp, nbits); 354 bitmap_from_arr32(bmap2, arr, nbits); 355 expect_eq_bitmap(bmap2, exp, nbits); 356 357 next_bit = find_next_bit(bmap2, 358 round_up(nbits, BITS_PER_LONG), nbits); 359 if (next_bit < round_up(nbits, BITS_PER_LONG)) 360 pr_err("bitmap_copy_arr32(nbits == %d:" 361 " tail is not safely cleared: %d\n", 362 nbits, next_bit); 363 364 if (nbits < EXP_BYTES - 32) 365 expect_eq_uint(arr[DIV_ROUND_UP(nbits, 32)], 366 0xa5a5a5a5); 367 } 368 } 369 370 static void noinline __init test_mem_optimisations(void) 371 { 372 DECLARE_BITMAP(bmap1, 1024); 373 DECLARE_BITMAP(bmap2, 1024); 374 unsigned int start, nbits; 375 376 for (start = 0; start < 1024; start += 8) { 377 for (nbits = 0; nbits < 1024 - start; nbits += 8) { 378 memset(bmap1, 0x5a, sizeof(bmap1)); 379 memset(bmap2, 0x5a, sizeof(bmap2)); 380 381 bitmap_set(bmap1, start, nbits); 382 __bitmap_set(bmap2, start, nbits); 383 if (!bitmap_equal(bmap1, bmap2, 1024)) { 384 printk("set not equal %d %d\n", start, nbits); 385 failed_tests++; 386 } 387 if (!__bitmap_equal(bmap1, bmap2, 1024)) { 388 printk("set not __equal %d %d\n", start, nbits); 389 failed_tests++; 390 } 391 392 bitmap_clear(bmap1, start, nbits); 393 __bitmap_clear(bmap2, start, nbits); 394 if (!bitmap_equal(bmap1, bmap2, 1024)) { 395 printk("clear not equal %d %d\n", start, nbits); 396 failed_tests++; 397 } 398 if (!__bitmap_equal(bmap1, bmap2, 1024)) { 399 printk("clear not __equal %d %d\n", start, 400 nbits); 401 failed_tests++; 402 } 403 } 404 } 405 } 406 407 static void __init selftest(void) 408 { 409 test_zero_clear(); 410 test_fill_set(); 411 test_copy(); 412 test_bitmap_arr32(); 413 test_bitmap_parselist(); 414 test_bitmap_parselist_user(); 415 test_mem_optimisations(); 416 } 417 418 KSTM_MODULE_LOADERS(test_bitmap); 419 MODULE_AUTHOR("david decotigny <david.decotigny@googlers.com>"); 420 MODULE_LICENSE("GPL"); 421