* [PATCH v2 0/2] char: misc: improve test and dynamic allocation
@ 2025-03-07 14:39 Thadeu Lima de Souza Cascardo
2025-03-07 14:39 ` [PATCH v2 1/2] char: misc: restrict the dynamic range to exclude reserved minors Thadeu Lima de Souza Cascardo
2025-03-07 14:39 ` [PATCH v2 2/2] char: misc: add test cases Thadeu Lima de Souza Cascardo
0 siblings, 2 replies; 4+ messages in thread
From: Thadeu Lima de Souza Cascardo @ 2025-03-07 14:39 UTC (permalink / raw)
To: Arnd Bergmann, Greg Kroah-Hartman
Cc: Andrew Morton, Dirk VanDerMerwe, Vimal Agrawal, linux-kernel,
Thadeu Lima de Souza Cascardo
This includes a change that prevents dynamic allocation from using a minor
number that belongs to the historically static reserved range, which is
still used by some drivers.
It also improves the test, including a lot of corner cases, specially ones
that would fail before past fixes.
Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@igalia.com>
---
Thadeu Lima de Souza Cascardo (2):
char: misc: restrict the dynamic range to exclude reserved minors
char: misc: add test cases
drivers/char/misc.c | 9 +-
drivers/misc/misc_minor_kunit.c | 509 +++++++++++++++++++++++++++++++++++++++-
2 files changed, 509 insertions(+), 9 deletions(-)
---
base-commit: 2397d61ee45cddb8f3bd3a3a9840ef0f0b5aa843
change-id: 20250307-misc-dynrange-d54c92a5e319
Best regards,
--
Thadeu Lima de Souza Cascardo <cascardo@igalia.com>
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v2 1/2] char: misc: restrict the dynamic range to exclude reserved minors
2025-03-07 14:39 [PATCH v2 0/2] char: misc: improve test and dynamic allocation Thadeu Lima de Souza Cascardo
@ 2025-03-07 14:39 ` Thadeu Lima de Souza Cascardo
2025-03-17 8:13 ` kernel test robot
2025-03-07 14:39 ` [PATCH v2 2/2] char: misc: add test cases Thadeu Lima de Souza Cascardo
1 sibling, 1 reply; 4+ messages in thread
From: Thadeu Lima de Souza Cascardo @ 2025-03-07 14:39 UTC (permalink / raw)
To: Arnd Bergmann, Greg Kroah-Hartman
Cc: Andrew Morton, Dirk VanDerMerwe, Vimal Agrawal, linux-kernel,
Thadeu Lima de Souza Cascardo
When this was first reported [1], the possibility of having sufficient
number of dynamic misc devices was theoretical, in the case of dlm driver.
In practice, its userspace never created more than one device.
What we know from commit ab760791c0cf ("char: misc: Increase the maximum
number of dynamic misc devices to 1048448"), is that the miscdevice
interface has been used for allocating more than the single-shot devices it
was designed for. And it is not only coresight_tmc, but many other drivers
are able to create multiple devices.
On systems like the ones described in the above commit, it is certain that
the dynamic allocation will allocate certain reserved minor numbers,
leading to failures when a later driver tries to claim its reserved number.
Instead of excluding the historically statically allocated range from
dynamic allocation, restrict the latter to minors above 255.
Since commit ab760791c0cf ("char: misc: Increase the maximum number of
dynamic misc devices to 1048448") has been applied, such range is already
possible. And given such devices already need to be dynamically created,
there should be no systems where this might become a problem.
[1] https://lore.kernel.org/all/1257813017-28598-3-git-send-email-cascardo@holoscopio.com/
Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@igalia.com>
---
drivers/char/misc.c | 9 ++-------
1 file changed, 2 insertions(+), 7 deletions(-)
diff --git a/drivers/char/misc.c b/drivers/char/misc.c
index f7dd455dd0dd3c7c9956e772b5ab8bd83a67a4a6..6a7f4f2f8d1227747a74be567bdc420a9e97f8f2 100644
--- a/drivers/char/misc.c
+++ b/drivers/char/misc.c
@@ -69,13 +69,8 @@ static int misc_minor_alloc(int minor)
if (minor == MISC_DYNAMIC_MINOR) {
/* allocate free id */
- ret = ida_alloc_max(&misc_minors_ida, DYNAMIC_MINORS - 1, GFP_KERNEL);
- if (ret >= 0) {
- ret = DYNAMIC_MINORS - ret - 1;
- } else {
- ret = ida_alloc_range(&misc_minors_ida, MISC_DYNAMIC_MINOR + 1,
- MINORMASK, GFP_KERNEL);
- }
+ ret = ida_alloc_range(&misc_minors_ida, MISC_DYNAMIC_MINOR + 1,
+ MINORMASK, GFP_KERNEL);
} else {
/* specific minor, check if it is in dynamic or misc dynamic range */
if (minor < DYNAMIC_MINORS) {
--
2.47.2
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH v2 2/2] char: misc: add test cases
2025-03-07 14:39 [PATCH v2 0/2] char: misc: improve test and dynamic allocation Thadeu Lima de Souza Cascardo
2025-03-07 14:39 ` [PATCH v2 1/2] char: misc: restrict the dynamic range to exclude reserved minors Thadeu Lima de Souza Cascardo
@ 2025-03-07 14:39 ` Thadeu Lima de Souza Cascardo
1 sibling, 0 replies; 4+ messages in thread
From: Thadeu Lima de Souza Cascardo @ 2025-03-07 14:39 UTC (permalink / raw)
To: Arnd Bergmann, Greg Kroah-Hartman
Cc: Andrew Morton, Dirk VanDerMerwe, Vimal Agrawal, linux-kernel,
Thadeu Lima de Souza Cascardo
Add test cases for static and dynamic minor number allocation and
deallocation.
While at it, improve description and test suite name.
Some of the cases include:
- that static and dynamic allocation reserved the expected minors.
- that registering duplicate minors or duplicate names will fail.
- that failing to create a sysfs file (due to duplicate names) will
deallocate the dynamic minor correctly.
- that dynamic allocation does not allocate a minor number in the static
range.
- that there are no collisions when mixing dynamic and static allocations.
- that registering a static number in the dynamic range won't conflict with
a dynamic allocation.
This last test verifies the bug fixed by commit 6d04d2b554b1 ("misc:
misc_minor_alloc to use ida for all dynamic/misc dynamic minors") has not
regressed.
Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@igalia.com>
---
drivers/misc/misc_minor_kunit.c | 509 +++++++++++++++++++++++++++++++++++++++-
1 file changed, 507 insertions(+), 2 deletions(-)
diff --git a/drivers/misc/misc_minor_kunit.c b/drivers/misc/misc_minor_kunit.c
index 293e0fb7e43edc330842722e1132d16cd23e3aa8..29f61531b27e737cf647f5ba20fb0422d95bdcbd 100644
--- a/drivers/misc/misc_minor_kunit.c
+++ b/drivers/misc/misc_minor_kunit.c
@@ -51,19 +51,524 @@ static void kunit_misc_dynamic_minor(struct kunit *test)
misc_deregister(&dev_misc_dynamic_minor);
}
+struct miscdev_test_case {
+ const char *str;
+ int minor;
+};
+
+static struct miscdev_test_case miscdev_test_ranges[] = {
+ {
+ .str = "lower static range, top",
+ .minor = 15,
+ },
+ {
+ .str = "upper static range, bottom",
+ .minor = 130,
+ },
+ {
+ .str = "lower static range, bottom",
+ .minor = 0,
+ },
+ {
+ .str = "upper static range, top",
+ .minor = MISC_DYNAMIC_MINOR - 1,
+ },
+};
+
+KUNIT_ARRAY_PARAM_DESC(miscdev, miscdev_test_ranges, str);
+
+static int miscdev_find_minors(struct kunit_suite *suite)
+{
+ int ret;
+ struct miscdevice miscstat = {
+ .name = "miscstat",
+ };
+ int i;
+
+ for (i = 15; i >= 0; i--) {
+ miscstat.minor = i;
+ ret = misc_register(&miscstat);
+ if (ret == 0)
+ break;
+ }
+
+ if (ret == 0) {
+ kunit_info(suite, "found misc device minor %d available\n",
+ miscstat.minor);
+ miscdev_test_ranges[0].minor = miscstat.minor;
+ misc_deregister(&miscstat);
+ } else {
+ return ret;
+ }
+
+ for (i = 128; i < MISC_DYNAMIC_MINOR; i++) {
+ miscstat.minor = i;
+ ret = misc_register(&miscstat);
+ if (ret == 0)
+ break;
+ }
+
+ if (ret == 0) {
+ kunit_info(suite, "found misc device minor %d available\n",
+ miscstat.minor);
+ miscdev_test_ranges[1].minor = miscstat.minor;
+ misc_deregister(&miscstat);
+ } else {
+ return ret;
+ }
+
+ for (i = 0; i < miscdev_test_ranges[0].minor; i++) {
+ miscstat.minor = i;
+ ret = misc_register(&miscstat);
+ if (ret == 0)
+ break;
+ }
+
+ if (ret == 0) {
+ kunit_info(suite, "found misc device minor %d available\n",
+ miscstat.minor);
+ miscdev_test_ranges[2].minor = miscstat.minor;
+ misc_deregister(&miscstat);
+ } else {
+ return ret;
+ }
+
+ for (i = MISC_DYNAMIC_MINOR - 1; i > miscdev_test_ranges[1].minor; i--) {
+ miscstat.minor = i;
+ ret = misc_register(&miscstat);
+ if (ret == 0)
+ break;
+ }
+
+ if (ret == 0) {
+ kunit_info(suite, "found misc device minor %d available\n",
+ miscstat.minor);
+ miscdev_test_ranges[3].minor = miscstat.minor;
+ misc_deregister(&miscstat);
+ }
+
+ return ret;
+}
+
+static bool is_valid_dynamic_minor(int minor)
+{
+ if (minor < 0)
+ return false;
+ if (minor == MISC_DYNAMIC_MINOR)
+ return false;
+ if (minor >= 0 && minor <= 15)
+ return false;
+ if (minor >= 128 && minor < MISC_DYNAMIC_MINOR)
+ return false;
+ return true;
+}
+
+static void miscdev_test_static_basic(struct kunit *test)
+{
+ struct miscdevice misc_test = {
+ .name = "misc_test",
+ };
+ int ret;
+ const struct miscdev_test_case *params = test->param_value;
+
+ misc_test.minor = params->minor;
+
+ ret = misc_register(&misc_test);
+ KUNIT_EXPECT_EQ(test, ret, 0);
+ KUNIT_EXPECT_EQ(test, misc_test.minor, params->minor);
+ if (ret == 0)
+ misc_deregister(&misc_test);
+}
+
+static void miscdev_test_dynamic_basic(struct kunit *test)
+{
+ struct miscdevice misc_test = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "misc_test",
+ };
+ int ret;
+
+ ret = misc_register(&misc_test);
+ KUNIT_EXPECT_EQ(test, ret, 0);
+ KUNIT_EXPECT_TRUE(test, is_valid_dynamic_minor(misc_test.minor));
+ if (ret == 0)
+ misc_deregister(&misc_test);
+}
+
+static void miscdev_test_twice(struct kunit *test)
+{
+ struct miscdevice misc_test = {
+ .name = "misc_test",
+ };
+ int ret;
+ const struct miscdev_test_case *params = test->param_value;
+
+ misc_test.minor = params->minor;
+
+ ret = misc_register(&misc_test);
+ KUNIT_EXPECT_EQ(test, ret, 0);
+ KUNIT_EXPECT_EQ(test, misc_test.minor, params->minor);
+ if (ret == 0)
+ misc_deregister(&misc_test);
+
+ ret = misc_register(&misc_test);
+ KUNIT_EXPECT_EQ(test, ret, 0);
+ KUNIT_EXPECT_EQ(test, misc_test.minor, params->minor);
+ if (ret == 0)
+ misc_deregister(&misc_test);
+}
+
+static void miscdev_test_duplicate_minor(struct kunit *test)
+{
+ struct miscdevice misc1 = {
+ .name = "misc1",
+ };
+ struct miscdevice misc2 = {
+ .name = "misc2",
+ };
+ int ret;
+ const struct miscdev_test_case *params = test->param_value;
+
+ misc1.minor = params->minor;
+ misc2.minor = params->minor;
+
+ ret = misc_register(&misc1);
+ KUNIT_EXPECT_EQ(test, ret, 0);
+ KUNIT_EXPECT_EQ(test, misc1.minor, params->minor);
+
+ ret = misc_register(&misc2);
+ KUNIT_EXPECT_EQ(test, ret, -EBUSY);
+ if (ret == 0)
+ misc_deregister(&misc2);
+
+ misc_deregister(&misc1);
+}
+
+static void miscdev_test_duplicate_name(struct kunit *test)
+{
+ struct miscdevice misc1 = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "misc1",
+ };
+ struct miscdevice misc2 = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "misc1",
+ };
+ int ret;
+
+ ret = misc_register(&misc1);
+ KUNIT_EXPECT_EQ(test, ret, 0);
+ KUNIT_EXPECT_TRUE(test, is_valid_dynamic_minor(misc1.minor));
+
+ ret = misc_register(&misc2);
+ KUNIT_EXPECT_EQ(test, ret, -EEXIST);
+ if (ret == 0)
+ misc_deregister(&misc2);
+
+ misc_deregister(&misc1);
+}
+
+/*
+ * Test that after a duplicate name failure, the reserved minor number is
+ * freed to be allocated next.
+ */
+static void miscdev_test_duplicate_name_leak(struct kunit *test)
+{
+ struct miscdevice misc1 = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "misc1",
+ };
+ struct miscdevice misc2 = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "misc1",
+ };
+ struct miscdevice misc3 = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "misc3",
+ };
+ int ret;
+ int dyn_minor;
+
+ ret = misc_register(&misc1);
+ KUNIT_EXPECT_EQ(test, ret, 0);
+ KUNIT_EXPECT_TRUE(test, is_valid_dynamic_minor(misc1.minor));
+
+ /*
+ * Find out what is the next minor number available.
+ */
+ ret = misc_register(&misc3);
+ KUNIT_EXPECT_EQ(test, ret, 0);
+ KUNIT_EXPECT_TRUE(test, is_valid_dynamic_minor(misc3.minor));
+ dyn_minor = misc3.minor;
+ misc_deregister(&misc3);
+ misc3.minor = MISC_DYNAMIC_MINOR;
+
+ ret = misc_register(&misc2);
+ KUNIT_EXPECT_EQ(test, ret, -EEXIST);
+ if (ret == 0)
+ misc_deregister(&misc2);
+
+ /*
+ * Now check that we can still get the same minor we found before.
+ */
+ ret = misc_register(&misc3);
+ KUNIT_EXPECT_EQ(test, ret, 0);
+ KUNIT_EXPECT_TRUE(test, is_valid_dynamic_minor(misc3.minor));
+ KUNIT_EXPECT_EQ(test, misc3.minor, dyn_minor);
+ misc_deregister(&misc3);
+
+ misc_deregister(&misc1);
+}
+
+/*
+ * Try to register a static minor with a duplicate name. That might not
+ * deallocate the minor, preventing it from being used again.
+ */
+static void miscdev_test_duplicate_error(struct kunit *test)
+{
+ struct miscdevice miscdyn = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "name1",
+ };
+ struct miscdevice miscstat = {
+ .name = "name1",
+ };
+ struct miscdevice miscnew = {
+ .name = "name2",
+ };
+ int ret;
+ const struct miscdev_test_case *params = test->param_value;
+
+ miscstat.minor = params->minor;
+ miscnew.minor = params->minor;
+
+ ret = misc_register(&miscdyn);
+ KUNIT_EXPECT_EQ(test, ret, 0);
+ KUNIT_EXPECT_TRUE(test, is_valid_dynamic_minor(miscdyn.minor));
+
+ ret = misc_register(&miscstat);
+ KUNIT_EXPECT_EQ(test, ret, -EEXIST);
+ if (ret == 0)
+ misc_deregister(&miscstat);
+
+ ret = misc_register(&miscnew);
+ KUNIT_EXPECT_EQ(test, ret, 0);
+ KUNIT_EXPECT_EQ(test, miscnew.minor, params->minor);
+ if (ret == 0)
+ misc_deregister(&miscnew);
+
+ misc_deregister(&miscdyn);
+}
+
+static void miscdev_test_dynamic_only_range(struct kunit *test)
+{
+ int ret;
+ struct miscdevice *miscdev;
+ const int dynamic_minors = 256;
+ int i;
+
+ miscdev = kunit_kmalloc_array(test, dynamic_minors,
+ sizeof(struct miscdevice),
+ GFP_KERNEL | __GFP_ZERO);
+
+ for (i = 0; i < dynamic_minors; i++) {
+ miscdev[i].minor = MISC_DYNAMIC_MINOR;
+ miscdev[i].name = kasprintf(GFP_KERNEL, "misc_test%d", i);
+ ret = misc_register(&miscdev[i]);
+ if (ret != 0)
+ break;
+ /*
+ * This is the bug we are looking for!
+ * We asked for a dynamic minor and got a minor in the static range space.
+ */
+ if (miscdev[i].minor >= 0 && miscdev[i].minor <= 15) {
+ KUNIT_FAIL(test, "misc_register allocated minor %d\n", miscdev[i].minor);
+ i++;
+ break;
+ }
+ KUNIT_EXPECT_TRUE(test, is_valid_dynamic_minor(miscdev[i].minor));
+ }
+
+ for (i--; i >= 0; i--) {
+ misc_deregister(&miscdev[i]);
+ kfree_const(miscdev[i].name);
+ }
+
+ KUNIT_EXPECT_EQ(test, ret, 0);
+}
+
+static void miscdev_test_collision(struct kunit *test)
+{
+ int ret;
+ struct miscdevice *miscdev;
+ struct miscdevice miscstat = {
+ .name = "miscstat",
+ };
+ const int dynamic_minors = 256;
+ int i;
+
+ miscdev = kunit_kmalloc_array(test, dynamic_minors,
+ sizeof(struct miscdevice),
+ GFP_KERNEL | __GFP_ZERO);
+
+ miscstat.minor = miscdev_test_ranges[0].minor;
+ ret = misc_register(&miscstat);
+ KUNIT_ASSERT_EQ(test, ret, 0);
+ KUNIT_EXPECT_EQ(test, miscstat.minor, miscdev_test_ranges[0].minor);
+
+ for (i = 0; i < dynamic_minors; i++) {
+ miscdev[i].minor = MISC_DYNAMIC_MINOR;
+ miscdev[i].name = kasprintf(GFP_KERNEL, "misc_test%d", i);
+ ret = misc_register(&miscdev[i]);
+ if (ret != 0)
+ break;
+ KUNIT_EXPECT_TRUE(test, is_valid_dynamic_minor(miscdev[i].minor));
+ }
+
+ for (i--; i >= 0; i--) {
+ misc_deregister(&miscdev[i]);
+ kfree_const(miscdev[i].name);
+ }
+
+ misc_deregister(&miscstat);
+
+ KUNIT_EXPECT_EQ(test, ret, 0);
+}
+
+static void miscdev_test_collision_reverse(struct kunit *test)
+{
+ int ret;
+ struct miscdevice *miscdev;
+ struct miscdevice miscstat = {
+ .name = "miscstat",
+ };
+ const int dynamic_minors = 256;
+ int i;
+
+ miscdev = kunit_kmalloc_array(test, dynamic_minors,
+ sizeof(struct miscdevice),
+ GFP_KERNEL | __GFP_ZERO);
+
+ for (i = 0; i < dynamic_minors; i++) {
+ miscdev[i].minor = MISC_DYNAMIC_MINOR;
+ miscdev[i].name = kasprintf(GFP_KERNEL, "misc_test%d", i);
+ ret = misc_register(&miscdev[i]);
+ if (ret != 0)
+ break;
+ KUNIT_EXPECT_TRUE(test, is_valid_dynamic_minor(miscdev[i].minor));
+ }
+
+ KUNIT_EXPECT_EQ(test, ret, 0);
+
+ miscstat.minor = miscdev_test_ranges[0].minor;
+ ret = misc_register(&miscstat);
+ KUNIT_EXPECT_EQ(test, ret, 0);
+ KUNIT_EXPECT_EQ(test, miscstat.minor, miscdev_test_ranges[0].minor);
+ if (ret == 0)
+ misc_deregister(&miscstat);
+
+ for (i--; i >= 0; i--) {
+ misc_deregister(&miscdev[i]);
+ kfree_const(miscdev[i].name);
+ }
+}
+
+static void miscdev_test_conflict(struct kunit *test)
+{
+ int ret;
+ struct miscdevice miscdyn = {
+ .name = "miscdyn",
+ .minor = MISC_DYNAMIC_MINOR,
+ };
+ struct miscdevice miscstat = {
+ .name = "miscstat",
+ };
+
+ ret = misc_register(&miscdyn);
+ KUNIT_ASSERT_EQ(test, ret, 0);
+ KUNIT_EXPECT_TRUE(test, is_valid_dynamic_minor(miscdyn.minor));
+
+ /*
+ * Try to register a static minor with the same minor as the
+ * dynamic one.
+ */
+ miscstat.minor = miscdyn.minor;
+ ret = misc_register(&miscstat);
+ KUNIT_EXPECT_EQ(test, ret, -EBUSY);
+ if (ret == 0)
+ misc_deregister(&miscstat);
+
+ misc_deregister(&miscdyn);
+}
+
+static void miscdev_test_conflict_reverse(struct kunit *test)
+{
+ int ret;
+ struct miscdevice miscdyn = {
+ .name = "miscdyn",
+ .minor = MISC_DYNAMIC_MINOR,
+ };
+ struct miscdevice miscstat = {
+ .name = "miscstat",
+ };
+
+ /*
+ * Find the first available dynamic minor to use it as a static
+ * minor later on.
+ */
+ ret = misc_register(&miscdyn);
+ KUNIT_ASSERT_EQ(test, ret, 0);
+ KUNIT_EXPECT_TRUE(test, is_valid_dynamic_minor(miscdyn.minor));
+ miscstat.minor = miscdyn.minor;
+ misc_deregister(&miscdyn);
+
+ ret = misc_register(&miscstat);
+ KUNIT_EXPECT_EQ(test, ret, 0);
+ KUNIT_EXPECT_EQ(test, miscstat.minor, miscdyn.minor);
+
+ /*
+ * Try to register a dynamic minor after registering a static minor
+ * within the dynamic range. It should work but get a different
+ * minor.
+ */
+ miscdyn.minor = MISC_DYNAMIC_MINOR;
+ ret = misc_register(&miscdyn);
+ KUNIT_EXPECT_EQ(test, ret, 0);
+ KUNIT_EXPECT_NE(test, miscdyn.minor, miscstat.minor);
+ KUNIT_EXPECT_TRUE(test, is_valid_dynamic_minor(miscdyn.minor));
+ if (ret == 0)
+ misc_deregister(&miscdyn);
+
+ misc_deregister(&miscstat);
+}
+
static struct kunit_case test_cases[] = {
KUNIT_CASE(kunit_dynamic_minor),
KUNIT_CASE(kunit_static_minor),
KUNIT_CASE(kunit_misc_dynamic_minor),
+ KUNIT_CASE_PARAM(miscdev_test_static_basic, miscdev_gen_params),
+ KUNIT_CASE(miscdev_test_dynamic_basic),
+ KUNIT_CASE_PARAM(miscdev_test_twice, miscdev_gen_params),
+ KUNIT_CASE_PARAM(miscdev_test_duplicate_minor, miscdev_gen_params),
+ 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_only_range),
+ KUNIT_CASE(miscdev_test_collision),
+ KUNIT_CASE(miscdev_test_collision_reverse),
+ KUNIT_CASE(miscdev_test_conflict),
+ KUNIT_CASE(miscdev_test_conflict_reverse),
{}
};
static struct kunit_suite test_suite = {
- .name = "misc_minor_test",
+ .name = "miscdev",
+ .suite_init = miscdev_find_minors,
.test_cases = test_cases,
};
kunit_test_suite(test_suite);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Vimal Agrawal");
-MODULE_DESCRIPTION("misc minor testing");
+MODULE_AUTHOR("Thadeu Lima de Souza Cascardo <cascardo@igalia.com>");
+MODULE_DESCRIPTION("Test module for misc character devices");
--
2.47.2
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH v2 1/2] char: misc: restrict the dynamic range to exclude reserved minors
2025-03-07 14:39 ` [PATCH v2 1/2] char: misc: restrict the dynamic range to exclude reserved minors Thadeu Lima de Souza Cascardo
@ 2025-03-17 8:13 ` kernel test robot
0 siblings, 0 replies; 4+ messages in thread
From: kernel test robot @ 2025-03-17 8:13 UTC (permalink / raw)
To: Thadeu Lima de Souza Cascardo
Cc: oe-lkp, lkp, linux-kernel, Arnd Bergmann, Greg Kroah-Hartman,
Andrew Morton, Dirk VanDerMerwe, Vimal Agrawal,
Thadeu Lima de Souza Cascardo, oliver.sang
Hello,
kernel test robot noticed "kernel-selftests.sgx.test_sgx.enclave.unclobbered_vdso.fail" on:
commit: 47b2b7ca1ce4d1dbbaae0334436869c9e987d03c ("[PATCH v2 1/2] char: misc: restrict the dynamic range to exclude reserved minors")
url: https://github.com/intel-lab-lkp/linux/commits/Thadeu-Lima-de-Souza-Cascardo/char-misc-restrict-the-dynamic-range-to-exclude-reserved-minors/20250307-231711
patch link: https://lore.kernel.org/all/20250307-misc-dynrange-v2-1-6fe19032ef76@igalia.com/
patch subject: [PATCH v2 1/2] char: misc: restrict the dynamic range to exclude reserved minors
in testcase: kernel-selftests
version: kernel-selftests-x86_64-7ff71e6d9239-1_20250215
with following parameters:
group: sgx
config: x86_64-rhel-9.4-kselftests
compiler: gcc-12
test machine: 16 threads 1 sockets Intel(R) Xeon(R) E-2278G CPU @ 3.40GHz (Coffee Lake-E) with 32G memory
(please refer to attached dmesg/kmsg for entire log/backtrace)
here is a comparison with more details, cases failed upon this commit while
pass on parent:
=========================================================================================
tbox_group/testcase/rootfs/kconfig/compiler/group:
lkp-cfl-e1/kernel-selftests/debian-12-x86_64-20240206.cgz/x86_64-rhel-9.4-kselftests/gcc-12/sgx
2397d61ee45cddb8 47b2b7ca1ce4d1dbbaae0334436
---------------- ---------------------------
fail:runs %reproduction fail:runs
| | |
:9 67% 6:6 kernel-selftests.sgx.test_sgx.enclave.clobbered_vdso.fail
:9 67% 6:6 kernel-selftests.sgx.test_sgx.enclave.clobbered_vdso_and_user_function.fail
:9 67% 6:6 kernel-selftests.sgx.test_sgx.enclave.pte_permissions.fail
:9 67% 6:6 kernel-selftests.sgx.test_sgx.enclave.tcs_entry.fail
:9 67% 6:6 kernel-selftests.sgx.test_sgx.enclave.unclobbered_vdso.fail
:9 67% 6:6 kernel-selftests.sgx.test_sgx.enclave.unclobbered_vdso_oversubscribed.fail
:9 67% 6:6 kernel-selftests.sgx.test_sgx.fail
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <oliver.sang@intel.com>
| Closes: https://lore.kernel.org/oe-lkp/202503171507.6c8093d0-lkp@intel.com
2025-03-11 18:27:45 make quicktest=1 run_tests -C sgx
make: Entering directory '/usr/src/perf_selftests-x86_64-rhel-9.4-kselftests-47b2b7ca1ce4d1dbbaae0334436869c9e987d03c/tools/testing/selftests/sgx'
TAP version 13
1..1
# timeout set to 300
# selftests: sgx: test_sgx
# TAP version 13
# 1..16
# # Starting 16 tests from 1 test cases.
# # RUN enclave.unclobbered_vdso ...
# Unable to open /dev/sgx_enclave: No such device or address
# # main.c:188:unclobbered_vdso:Failed to load the test enclave.
# # main.c:287:unclobbered_vdso:Expected 0 (0) != setup_test_encl(ENCL_HEAP_SIZE_DEFAULT, &self->encl, _metadata) (0)
# # unclobbered_vdso: Test terminated by assertion
# # FAIL enclave.unclobbered_vdso
# not ok 1 enclave.unclobbered_vdso
# # RUN enclave.unclobbered_vdso_oversubscribed ...
# Unable to open /dev/sgx_enclave: No such device or address
# # main.c:188:unclobbered_vdso_oversubscribed:Failed to load the test enclave.
# # main.c:360:unclobbered_vdso_oversubscribed:Expected 0 (0) != setup_test_encl(total_mem, &self->encl, _metadata) (0)
# # unclobbered_vdso_oversubscribed: Test terminated by assertion
# # FAIL enclave.unclobbered_vdso_oversubscribed
# not ok 2 enclave.unclobbered_vdso_oversubscribed
# # RUN enclave.unclobbered_vdso_oversubscribed_remove ...
# # main.c:402:unclobbered_vdso_oversubscribed_remove:Creating an enclave with 198705152 bytes heap may take a while ...
# Unable to open /dev/sgx_enclave: No such device or address
# # main.c:188:unclobbered_vdso_oversubscribed_remove:Failed to load the test enclave.
# # main.c:404:unclobbered_vdso_oversubscribed_remove:Expected 0 (0) != setup_test_encl(total_mem, &self->encl, _metadata) (0)
# # unclobbered_vdso_oversubscribed_remove: Test terminated by assertion
# # FAIL enclave.unclobbered_vdso_oversubscribed_remove
# not ok 3 enclave.unclobbered_vdso_oversubscribed_remove
# # RUN enclave.clobbered_vdso ...
# Unable to open /dev/sgx_enclave: No such device or address
# # main.c:188:clobbered_vdso:Failed to load the test enclave.
# # main.c:509:clobbered_vdso:Expected 0 (0) != setup_test_encl(ENCL_HEAP_SIZE_DEFAULT, &self->encl, _metadata) (0)
# # clobbered_vdso: Test terminated by assertion
# # FAIL enclave.clobbered_vdso
# not ok 4 enclave.clobbered_vdso
# # RUN enclave.clobbered_vdso_and_user_function ...
# Unable to open /dev/sgx_enclave: No such device or address
# # main.c:188:clobbered_vdso_and_user_function:Failed to load the test enclave.
# # main.c:545:clobbered_vdso_and_user_function:Expected 0 (0) != setup_test_encl(ENCL_HEAP_SIZE_DEFAULT, &self->encl, _metadata) (0)
# # clobbered_vdso_and_user_function: Test terminated by assertion
# # FAIL enclave.clobbered_vdso_and_user_function
# not ok 5 enclave.clobbered_vdso_and_user_function
# # RUN enclave.tcs_entry ...
# Unable to open /dev/sgx_enclave: No such device or address
# # main.c:188:tcs_entry:Failed to load the test enclave.
# # main.c:578:tcs_entry:Expected 0 (0) != setup_test_encl(ENCL_HEAP_SIZE_DEFAULT, &self->encl, _metadata) (0)
# # tcs_entry: Test terminated by assertion
# # FAIL enclave.tcs_entry
# not ok 6 enclave.tcs_entry
# # RUN enclave.pte_permissions ...
# Unable to open /dev/sgx_enclave: No such device or address
# # main.c:188:pte_permissions:Failed to load the test enclave.
# # main.c:623:pte_permissions:Expected 0 (0) != setup_test_encl(ENCL_HEAP_SIZE_DEFAULT, &self->encl, _metadata) (0)
# # pte_permissions: Test terminated by assertion
# # FAIL enclave.pte_permissions
# not ok 7 enclave.pte_permissions
# # RUN enclave.tcs_permissions ...
# Unable to open /dev/sgx_enclave: No such device or address
# # main.c:188:tcs_permissions:Failed to load the test enclave.
# # main.c:725:tcs_permissions:Expected 0 (0) != setup_test_encl(ENCL_HEAP_SIZE_DEFAULT, &self->encl, _metadata) (0)
# # tcs_permissions: Test terminated by assertion
# # FAIL enclave.tcs_permissions
# not ok 8 enclave.tcs_permissions
# # RUN enclave.epcm_permissions ...
# Unable to open /dev/sgx_enclave: No such device or address
# # main.c:188:epcm_permissions:Failed to load the test enclave.
# # main.c:788:epcm_permissions:Expected 0 (0) != setup_test_encl(ENCL_HEAP_SIZE_DEFAULT, &self->encl, _metadata) (0)
# # epcm_permissions: Test terminated by assertion
# # FAIL enclave.epcm_permissions
# not ok 9 enclave.epcm_permissions
# # RUN enclave.augment ...
# # SKIP SGX2 not supported
# # OK enclave.augment
# ok 10 enclave.augment # SKIP SGX2 not supported
# # RUN enclave.augment_via_eaccept ...
# # SKIP SGX2 not supported
# # OK enclave.augment_via_eaccept
# ok 11 enclave.augment_via_eaccept # SKIP SGX2 not supported
# # RUN enclave.tcs_create ...
# Unable to open /dev/sgx_enclave: No such device or address
# # main.c:188:tcs_create:Failed to load the test enclave.
# # main.c:1240:tcs_create:Expected 0 (0) != setup_test_encl(ENCL_HEAP_SIZE_DEFAULT, &self->encl, _metadata) (0)
# # tcs_create: Test terminated by assertion
# # FAIL enclave.tcs_create
# not ok 12 enclave.tcs_create
# # RUN enclave.remove_added_page_no_eaccept ...
# Unable to open /dev/sgx_enclave: No such device or address
# # main.c:188:remove_added_page_no_eaccept:Failed to load the test enclave.
# # main.c:1571:remove_added_page_no_eaccept:Expected 0 (0) != setup_test_encl(ENCL_HEAP_SIZE_DEFAULT, &self->encl, _metadata) (0)
# # remove_added_page_no_eaccept: Test terminated by assertion
# # FAIL enclave.remove_added_page_no_eaccept
# not ok 13 enclave.remove_added_page_no_eaccept
# # RUN enclave.remove_added_page_invalid_access ...
# Unable to open /dev/sgx_enclave: No such device or address
# # main.c:188:remove_added_page_invalid_access:Failed to load the test enclave.
# # main.c:1682:remove_added_page_invalid_access:Expected 0 (0) != setup_test_encl(ENCL_HEAP_SIZE_DEFAULT, &self->encl, _metadata) (0)
# # remove_added_page_invalid_access: Test terminated by assertion
# # FAIL enclave.remove_added_page_invalid_access
# not ok 14 enclave.remove_added_page_invalid_access
# # RUN enclave.remove_added_page_invalid_access_after_eaccept ...
# Unable to open /dev/sgx_enclave: No such device or address
# # main.c:188:remove_added_page_invalid_access_after_eaccept:Failed to load the test enclave.
# # main.c:1797:remove_added_page_invalid_access_after_eaccept:Expected 0 (0) != setup_test_encl(ENCL_HEAP_SIZE_DEFAULT, &self->encl, _metadata) (0)
# # remove_added_page_invalid_access_after_eaccept: Test terminated by assertion
# # FAIL enclave.remove_added_page_invalid_access_after_eaccept
# not ok 15 enclave.remove_added_page_invalid_access_after_eaccept
# # RUN enclave.remove_untouched_page ...
# Unable to open /dev/sgx_enclave: No such device or address
# # main.c:188:remove_untouched_page:Failed to load the test enclave.
# # main.c:1921:remove_untouched_page:Expected 0 (0) != setup_test_encl(ENCL_HEAP_SIZE_DEFAULT, &self->encl, _metadata) (0)
# # remove_untouched_page: Test terminated by assertion
# # FAIL enclave.remove_untouched_page
# not ok 16 enclave.remove_untouched_page
# # FAILED: 2 / 16 tests passed.
# # 2 skipped test(s) detected. Consider enabling relevant config options to improve coverage.
# # Totals: pass:0 fail:14 xfail:0 xpass:0 skip:2 error:0
not ok 1 selftests: sgx: test_sgx # exit=1
make: Leaving directory '/usr/src/perf_selftests-x86_64-rhel-9.4-kselftests-47b2b7ca1ce4d1dbbaae0334436869c9e987d03c/tools/testing/selftests/sgx'
The kernel config and materials to reproduce are available at:
https://download.01.org/0day-ci/archive/20250317/202503171507.6c8093d0-lkp@intel.com
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2025-03-17 8:13 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-03-07 14:39 [PATCH v2 0/2] char: misc: improve test and dynamic allocation Thadeu Lima de Souza Cascardo
2025-03-07 14:39 ` [PATCH v2 1/2] char: misc: restrict the dynamic range to exclude reserved minors Thadeu Lima de Souza Cascardo
2025-03-17 8:13 ` kernel test robot
2025-03-07 14:39 ` [PATCH v2 2/2] char: misc: add test cases Thadeu Lima de Souza Cascardo
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.