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

Configure Feed

Select the types of activity you want to include in your feed.

kcov: Add interrupt handling self test

Add a boot self test that can catch sprious coverage from interrupts.
The coverage callback filters out interrupt code, but only after the
handler updates preempt count. Some code periodically leaks out
of that section and leads to spurious coverage.
Add a best-effort (but simple) test that is likely to catch such bugs.
If the test is enabled on CI systems that use KCOV, they should catch
any issues fast.

Signed-off-by: Dmitry Vyukov <dvyukov@google.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Alexander Potapenko <glider@google.com>
Reviewed-by: Marco Elver <elver@google.com>
Reviewed-by: Andrey Konovalov <andreyknvl@gmail.com>
Link: https://lore.kernel.org/all/7662127c97e29da1a748ad1c1539dd7b65b737b2.1718092070.git.dvyukov@google.com


authored by

Dmitry Vyukov and committed by
Thomas Gleixner
6cd0dd93 477d81a1

+39
+31
kernel/kcov.c
··· 11 11 #include <linux/fs.h> 12 12 #include <linux/hashtable.h> 13 13 #include <linux/init.h> 14 + #include <linux/jiffies.h> 14 15 #include <linux/kmsan-checks.h> 15 16 #include <linux/mm.h> 16 17 #include <linux/preempt.h> ··· 1059 1058 } 1060 1059 EXPORT_SYMBOL(kcov_common_handle); 1061 1060 1061 + #ifdef CONFIG_KCOV_SELFTEST 1062 + static void __init selftest(void) 1063 + { 1064 + unsigned long start; 1065 + 1066 + pr_err("running self test\n"); 1067 + /* 1068 + * Test that interrupts don't produce spurious coverage. 1069 + * The coverage callback filters out interrupt code, but only 1070 + * after the handler updates preempt count. Some code periodically 1071 + * leaks out of that section and leads to spurious coverage. 1072 + * It's hard to call the actual interrupt handler directly, 1073 + * so we just loop here for a bit waiting for a timer interrupt. 1074 + * We set kcov_mode to enable tracing, but don't setup the area, 1075 + * so any attempt to trace will crash. Note: we must not call any 1076 + * potentially traced functions in this region. 1077 + */ 1078 + start = jiffies; 1079 + current->kcov_mode = KCOV_MODE_TRACE_PC; 1080 + while ((jiffies - start) * MSEC_PER_SEC / HZ < 300) 1081 + ; 1082 + current->kcov_mode = 0; 1083 + pr_err("done running self test\n"); 1084 + } 1085 + #endif 1086 + 1062 1087 static int __init kcov_init(void) 1063 1088 { 1064 1089 int cpu; ··· 1103 1076 * use of debugfs_create_file_unsafe() is actually safe here. 1104 1077 */ 1105 1078 debugfs_create_file_unsafe("kcov", 0600, NULL, NULL, &kcov_fops); 1079 + 1080 + #ifdef CONFIG_KCOV_SELFTEST 1081 + selftest(); 1082 + #endif 1106 1083 1107 1084 return 0; 1108 1085 }
+8
lib/Kconfig.debug
··· 2173 2173 soft interrupts. This specifies the size of those areas in the 2174 2174 number of unsigned long words. 2175 2175 2176 + config KCOV_SELFTEST 2177 + bool "Perform short selftests on boot" 2178 + depends on KCOV 2179 + help 2180 + Run short KCOV coverage collection selftests on boot. 2181 + On test failure, causes the kernel to panic. Recommended to be 2182 + enabled, ensuring critical functionality works as intended. 2183 + 2176 2184 menuconfig RUNTIME_TESTING_MENU 2177 2185 bool "Runtime Testing" 2178 2186 default y