From: Linus Torvalds Date: Tue, 17 Sep 2024 10:40:34 +0000 (+0200) Subject: Merge tag 'x86-build-2024-09-17' of git://git.kernel.org/pub/scm/linux/kernel/git... X-Git-Url: https://repo.jachan.dev/J-linux.git/commitdiff_plain/5ba202a7c986fc58dd2fd1571c99667ab2699995?hp=-c Merge tag 'x86-build-2024-09-17' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip Pull x86 build updates from Thomas Gleixner: "Updates for KCOV instrumentation on x86: - Prevent spurious KCOV coverage in common_interrupt() - Fixup the KCOV Makefile directive which got stale due to a source file rename - Exclude stack unwinding from KCOV as it creates large amounts of uninteresting coverage - Provide a self test to validate that KCOV coverage of the interrupt handling code starts not before preempt count got updated" * tag 'x86-build-2024-09-17' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86: Ignore stack unwinding in KCOV module: Fix KCOV-ignored file name kcov: Add interrupt handling self test x86/entry: Remove unwanted instrumentation in common_interrupt() --- 5ba202a7c986fc58dd2fd1571c99667ab2699995 diff --combined kernel/kcov.c index 274b6b7c718d,d9d4a0c04185..28a6be6e64fd --- a/kernel/kcov.c +++ b/kernel/kcov.c @@@ -11,6 -11,7 +11,7 @@@ #include #include #include + #include #include #include #include @@@ -161,15 -162,6 +162,15 @@@ static void kcov_remote_area_put(struc kmsan_unpoison_memory(&area->list, sizeof(area->list)); } +/* + * Unlike in_serving_softirq(), this function returns false when called during + * a hardirq or an NMI that happened in the softirq context. + */ +static inline bool in_softirq_really(void) +{ + return in_serving_softirq() && !in_hardirq() && !in_nmi(); +} + static notrace bool check_kcov_mode(enum kcov_mode needed_mode, struct task_struct *t) { unsigned int mode; @@@ -179,7 -171,7 +180,7 @@@ * so we ignore code executed in interrupts, unless we are in a remote * coverage collection section in a softirq. */ - if (!in_task() && !(in_serving_softirq() && t->kcov_softirq)) + if (!in_task() && !(in_softirq_really() && t->kcov_softirq)) return false; mode = READ_ONCE(t->kcov_mode); /* @@@ -858,7 -850,7 +859,7 @@@ void kcov_remote_start(u64 handle if (WARN_ON(!kcov_check_handle(handle, true, true, true))) return; - if (!in_task() && !in_serving_softirq()) + if (!in_task() && !in_softirq_really()) return; local_lock_irqsave(&kcov_percpu_data.lock, flags); @@@ -1000,7 -992,7 +1001,7 @@@ void kcov_remote_stop(void int sequence; unsigned long flags; - if (!in_task() && !in_serving_softirq()) + if (!in_task() && !in_softirq_really()) return; local_lock_irqsave(&kcov_percpu_data.lock, flags); @@@ -1067,6 -1059,32 +1068,32 @@@ u64 kcov_common_handle(void } EXPORT_SYMBOL(kcov_common_handle); + #ifdef CONFIG_KCOV_SELFTEST + static void __init selftest(void) + { + unsigned long start; + + pr_err("running self test\n"); + /* + * Test that interrupts don't produce spurious coverage. + * 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. + * It's hard to call the actual interrupt handler directly, + * so we just loop here for a bit waiting for a timer interrupt. + * We set kcov_mode to enable tracing, but don't setup the area, + * so any attempt to trace will crash. Note: we must not call any + * potentially traced functions in this region. + */ + start = jiffies; + current->kcov_mode = KCOV_MODE_TRACE_PC; + while ((jiffies - start) * MSEC_PER_SEC / HZ < 300) + ; + current->kcov_mode = 0; + pr_err("done running self test\n"); + } + #endif + static int __init kcov_init(void) { int cpu; @@@ -1086,6 -1104,10 +1113,10 @@@ */ debugfs_create_file_unsafe("kcov", 0600, NULL, NULL, &kcov_fops); + #ifdef CONFIG_KCOV_SELFTEST + selftest(); + #endif + return 0; } diff --combined lib/Kconfig.debug index a40aa606cd04,270e367b3e6f..26354671b37d --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@@ -97,7 -97,7 +97,7 @@@ config BOOT_PRINTK_DELA using "boot_delay=N". It is likely that you would also need to use "lpj=M" to preset - the "loops per jiffie" value. + the "loops per jiffy" value. See a previous boot log for the "lpj" value to use for your system, and then set "lpj=M" before setting "boot_delay=N". NOTE: Using this option may adversely affect SMP systems. @@@ -2173,6 -2173,14 +2173,14 @@@ config KCOV_IRQ_AREA_SIZ soft interrupts. This specifies the size of those areas in the number of unsigned long words. + config KCOV_SELFTEST + bool "Perform short selftests on boot" + depends on KCOV + help + Run short KCOV coverage collection selftests on boot. + On test failure, causes the kernel to panic. Recommended to be + enabled, ensuring critical functionality works as intended. + menuconfig RUNTIME_TESTING_MENU bool "Runtime Testing" default y