Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Revert "char: misc: add test cases"

This reverts commit 45f0de4f8dc385cd8959d884cd89b3b84c76b7f9.

It breaks the build on many systems, so revert it for now.

Link: https://lore.kernel.org/r/20250501164501.0fc0ab68@canb.auug.org.au
Reported-by: Stephen Rothwell <sfr@canb.auug.org.au>
Cc: Thadeu Lima de Souza Cascardo <cascardo@igalia.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

+2 -587
+2 -587
drivers/misc/misc_minor_kunit.c
··· 3 3 #include <kunit/test-bug.h> 4 4 #include <linux/module.h> 5 5 #include <linux/miscdevice.h> 6 - #include <linux/fs.h> 7 - #include <linux/file.h> 8 - #include <linux/init_syscalls.h> 9 6 10 7 /* dynamic minor (2) */ 11 8 static struct miscdevice dev_dynamic_minor = { ··· 51 54 misc_deregister(&dev_misc_dynamic_minor); 52 55 } 53 56 54 - struct miscdev_test_case { 55 - const char *str; 56 - int minor; 57 - }; 58 - 59 - static struct miscdev_test_case miscdev_test_ranges[] = { 60 - { 61 - .str = "lower static range, top", 62 - .minor = 15, 63 - }, 64 - { 65 - .str = "upper static range, bottom", 66 - .minor = 130, 67 - }, 68 - { 69 - .str = "lower static range, bottom", 70 - .minor = 0, 71 - }, 72 - { 73 - .str = "upper static range, top", 74 - .minor = MISC_DYNAMIC_MINOR - 1, 75 - }, 76 - }; 77 - 78 - KUNIT_ARRAY_PARAM_DESC(miscdev, miscdev_test_ranges, str); 79 - 80 - static int miscdev_find_minors(struct kunit_suite *suite) 81 - { 82 - int ret; 83 - struct miscdevice miscstat = { 84 - .name = "miscstat", 85 - }; 86 - int i; 87 - 88 - for (i = 15; i >= 0; i--) { 89 - miscstat.minor = i; 90 - ret = misc_register(&miscstat); 91 - if (ret == 0) 92 - break; 93 - } 94 - 95 - if (ret == 0) { 96 - kunit_info(suite, "found misc device minor %d available\n", 97 - miscstat.minor); 98 - miscdev_test_ranges[0].minor = miscstat.minor; 99 - misc_deregister(&miscstat); 100 - } else { 101 - return ret; 102 - } 103 - 104 - for (i = 128; i < MISC_DYNAMIC_MINOR; i++) { 105 - miscstat.minor = i; 106 - ret = misc_register(&miscstat); 107 - if (ret == 0) 108 - break; 109 - } 110 - 111 - if (ret == 0) { 112 - kunit_info(suite, "found misc device minor %d available\n", 113 - miscstat.minor); 114 - miscdev_test_ranges[1].minor = miscstat.minor; 115 - misc_deregister(&miscstat); 116 - } else { 117 - return ret; 118 - } 119 - 120 - for (i = 0; i < miscdev_test_ranges[0].minor; i++) { 121 - miscstat.minor = i; 122 - ret = misc_register(&miscstat); 123 - if (ret == 0) 124 - break; 125 - } 126 - 127 - if (ret == 0) { 128 - kunit_info(suite, "found misc device minor %d available\n", 129 - miscstat.minor); 130 - miscdev_test_ranges[2].minor = miscstat.minor; 131 - misc_deregister(&miscstat); 132 - } else { 133 - return ret; 134 - } 135 - 136 - for (i = MISC_DYNAMIC_MINOR - 1; i > miscdev_test_ranges[1].minor; i--) { 137 - miscstat.minor = i; 138 - ret = misc_register(&miscstat); 139 - if (ret == 0) 140 - break; 141 - } 142 - 143 - if (ret == 0) { 144 - kunit_info(suite, "found misc device minor %d available\n", 145 - miscstat.minor); 146 - miscdev_test_ranges[3].minor = miscstat.minor; 147 - misc_deregister(&miscstat); 148 - } 149 - 150 - return ret; 151 - } 152 - 153 - static bool is_valid_dynamic_minor(int minor) 154 - { 155 - if (minor < 0) 156 - return false; 157 - if (minor == MISC_DYNAMIC_MINOR) 158 - return false; 159 - if (minor >= 0 && minor <= 15) 160 - return false; 161 - if (minor >= 128 && minor < MISC_DYNAMIC_MINOR) 162 - return false; 163 - return true; 164 - } 165 - 166 - static int miscdev_test_open(struct inode *inode, struct file *file) 167 - { 168 - return 0; 169 - } 170 - 171 - static const struct file_operations miscdev_test_fops = { 172 - .open = miscdev_test_open, 173 - }; 174 - 175 - static void __init miscdev_test_can_open(struct kunit *test, struct miscdevice *misc) 176 - { 177 - int ret; 178 - struct file *filp; 179 - char *devname; 180 - 181 - devname = kasprintf(GFP_KERNEL, "/dev/%s", misc->name); 182 - ret = init_mknod(devname, S_IFCHR | 0600, 183 - new_encode_dev(MKDEV(MISC_MAJOR, misc->minor))); 184 - if (ret != 0) 185 - KUNIT_FAIL(test, "failed to create node\n"); 186 - 187 - filp = filp_open(devname, O_RDONLY, 0); 188 - if (IS_ERR_OR_NULL(filp)) 189 - KUNIT_FAIL(test, "failed to open misc device: %ld\n", PTR_ERR(filp)); 190 - else 191 - fput(filp); 192 - 193 - init_unlink(devname); 194 - kfree(devname); 195 - } 196 - 197 - static void __init miscdev_test_static_basic(struct kunit *test) 198 - { 199 - struct miscdevice misc_test = { 200 - .name = "misc_test", 201 - .fops = &miscdev_test_fops, 202 - }; 203 - int ret; 204 - const struct miscdev_test_case *params = test->param_value; 205 - 206 - misc_test.minor = params->minor; 207 - 208 - ret = misc_register(&misc_test); 209 - KUNIT_EXPECT_EQ(test, ret, 0); 210 - KUNIT_EXPECT_EQ(test, misc_test.minor, params->minor); 211 - 212 - if (ret == 0) { 213 - miscdev_test_can_open(test, &misc_test); 214 - misc_deregister(&misc_test); 215 - } 216 - } 217 - 218 - static void __init miscdev_test_dynamic_basic(struct kunit *test) 219 - { 220 - struct miscdevice misc_test = { 221 - .minor = MISC_DYNAMIC_MINOR, 222 - .name = "misc_test", 223 - .fops = &miscdev_test_fops, 224 - }; 225 - int ret; 226 - 227 - ret = misc_register(&misc_test); 228 - KUNIT_EXPECT_EQ(test, ret, 0); 229 - KUNIT_EXPECT_TRUE(test, is_valid_dynamic_minor(misc_test.minor)); 230 - 231 - if (ret == 0) { 232 - miscdev_test_can_open(test, &misc_test); 233 - misc_deregister(&misc_test); 234 - } 235 - } 236 - 237 - static void miscdev_test_twice(struct kunit *test) 238 - { 239 - struct miscdevice misc_test = { 240 - .name = "misc_test", 241 - .fops = &miscdev_test_fops, 242 - }; 243 - int ret; 244 - const struct miscdev_test_case *params = test->param_value; 245 - 246 - misc_test.minor = params->minor; 247 - 248 - ret = misc_register(&misc_test); 249 - KUNIT_EXPECT_EQ(test, ret, 0); 250 - KUNIT_EXPECT_EQ(test, misc_test.minor, params->minor); 251 - if (ret == 0) 252 - misc_deregister(&misc_test); 253 - 254 - ret = misc_register(&misc_test); 255 - KUNIT_EXPECT_EQ(test, ret, 0); 256 - KUNIT_EXPECT_EQ(test, misc_test.minor, params->minor); 257 - if (ret == 0) 258 - misc_deregister(&misc_test); 259 - } 260 - 261 - static void miscdev_test_duplicate_minor(struct kunit *test) 262 - { 263 - struct miscdevice misc1 = { 264 - .name = "misc1", 265 - .fops = &miscdev_test_fops, 266 - }; 267 - struct miscdevice misc2 = { 268 - .name = "misc2", 269 - .fops = &miscdev_test_fops, 270 - }; 271 - int ret; 272 - const struct miscdev_test_case *params = test->param_value; 273 - 274 - misc1.minor = params->minor; 275 - misc2.minor = params->minor; 276 - 277 - ret = misc_register(&misc1); 278 - KUNIT_EXPECT_EQ(test, ret, 0); 279 - KUNIT_EXPECT_EQ(test, misc1.minor, params->minor); 280 - 281 - ret = misc_register(&misc2); 282 - KUNIT_EXPECT_EQ(test, ret, -EBUSY); 283 - if (ret == 0) 284 - misc_deregister(&misc2); 285 - 286 - misc_deregister(&misc1); 287 - } 288 - 289 - static void miscdev_test_duplicate_name(struct kunit *test) 290 - { 291 - struct miscdevice misc1 = { 292 - .minor = MISC_DYNAMIC_MINOR, 293 - .name = "misc1", 294 - .fops = &miscdev_test_fops, 295 - }; 296 - struct miscdevice misc2 = { 297 - .minor = MISC_DYNAMIC_MINOR, 298 - .name = "misc1", 299 - .fops = &miscdev_test_fops, 300 - }; 301 - int ret; 302 - 303 - ret = misc_register(&misc1); 304 - KUNIT_EXPECT_EQ(test, ret, 0); 305 - KUNIT_EXPECT_TRUE(test, is_valid_dynamic_minor(misc1.minor)); 306 - 307 - ret = misc_register(&misc2); 308 - KUNIT_EXPECT_EQ(test, ret, -EEXIST); 309 - if (ret == 0) 310 - misc_deregister(&misc2); 311 - 312 - misc_deregister(&misc1); 313 - } 314 - 315 - /* 316 - * Test that after a duplicate name failure, the reserved minor number is 317 - * freed to be allocated next. 318 - */ 319 - static void miscdev_test_duplicate_name_leak(struct kunit *test) 320 - { 321 - struct miscdevice misc1 = { 322 - .minor = MISC_DYNAMIC_MINOR, 323 - .name = "misc1", 324 - .fops = &miscdev_test_fops, 325 - }; 326 - struct miscdevice misc2 = { 327 - .minor = MISC_DYNAMIC_MINOR, 328 - .name = "misc1", 329 - .fops = &miscdev_test_fops, 330 - }; 331 - struct miscdevice misc3 = { 332 - .minor = MISC_DYNAMIC_MINOR, 333 - .name = "misc3", 334 - .fops = &miscdev_test_fops, 335 - }; 336 - int ret; 337 - int dyn_minor; 338 - 339 - ret = misc_register(&misc1); 340 - KUNIT_EXPECT_EQ(test, ret, 0); 341 - KUNIT_EXPECT_TRUE(test, is_valid_dynamic_minor(misc1.minor)); 342 - 343 - /* 344 - * Find out what is the next minor number available. 345 - */ 346 - ret = misc_register(&misc3); 347 - KUNIT_EXPECT_EQ(test, ret, 0); 348 - KUNIT_EXPECT_TRUE(test, is_valid_dynamic_minor(misc3.minor)); 349 - dyn_minor = misc3.minor; 350 - misc_deregister(&misc3); 351 - misc3.minor = MISC_DYNAMIC_MINOR; 352 - 353 - ret = misc_register(&misc2); 354 - KUNIT_EXPECT_EQ(test, ret, -EEXIST); 355 - if (ret == 0) 356 - misc_deregister(&misc2); 357 - 358 - /* 359 - * Now check that we can still get the same minor we found before. 360 - */ 361 - ret = misc_register(&misc3); 362 - KUNIT_EXPECT_EQ(test, ret, 0); 363 - KUNIT_EXPECT_TRUE(test, is_valid_dynamic_minor(misc3.minor)); 364 - KUNIT_EXPECT_EQ(test, misc3.minor, dyn_minor); 365 - misc_deregister(&misc3); 366 - 367 - misc_deregister(&misc1); 368 - } 369 - 370 - /* 371 - * Try to register a static minor with a duplicate name. That might not 372 - * deallocate the minor, preventing it from being used again. 373 - */ 374 - static void miscdev_test_duplicate_error(struct kunit *test) 375 - { 376 - struct miscdevice miscdyn = { 377 - .minor = MISC_DYNAMIC_MINOR, 378 - .name = "name1", 379 - .fops = &miscdev_test_fops, 380 - }; 381 - struct miscdevice miscstat = { 382 - .name = "name1", 383 - .fops = &miscdev_test_fops, 384 - }; 385 - struct miscdevice miscnew = { 386 - .name = "name2", 387 - .fops = &miscdev_test_fops, 388 - }; 389 - int ret; 390 - const struct miscdev_test_case *params = test->param_value; 391 - 392 - miscstat.minor = params->minor; 393 - miscnew.minor = params->minor; 394 - 395 - ret = misc_register(&miscdyn); 396 - KUNIT_EXPECT_EQ(test, ret, 0); 397 - KUNIT_EXPECT_TRUE(test, is_valid_dynamic_minor(miscdyn.minor)); 398 - 399 - ret = misc_register(&miscstat); 400 - KUNIT_EXPECT_EQ(test, ret, -EEXIST); 401 - if (ret == 0) 402 - misc_deregister(&miscstat); 403 - 404 - ret = misc_register(&miscnew); 405 - KUNIT_EXPECT_EQ(test, ret, 0); 406 - KUNIT_EXPECT_EQ(test, miscnew.minor, params->minor); 407 - if (ret == 0) 408 - misc_deregister(&miscnew); 409 - 410 - misc_deregister(&miscdyn); 411 - } 412 - 413 - static void __init miscdev_test_dynamic_only_range(struct kunit *test) 414 - { 415 - int ret; 416 - struct miscdevice *miscdev; 417 - const int dynamic_minors = 256; 418 - int i; 419 - 420 - miscdev = kunit_kmalloc_array(test, dynamic_minors, 421 - sizeof(struct miscdevice), 422 - GFP_KERNEL | __GFP_ZERO); 423 - 424 - for (i = 0; i < dynamic_minors; i++) { 425 - miscdev[i].minor = MISC_DYNAMIC_MINOR; 426 - miscdev[i].name = kasprintf(GFP_KERNEL, "misc_test%d", i); 427 - miscdev[i].fops = &miscdev_test_fops; 428 - ret = misc_register(&miscdev[i]); 429 - if (ret != 0) 430 - break; 431 - /* 432 - * This is the bug we are looking for! 433 - * We asked for a dynamic minor and got a minor in the static range space. 434 - */ 435 - if (miscdev[i].minor >= 0 && miscdev[i].minor <= 15) { 436 - KUNIT_FAIL(test, "misc_register allocated minor %d\n", miscdev[i].minor); 437 - i++; 438 - break; 439 - } 440 - KUNIT_EXPECT_TRUE(test, is_valid_dynamic_minor(miscdev[i].minor)); 441 - } 442 - 443 - for (i--; i >= 0; i--) { 444 - miscdev_test_can_open(test, &miscdev[i]); 445 - misc_deregister(&miscdev[i]); 446 - kfree_const(miscdev[i].name); 447 - } 448 - 449 - KUNIT_EXPECT_EQ(test, ret, 0); 450 - } 451 - 452 - static void __init miscdev_test_collision(struct kunit *test) 453 - { 454 - int ret; 455 - struct miscdevice *miscdev; 456 - struct miscdevice miscstat = { 457 - .name = "miscstat", 458 - .fops = &miscdev_test_fops, 459 - }; 460 - const int dynamic_minors = 256; 461 - int i; 462 - 463 - miscdev = kunit_kmalloc_array(test, dynamic_minors, 464 - sizeof(struct miscdevice), 465 - GFP_KERNEL | __GFP_ZERO); 466 - 467 - miscstat.minor = miscdev_test_ranges[0].minor; 468 - ret = misc_register(&miscstat); 469 - KUNIT_ASSERT_EQ(test, ret, 0); 470 - KUNIT_EXPECT_EQ(test, miscstat.minor, miscdev_test_ranges[0].minor); 471 - 472 - for (i = 0; i < dynamic_minors; i++) { 473 - miscdev[i].minor = MISC_DYNAMIC_MINOR; 474 - miscdev[i].name = kasprintf(GFP_KERNEL, "misc_test%d", i); 475 - miscdev[i].fops = &miscdev_test_fops; 476 - ret = misc_register(&miscdev[i]); 477 - if (ret != 0) 478 - break; 479 - KUNIT_EXPECT_TRUE(test, is_valid_dynamic_minor(miscdev[i].minor)); 480 - } 481 - 482 - for (i--; i >= 0; i--) { 483 - miscdev_test_can_open(test, &miscdev[i]); 484 - misc_deregister(&miscdev[i]); 485 - kfree_const(miscdev[i].name); 486 - } 487 - 488 - misc_deregister(&miscstat); 489 - 490 - KUNIT_EXPECT_EQ(test, ret, 0); 491 - } 492 - 493 - static void __init miscdev_test_collision_reverse(struct kunit *test) 494 - { 495 - int ret; 496 - struct miscdevice *miscdev; 497 - struct miscdevice miscstat = { 498 - .name = "miscstat", 499 - .fops = &miscdev_test_fops, 500 - }; 501 - const int dynamic_minors = 256; 502 - int i; 503 - 504 - miscdev = kunit_kmalloc_array(test, dynamic_minors, 505 - sizeof(struct miscdevice), 506 - GFP_KERNEL | __GFP_ZERO); 507 - 508 - for (i = 0; i < dynamic_minors; i++) { 509 - miscdev[i].minor = MISC_DYNAMIC_MINOR; 510 - miscdev[i].name = kasprintf(GFP_KERNEL, "misc_test%d", i); 511 - miscdev[i].fops = &miscdev_test_fops; 512 - ret = misc_register(&miscdev[i]); 513 - if (ret != 0) 514 - break; 515 - KUNIT_EXPECT_TRUE(test, is_valid_dynamic_minor(miscdev[i].minor)); 516 - } 517 - 518 - KUNIT_EXPECT_EQ(test, ret, 0); 519 - 520 - miscstat.minor = miscdev_test_ranges[0].minor; 521 - ret = misc_register(&miscstat); 522 - KUNIT_EXPECT_EQ(test, ret, 0); 523 - KUNIT_EXPECT_EQ(test, miscstat.minor, miscdev_test_ranges[0].minor); 524 - if (ret == 0) 525 - misc_deregister(&miscstat); 526 - 527 - for (i--; i >= 0; i--) { 528 - miscdev_test_can_open(test, &miscdev[i]); 529 - misc_deregister(&miscdev[i]); 530 - kfree_const(miscdev[i].name); 531 - } 532 - } 533 - 534 - static void __init miscdev_test_conflict(struct kunit *test) 535 - { 536 - int ret; 537 - struct miscdevice miscdyn = { 538 - .name = "miscdyn", 539 - .minor = MISC_DYNAMIC_MINOR, 540 - .fops = &miscdev_test_fops, 541 - }; 542 - struct miscdevice miscstat = { 543 - .name = "miscstat", 544 - .fops = &miscdev_test_fops, 545 - }; 546 - 547 - ret = misc_register(&miscdyn); 548 - KUNIT_ASSERT_EQ(test, ret, 0); 549 - KUNIT_EXPECT_TRUE(test, is_valid_dynamic_minor(miscdyn.minor)); 550 - 551 - /* 552 - * Try to register a static minor with the same minor as the 553 - * dynamic one. 554 - */ 555 - miscstat.minor = miscdyn.minor; 556 - ret = misc_register(&miscstat); 557 - KUNIT_EXPECT_EQ(test, ret, -EBUSY); 558 - if (ret == 0) 559 - misc_deregister(&miscstat); 560 - 561 - miscdev_test_can_open(test, &miscdyn); 562 - 563 - misc_deregister(&miscdyn); 564 - } 565 - 566 - static void __init miscdev_test_conflict_reverse(struct kunit *test) 567 - { 568 - int ret; 569 - struct miscdevice miscdyn = { 570 - .name = "miscdyn", 571 - .minor = MISC_DYNAMIC_MINOR, 572 - .fops = &miscdev_test_fops, 573 - }; 574 - struct miscdevice miscstat = { 575 - .name = "miscstat", 576 - .fops = &miscdev_test_fops, 577 - }; 578 - 579 - /* 580 - * Find the first available dynamic minor to use it as a static 581 - * minor later on. 582 - */ 583 - ret = misc_register(&miscdyn); 584 - KUNIT_ASSERT_EQ(test, ret, 0); 585 - KUNIT_EXPECT_TRUE(test, is_valid_dynamic_minor(miscdyn.minor)); 586 - miscstat.minor = miscdyn.minor; 587 - misc_deregister(&miscdyn); 588 - 589 - ret = misc_register(&miscstat); 590 - KUNIT_EXPECT_EQ(test, ret, 0); 591 - KUNIT_EXPECT_EQ(test, miscstat.minor, miscdyn.minor); 592 - 593 - /* 594 - * Try to register a dynamic minor after registering a static minor 595 - * within the dynamic range. It should work but get a different 596 - * minor. 597 - */ 598 - miscdyn.minor = MISC_DYNAMIC_MINOR; 599 - ret = misc_register(&miscdyn); 600 - KUNIT_EXPECT_EQ(test, ret, 0); 601 - KUNIT_EXPECT_NE(test, miscdyn.minor, miscstat.minor); 602 - KUNIT_EXPECT_TRUE(test, is_valid_dynamic_minor(miscdyn.minor)); 603 - if (ret == 0) 604 - misc_deregister(&miscdyn); 605 - 606 - miscdev_test_can_open(test, &miscstat); 607 - 608 - misc_deregister(&miscstat); 609 - } 610 - 611 57 static struct kunit_case test_cases[] = { 612 58 KUNIT_CASE(kunit_dynamic_minor), 613 59 KUNIT_CASE(kunit_static_minor), 614 60 KUNIT_CASE(kunit_misc_dynamic_minor), 615 - KUNIT_CASE_PARAM(miscdev_test_twice, miscdev_gen_params), 616 - KUNIT_CASE_PARAM(miscdev_test_duplicate_minor, miscdev_gen_params), 617 - KUNIT_CASE(miscdev_test_duplicate_name), 618 - KUNIT_CASE(miscdev_test_duplicate_name_leak), 619 - KUNIT_CASE_PARAM(miscdev_test_duplicate_error, miscdev_gen_params), 620 61 {} 621 62 }; 622 63 623 64 static struct kunit_suite test_suite = { 624 - .name = "miscdev", 625 - .suite_init = miscdev_find_minors, 65 + .name = "misc_minor_test", 626 66 .test_cases = test_cases, 627 67 }; 628 68 kunit_test_suite(test_suite); 629 69 630 - static struct kunit_case __refdata test_init_cases[] = { 631 - KUNIT_CASE_PARAM(miscdev_test_static_basic, miscdev_gen_params), 632 - KUNIT_CASE(miscdev_test_dynamic_basic), 633 - KUNIT_CASE(miscdev_test_dynamic_only_range), 634 - KUNIT_CASE(miscdev_test_collision), 635 - KUNIT_CASE(miscdev_test_collision_reverse), 636 - KUNIT_CASE(miscdev_test_conflict), 637 - KUNIT_CASE(miscdev_test_conflict_reverse), 638 - {} 639 - }; 640 - 641 - static struct kunit_suite test_init_suite = { 642 - .name = "miscdev_init", 643 - .suite_init = miscdev_find_minors, 644 - .test_cases = test_init_cases, 645 - }; 646 - kunit_test_init_section_suite(test_init_suite); 647 - 648 70 MODULE_LICENSE("GPL"); 649 71 MODULE_AUTHOR("Vimal Agrawal"); 650 - MODULE_AUTHOR("Thadeu Lima de Souza Cascardo <cascardo@igalia.com>"); 651 - MODULE_DESCRIPTION("Test module for misc character devices"); 72 + MODULE_DESCRIPTION("misc minor testing");