summaryrefslogtreecommitdiff
path: root/drivers/char
diff options
context:
space:
mode:
authorZijun Hu <zijun.hu@oss.qualcomm.com>2025-07-14 23:34:15 +0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2025-08-19 12:41:17 +0200
commit2334668aaf410382412b8c81f7014283f3e80354 (patch)
treee00ca11b366ae12cda06fce95ee123a560b35078 /drivers/char
parentf5597840ac907858ad2a462b00e4a68fd199121e (diff)
downloadlinux-2334668aaf410382412b8c81f7014283f3e80354.tar.gz
linux-2334668aaf410382412b8c81f7014283f3e80354.tar.bz2
linux-2334668aaf410382412b8c81f7014283f3e80354.zip
char: misc: Add a case to test registering miscdevice again without reinitialization
For miscdevice who wants dynamic minor, add a cast to test if it can be successfully registered again without reinitialization: 1) Provide Both miscdevice @dev_A and @dev_B want to request dynamic minor by initializing their minor to MISC_DYNAMIC_MINOR. 2) Register then de-register @dev_A. 3) Register @dev_B. 4) Register @dev_A again without reinitialization. 5) Check if @dev_A can be successfully registered. Signed-off-by: Zijun Hu <zijun.hu@oss.qualcomm.com> Link: https://lore.kernel.org/r/20250714-rfc_miscdev-v6-4-2ed949665bde@oss.qualcomm.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/misc_minor_kunit.c44
1 files changed, 44 insertions, 0 deletions
diff --git a/drivers/char/misc_minor_kunit.c b/drivers/char/misc_minor_kunit.c
index 3184f383bea8..6fc8b05169c5 100644
--- a/drivers/char/misc_minor_kunit.c
+++ b/drivers/char/misc_minor_kunit.c
@@ -602,6 +602,49 @@ static void miscdev_test_invalid_input(struct kunit *test)
misc_deregister(&misc_test);
}
+/*
+ * Verify if @miscdyn_a can still be registered successfully without
+ * reinitialization even if its minor ever owned was requested by
+ * another miscdevice such as @miscdyn_b.
+ */
+static void miscdev_test_dynamic_reentry(struct kunit *test)
+{
+ struct miscdevice miscdyn_a = {
+ .name = "miscdyn_a",
+ .minor = MISC_DYNAMIC_MINOR,
+ .fops = &miscdev_test_fops,
+ };
+ struct miscdevice miscdyn_b = {
+ .name = "miscdyn_b",
+ .minor = MISC_DYNAMIC_MINOR,
+ .fops = &miscdev_test_fops,
+ };
+ int ret, minor_a;
+
+ ret = misc_register(&miscdyn_a);
+ KUNIT_ASSERT_EQ(test, ret, 0);
+ KUNIT_EXPECT_TRUE(test, is_valid_dynamic_minor(miscdyn_a.minor));
+ minor_a = miscdyn_a.minor;
+ if (ret != 0)
+ return;
+ misc_deregister(&miscdyn_a);
+
+ ret = misc_register(&miscdyn_b);
+ KUNIT_ASSERT_EQ(test, ret, 0);
+ KUNIT_EXPECT_EQ(test, miscdyn_b.minor, minor_a);
+ if (ret != 0)
+ return;
+
+ ret = misc_register(&miscdyn_a);
+ KUNIT_ASSERT_EQ(test, ret, 0);
+ KUNIT_EXPECT_TRUE(test, is_valid_dynamic_minor(miscdyn_a.minor));
+ KUNIT_EXPECT_NE(test, miscdyn_a.minor, miscdyn_b.minor);
+ if (ret == 0)
+ misc_deregister(&miscdyn_a);
+
+ misc_deregister(&miscdyn_b);
+}
+
static struct kunit_case test_cases[] = {
KUNIT_CASE(kunit_static_minor),
KUNIT_CASE(kunit_misc_dynamic_minor),
@@ -611,6 +654,7 @@ static struct kunit_case test_cases[] = {
KUNIT_CASE(miscdev_test_duplicate_name),
KUNIT_CASE(miscdev_test_duplicate_name_leak),
KUNIT_CASE_PARAM(miscdev_test_duplicate_error, miscdev_gen_params),
+ KUNIT_CASE(miscdev_test_dynamic_reentry),
{}
};