KCOV fixes
Subsystems (5)
Dmitry Vyukov
reviewerv2 cover KCOV fixes
Fix spurious KCOV coverage from interrupts and add a test. Ignore some additional files that lead to large amounts of uninteresting coverage.
As a reference point, tracing a simple open system call produces ~10K PCs with these changes instead of ~45K PCs.
Dmitry Vyukov (4):
x86/entry: Remove unwanted instrumentation in common_interrupt()
kcov: add interrupt handling self test
module: Fix KCOV-ignored file name
x86: Ignore stack unwinding in KCOV
arch/x86/include/asm/hardirq.h | 8 ++++++-- arch/x86/include/asm/idtentry.h | 6 +++--- arch/x86/kernel/Makefile | 8 ++++++++ kernel/kcov.c | 31 +++++++++++++++++++++++++++++++ kernel/module/Makefile | 2 +- lib/Kconfig.debug | 8 ++++++++ 6 files changed, 57 insertions(+), 6 deletions(-)
base-commit: 83a7eefedc9b56fe7bfeff13b6c7356688ffa670
Signature · 1 line
2.45.2.505.gda0bf45e8d-goog
Dmitry Vyukov
reviewerPATCH v2 1/4 x86/entry: Remove unwanted instrumentation in common_interrupt()
common_interrupt() and friends call kvm_set_cpu_l1tf_flush_l1d(), which is not marked as noinstr nor __always_inline.
So compiler outlines it and adds instrumentation to it. Since the call is inside of instrumentation_begin/end(), objtool does not warn about it.
The manifestation is that KCOV produces spurious coverage in kvm_set_cpu_l1tf_flush_l1d() in random places because the call happens when preempt count is not yet updated to say that we are in an interrupt.
Mark kvm_set_cpu_l1tf_flush_l1d() as __always_inline and move out of instrumentation_begin/end() section.
It only calls __this_cpu_write() which is already safe to call in noinstr contexts.
--- arch/x86/include/asm/hardirq.h | 8 ++++++-- arch/x86/include/asm/idtentry.h | 6 +++--- 2 files changed, 9 insertions(+), 5 deletions(-)
arch/x86/include/asm/hardirq.h +6 -2
@@ -69,7 +69,11 @@ extern u64 arch_irq_stat(void);#define local_softirq_pending_ref pcpu_hot.softirq_pending#if IS_ENABLED (CONFIG_KVM_INTEL ) -static inline void kvm_set_cpu_l1tf_flush_l1d (void ) +/* +* This function is called from noinstr interrupt contexts +* and must be inlined to not get instrumentation. +*/ +static __always_inline void kvm_set_cpu_l1tf_flush_l1d(void) {__this_cpu_write (irq_stat.kvm_cpu_l1tf_flush_l1d,1 ); }
@@ -84,7 +88,7 @@ static __always_inline bool kvm_get_cpu_l1tf_flush_l1d(void)return __this_cpu_read (irq_stat.kvm_cpu_l1tf_flush_l1d); }#else /* !IS_ENABLED(CONFIG_KVM_INTEL) */ -static inline void kvm_set_cpu_l1tf_flush_l1d (void ) { } +static __always_inline void kvm_set_cpu_l1tf_flush_l1d(void) { }#endif /* IS_ENABLED(CONFIG_KVM_INTEL) */ #endif /* _ASM_X86_HARDIRQ_H */
arch/x86/include/asm/idtentry.h +3 -3
@@ -212,8 +212,8 @@ __visible noinstr void func(struct pt_regs *regs, \irqentry_state_t state =irqentry_enter (regs); \u32 vector = (u32 )(u8 )error_code; \ \ +kvm_set_cpu_l1tf_flush_l1d (); \instrumentation_begin (); \ -kvm_set_cpu_l1tf_flush_l1d (); \ run_irq_on_irqstack_cond(__##func, regs, vector); \ instrumentation_end(); \ irqentry_exit(regs, state); \
@@ -250,7 +250,6 @@ static void __##func(struct pt_regs *regs); \ \ static __always_inline void instr_##func(struct pt_regs *regs) \ { \ - kvm_set_cpu_l1tf_flush_l1d(); \ run_sysvec_on_irqstack_cond(__##func, regs); \ } \ \
@@ -258,6 +257,7 @@ __visible noinstr void func(struct pt_regs *regs) \ { \irqentry_state_t state =irqentry_enter (regs); \ \ +kvm_set_cpu_l1tf_flush_l1d (); \instrumentation_begin (); \ instr_##func (regs); \instrumentation_end (); \
@@ -288,7 +288,6 @@ static __always_inline void __##func(struct pt_regs *regs); \ static __always_inline void instr_##func(struct pt_regs *regs) \ { \ __irq_enter_raw(); \ - kvm_set_cpu_l1tf_flush_l1d(); \ __##func (regs); \ __irq_exit_raw(); \ } \
@@ -297,6 +296,7 @@ __visible noinstr void func(struct pt_regs *regs) \ { \irqentry_state_t state =irqentry_enter (regs); \ \ +kvm_set_cpu_l1tf_flush_l1d (); \instrumentation_begin (); \ instr_##func (regs); \instrumentation_end (); \
Signature · 1 line
2.45.2.505.gda0bf45e8d-goog
Re: [PATCH v2 1/4] x86/entry: Remove unwanted instrumentation in common_interrupt()
Quoted 10 lines · Dmitry Vyukov
common_interrupt()and friends callkvm_set_cpu_l1tf_flush_l1d(), which is not marked as noinstr nor__always_inline.
So compiler outlines it and adds instrumentation to it. Since the call is inside of instrumentation_begin/end(), objtool does not warn about it.The manifestation is that KCOV produces spurious coverage in
kvm_set_cpu_l1tf_flush_l1d()in random places because the call happens when preempt count is not yet updated to say that we are in an interrupt.
So I'm reading spurious here, but the next patch trips BUG, them very much not the same thing. Which is it?
Quoted 11 lines
Mark
kvm_set_cpu_l1tf_flush_l1d()as__always_inlineand move out of instrumentation_begin/end() section.
It only calls__this_cpu_write()which is already safe to call in noinstr contexts.Signed-off-by Dmitry Vyukov <[email protected]>Reviewed-by Alexander Potapenko <[email protected]>Fixes 6368558c3710 ("x86/entry: Provide IDTENTRY_SYSVEC")
Anyway, the patch is fine,
Quoted 80 lines
--- arch/x86/include/asm/hardirq.h | 8 ++++++-- arch/x86/include/asm/idtentry.h | 6 +++--- 2 files changed, 9 insertions(+), 5 deletions(-)arch/x86/include/asm/hardirq.h +6
-2@@ -69,7 +69,11 @@ extern u64 arch_irq_stat(void);#define local_softirq_pending_ref pcpu_hot.softirq_pending#if IS_ENABLED (CONFIG_KVM_INTEL ) -static inline void kvm_set_cpu_l1tf_flush_l1d (void ) +/* +* This function is called from noinstr interrupt contexts +* and must be inlined to not get instrumentation. +*/ +static __always_inline void kvm_set_cpu_l1tf_flush_l1d(void) {__this_cpu_write (irq_stat.kvm_cpu_l1tf_flush_l1d,1 ); }@@ -84,7 +88,7 @@ static __always_inline bool kvm_get_cpu_l1tf_flush_l1d(void)return __this_cpu_read (irq_stat.kvm_cpu_l1tf_flush_l1d); }#else /* !IS_ENABLED(CONFIG_KVM_INTEL) */ -static inline void kvm_set_cpu_l1tf_flush_l1d (void ) { } +static __always_inline void kvm_set_cpu_l1tf_flush_l1d(void) { }#endif /* IS_ENABLED(CONFIG_KVM_INTEL) */ #endif /* _ASM_X86_HARDIRQ_H */ arch/x86/include/asm/idtentry.h +3
-3@@ -212,8 +212,8 @@ __visible noinstr void func(struct pt_regs *regs, \irqentry_state_t state =irqentry_enter (regs); \u32 vector = (u32 )(u8 )error_code; \ \ +kvm_set_cpu_l1tf_flush_l1d (); \instrumentation_begin (); \ -kvm_set_cpu_l1tf_flush_l1d (); \ run_irq_on_irqstack_cond(__##func, regs, vector); \ instrumentation_end(); \ irqentry_exit(regs, state); \@@ -250,7 +250,6 @@ static void __##func(struct pt_regs *regs); \ \ static __always_inline void instr_##func(struct pt_regs *regs) \ { \ - kvm_set_cpu_l1tf_flush_l1d(); \ run_sysvec_on_irqstack_cond(__##func, regs); \ } \ \@@ -258,6 +257,7 @@ __visible noinstr void func(struct pt_regs *regs) \ { \irqentry_state_t state =irqentry_enter (regs); \ \ +kvm_set_cpu_l1tf_flush_l1d (); \instrumentation_begin (); \ instr_##func (regs); \instrumentation_end (); \@@ -288,7 +288,6 @@ static __always_inline void __##func(struct pt_regs *regs); \ static __always_inline void instr_##func(struct pt_regs *regs) \ { \ __irq_enter_raw(); \ - kvm_set_cpu_l1tf_flush_l1d(); \ __##func (regs); \ __irq_exit_raw(); \ } \@@ -297,6 +296,7 @@ __visible noinstr void func(struct pt_regs *regs) \ { \irqentry_state_t state =irqentry_enter (regs); \ \ +kvm_set_cpu_l1tf_flush_l1d (); \instrumentation_begin (); \ instr_##func (regs); \instrumentation_end (); \Signature · 1 line
2.45.2.505.gda0bf45e8d-goog
Dmitry Vyukov
reviewerRe: [PATCH v2 1/4] x86/entry: Remove unwanted instrumentation in common_interrupt()
Quoted 8 lines · Peter Zijlstra
Quoted 6 lines · Dmitry Vyukov
common_interrupt()and friends callkvm_set_cpu_l1tf_flush_l1d(), which is not marked as noinstr nor__always_inline.
So compiler outlines it and adds instrumentation to it. Since the call is inside of instrumentation_begin/end(), objtool does not warn about it.
Quoted 7 lines
Quoted 4 lines
The manifestation is that KCOV produces spurious coverage in
kvm_set_cpu_l1tf_flush_l1d()in random places because the call happens when preempt count is not yet updated to say that we are in an interrupt.So I'm reading spurious here, but the next patch trips BUG, them very much not the same thing. Which is it?
I am not sure I understand the question.
Currently kvm_set_cpu_l1tf_flush_l1d() is traced, so the added test produces a BUG without this fix (and does not produce with this fix). By "spurious" I meant that tracing of kvm_set_cpu_l1tf_flush_l1d() and interrupts in general is parasitic/unwanted.
Quoted 101 lines
Quoted 11 lines
Mark
kvm_set_cpu_l1tf_flush_l1d()as__always_inlineand move out of instrumentation_begin/end() section.
It only calls__this_cpu_write()which is already safe to call in noinstr contexts.Signed-off-by Dmitry Vyukov <[email protected]>Reviewed-by Alexander Potapenko <[email protected]>Fixes 6368558c3710 ("x86/entry: Provide IDTENTRY_SYSVEC")Anyway, the patch is fine,
Quoted 78 lines
--- arch/x86/include/asm/hardirq.h | 8 ++++++-- arch/x86/include/asm/idtentry.h | 6 +++--- 2 files changed, 9 insertions(+), 5 deletions(-)arch/x86/include/asm/hardirq.h +6
-2@@ -69,7 +69,11 @@ extern u64 arch_irq_stat(void);#define local_softirq_pending_ref pcpu_hot.softirq_pending#if IS_ENABLED (CONFIG_KVM_INTEL ) -static inline void kvm_set_cpu_l1tf_flush_l1d (void ) +/* +* This function is called from noinstr interrupt contexts +* and must be inlined to not get instrumentation. +*/ +static __always_inline void kvm_set_cpu_l1tf_flush_l1d(void) {__this_cpu_write (irq_stat.kvm_cpu_l1tf_flush_l1d,1 ); }@@ -84,7 +88,7 @@ static __always_inline bool kvm_get_cpu_l1tf_flush_l1d(void)return __this_cpu_read (irq_stat.kvm_cpu_l1tf_flush_l1d); }#else /* !IS_ENABLED(CONFIG_KVM_INTEL) */ -static inline void kvm_set_cpu_l1tf_flush_l1d (void ) { } +static __always_inline void kvm_set_cpu_l1tf_flush_l1d(void) { }#endif /* IS_ENABLED(CONFIG_KVM_INTEL) */ #endif /* _ASM_X86_HARDIRQ_H */ arch/x86/include/asm/idtentry.h +3
-4@@ -212,8 +212,8 @@ __visible noinstr void func(struct pt_regs *regs, \irqentry_state_t state =irqentry_enter (regs); \u32 vector = (u32 )(u8 )error_code; \ \ +kvm_set_cpu_l1tf_flush_l1d (); \instrumentation_begin (); \ -kvm_set_cpu_l1tf_flush_l1d (); \ run_irq_on_irqstack_cond(__##func, regs, vector); \ instrumentation_end(); \ irqentry_exit(regs, state); \@@ -250,7 +250,6 @@ static void __##func(struct pt_regs *regs); \ \ static __always_inline void instr_##func(struct pt_regs *regs) \ { \ - kvm_set_cpu_l1tf_flush_l1d(); \ run_sysvec_on_irqstack_cond(__##func, regs); \ } \ \@@ -258,6 +257,7 @@ __visible noinstr void func(struct pt_regs *regs) \ { \irqentry_state_t state =irqentry_enter (regs); \ \ +kvm_set_cpu_l1tf_flush_l1d (); \instrumentation_begin (); \ instr_##func (regs); \instrumentation_end (); \@@ -288,7 +288,6 @@ static __always_inline void __##func(struct pt_regs *regs); \ static __always_inline void instr_##func(struct pt_regs *regs) \ { \ __irq_enter_raw(); \ - kvm_set_cpu_l1tf_flush_l1d(); \ __##func (regs); \ __irq_exit_raw(); \ } \@@ -297,6 +296,7 @@ __visible noinstr void func(struct pt_regs *regs) \ { \irqentry_state_t state =irqentry_enter (regs); \ \ +kvm_set_cpu_l1tf_flush_l1d (); \instrumentation_begin (); \ instr_##func (regs); \instrumentation_end (); \ --Quoted 2 lines
2.45.2.505.gda0bf45e8d-goog
--
You received this message because you are subscribed to the Google Groups "syzkaller" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/syzkaller/20240619111936.GK31592%40noisy.programming.kicks-ass.net.
[tip: x86/build] x86/entry: Remove unwanted instrumentation in common_interrupt()
In reply to Dmitry VyukovThe following commit has been merged into the x86/build branch of tip:
The following commit has been merged into the x86/build branch of tip:
Commit-ID: 477d81a1c47a1b79b9c08fc92b5dea3c5143800b Gitweb: https://git.kernel.org/tip/477d81a1c47a1b79b9c08fc92b5dea3c5143800b Author: Dmitry Vyukov <[email protected]> AuthorDate: Tue, 11 Jun 2024 09:50:30 +02:00 Committer: Thomas Gleixner <[email protected]> CommitterDate: Thu, 08 Aug 2024 17:36:35 +02:00
x86/entry: Remove unwanted instrumentation in common_interrupt()
common_interrupt() and related variants call kvm_set_cpu_l1tf_flush_l1d(), which is neither marked noinstr nor __always_inline.
So compiler puts it out of line and adds instrumentation to it. Since the call is inside of instrumentation_begin/end(), objtool does not warn about it.
The manifestation is that KCOV produces spurious coverage in kvm_set_cpu_l1tf_flush_l1d() in random places because the call happens when preempt count is not yet updated to say that the kernel is in an interrupt.
Mark kvm_set_cpu_l1tf_flush_l1d() as __always_inline and move it out of the instrumentation_begin/end() section. It only calls __this_cpu_write() which is already safe to call in noinstr contexts.
--- arch/x86/include/asm/hardirq.h | 8 ++++++-- arch/x86/include/asm/idtentry.h | 6 +++--- 2 files changed, 9 insertions(+), 5 deletions(-)
arch/x86/include/asm/hardirq.h +6 -2
@@ -69,7 +69,11 @@ extern u64 arch_irq_stat(void);#define local_softirq_pending_ref pcpu_hot.softirq_pending#if IS_ENABLED (CONFIG_KVM_INTEL ) -static inline void kvm_set_cpu_l1tf_flush_l1d (void ) +/* +* This function is called from noinstr interrupt contexts +* and must be inlined to not get instrumentation. +*/ +static __always_inline void kvm_set_cpu_l1tf_flush_l1d(void) {__this_cpu_write (irq_stat.kvm_cpu_l1tf_flush_l1d,1 ); }
@@ -84,7 +88,7 @@ static __always_inline bool kvm_get_cpu_l1tf_flush_l1d(void)return __this_cpu_read (irq_stat.kvm_cpu_l1tf_flush_l1d); }#else /* !IS_ENABLED(CONFIG_KVM_INTEL) */ -static inline void kvm_set_cpu_l1tf_flush_l1d (void ) { } +static __always_inline void kvm_set_cpu_l1tf_flush_l1d(void) { }#endif /* IS_ENABLED(CONFIG_KVM_INTEL) */ #endif /* _ASM_X86_HARDIRQ_H */
arch/x86/include/asm/idtentry.h +3 -3
@@ -212,8 +212,8 @@ __visible noinstr void func(struct pt_regs *regs, \irqentry_state_t state =irqentry_enter (regs); \u32 vector = (u32 )(u8 )error_code; \ \ +kvm_set_cpu_l1tf_flush_l1d (); \instrumentation_begin (); \ -kvm_set_cpu_l1tf_flush_l1d (); \ run_irq_on_irqstack_cond(__##func, regs, vector); \ instrumentation_end(); \ irqentry_exit(regs, state); \
@@ -250,7 +250,6 @@ static void __##func(struct pt_regs *regs); \ \ static __always_inline void instr_##func(struct pt_regs *regs) \ { \ - kvm_set_cpu_l1tf_flush_l1d(); \ run_sysvec_on_irqstack_cond(__##func, regs); \ } \ \
@@ -258,6 +257,7 @@ __visible noinstr void func(struct pt_regs *regs) \ { \irqentry_state_t state =irqentry_enter (regs); \ \ +kvm_set_cpu_l1tf_flush_l1d (); \instrumentation_begin (); \ instr_##func (regs); \instrumentation_end (); \
@@ -288,7 +288,6 @@ static __always_inline void __##func(struct pt_regs *regs); \ static __always_inline void instr_##func(struct pt_regs *regs) \ { \ __irq_enter_raw(); \ - kvm_set_cpu_l1tf_flush_l1d(); \ __##func (regs); \ __irq_exit_raw(); \ } \
@@ -297,6 +296,7 @@ __visible noinstr void func(struct pt_regs *regs) \ { \irqentry_state_t state =irqentry_enter (regs); \ \ +kvm_set_cpu_l1tf_flush_l1d (); \instrumentation_begin (); \ instr_##func (regs); \instrumentation_end (); \
Dmitry Vyukov
reviewerPATCH v2 2/4 kcov: add interrupt handling self test
In reply to Dmitry VyukovAdd 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.
---
Changed since v1:
- renamed KCOV_TEST to KCOV_SELFTEST
- improved the config description
- loop for exactly 300ms in the test
In my local testing w/o the previous fix,
it immidiatly produced the following splat:
kcov: running selftest
BUG: TASK stack guard page was hit at ffffc90000147ff8 Oops: stack guard page: 0000 [#1] PREEMPT SMP KASAN PTI ... kvm_set_cpu_l1tf_flush_l1d+0x5/0x20 sysvec_call_function+0x15/0xb0 asm_sysvec_call_function+0x1a/0x20 kcov_init+0xe4/0x130 do_one_initcall+0xbc/0x470 kernel_init_freeable+0x4fc/0x930 kernel_init+0x1c/0x2b0 --- kernel/kcov.c | 31 +++++++++++++++++++++++++++++++ lib/Kconfig.debug | 8 ++++++++ 2 files changed, 39 insertions(+)
kernel/kcov.c +31 -0
@@ -11,6 +11,7 @@#include <linux/fs.h> #include <linux/hashtable.h> #include <linux/init.h> +#include <linux/jiffies.h> #include <linux/kmsan-checks.h> #include <linux/mm.h> #include <linux/preempt.h>
@@ -1057,6 +1058,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;
@@ -1076,6 +1103,10 @@ static int __init kcov_init(void)*/ debugfs_create_file_unsafe ("kcov" ,0600 ,NULL ,NULL , &kcov_fops); +#ifdef CONFIG_KCOV_SELFTEST +selftest (); +#endif +return 0 ; }
lib/Kconfig.debug +8 -0
@@ -2171,6 +2171,14 @@ config KCOV_IRQ_AREA_SIZE 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
Signature · 1 line
2.45.2.505.gda0bf45e8d-goog
Re: [PATCH v2 2/4] kcov: add interrupt handling self test
Quoted 9 lines · Dmitry Vyukov
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.
Quoted 5 lines
Signed-off-by Dmitry Vyukov <[email protected]>Reviewed-by Alexander Potapenko <[email protected]>
Quoted 104 lines
---
Changed since v1:
- renamedKCOV_TESTtoKCOV_SELFTEST
- improved the config description
- loop for exactly 300ms in the testIn my local testing w/o the previous fix,
it immidiatly produced the following splat:kcov: running selftest
BUG: TASK stack guard page was hit at ffffc90000147ff8 Oops: stack guard page: 0000 [#1] PREEMPT SMP KASAN PTI ... kvm_set_cpu_l1tf_flush_l1d+0x5/0x20 sysvec_call_function+0x15/0xb0 asm_sysvec_call_function+0x1a/0x20 kcov_init+0xe4/0x130 do_one_initcall+0xbc/0x470 kernel_init_freeable+0x4fc/0x930 kernel_init+0x1c/0x2b0 --- kernel/kcov.c | 31 +++++++++++++++++++++++++++++++ lib/Kconfig.debug | 8 ++++++++ 2 files changed, 39 insertions(+)kernel/kcov.c +31
-0@@ -11,6 +11,7 @@#include <linux/fs.h> #include <linux/hashtable.h> #include <linux/init.h> +#include <linux/jiffies.h> #include <linux/kmsan-checks.h> #include <linux/mm.h> #include <linux/preempt.h> @@ -1057,6 +1058,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;@@ -1076,6 +1103,10 @@ static int __init kcov_init(void)*/ debugfs_create_file_unsafe ("kcov" ,0600 ,NULL ,NULL , &kcov_fops); +#ifdef CONFIG_KCOV_SELFTEST +selftest (); +#endif +return 0 ; }lib/Kconfig.debug +8
-1@@ -2171,6 +2171,14 @@ config KCOV_IRQ_AREA_SIZE 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 --2.45.2.505.gda0bf45e8d-goog
Re: [PATCH v2 2/4] kcov: add interrupt handling self test
In reply to Dmitry VyukovQuoted 102 lines · Dmitry Vyukov' via syzkaller
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 <[email protected]>Reviewed-by Alexander Potapenko <[email protected]>---
Changed since v1:
- renamedKCOV_TESTtoKCOV_SELFTEST
- improved the config description
- loop for exactly 300ms in the testIn my local testing w/o the previous fix,
it immidiatly produced the following splat:kcov: running selftest
BUG: TASK stack guard page was hit at ffffc90000147ff8 Oops: stack guard page: 0000 [#1] PREEMPT SMP KASAN PTI ... kvm_set_cpu_l1tf_flush_l1d+0x5/0x20 sysvec_call_function+0x15/0xb0 asm_sysvec_call_function+0x1a/0x20 kcov_init+0xe4/0x130 do_one_initcall+0xbc/0x470 kernel_init_freeable+0x4fc/0x930 kernel_init+0x1c/0x2b0 --- kernel/kcov.c | 31 +++++++++++++++++++++++++++++++ lib/Kconfig.debug | 8 ++++++++ 2 files changed, 39 insertions(+)kernel/kcov.c +31
-0@@ -11,6 +11,7 @@#include <linux/fs.h> #include <linux/hashtable.h> #include <linux/init.h> +#include <linux/jiffies.h> #include <linux/kmsan-checks.h> #include <linux/mm.h> #include <linux/preempt.h> @@ -1057,6 +1058,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;@@ -1076,6 +1103,10 @@ static int __init kcov_init(void)*/ debugfs_create_file_unsafe ("kcov" ,0600 ,NULL ,NULL , &kcov_fops); +#ifdef CONFIG_KCOV_SELFTEST +selftest (); +#endif +return 0 ; }lib/Kconfig.debug +0
-0
lib/Kconfig.debug config KCOV_IRQ_AREA_SIZE · line 2179
Quoted 9 lines
lib/Kconfig.debug +6
-0@@ -2171,6 +2171,14 @@ config KCOV_IRQ_AREA_SIZE 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
Nit: "causes the kernel to panic" => "causes a kernel panic" or "panic the kernel"
Quoted 7 lines
lib/Kconfig.debug +2
-1+ enabled, ensuring critical functionality works as intended. + menuconfig RUNTIME_TESTING_MENU bool "Runtime Testing" default y --2.45.2.505.gda0bf45e8d-goog
Re: [PATCH v2 2/4] kcov: add interrupt handling self test
In reply to Dmitry VyukovQuoted 25 lines · Dmitry Vyukov
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 <[email protected]>Reviewed-by Alexander Potapenko <[email protected]>---
Changed since v1:
- renamedKCOV_TESTtoKCOV_SELFTEST
- improved the config description
- loop for exactly 300ms in the testIn my local testing w/o the previous fix,
it immidiatly produced the following splat:kcov: running selftest
Quoted 10 lines
BUG: TASK stack guard page was hit at ffffc90000147ff8 Oops: stack guard page: 0000 [#1] PREEMPT SMP KASAN PTI ... kvm_set_cpu_l1tf_flush_l1d+0x5/0x20 sysvec_call_function+0x15/0xb0 asm_sysvec_call_function+0x1a/0x20 kcov_init+0xe4/0x130 do_one_initcall+0xbc/0x470 kernel_init_freeable+0x4fc/0x930 kernel_init+0x1c/0x2b0
So I'm not entirely sure how the above BUG comes about, nor how this selftest tickles it. Could you elaborate?
I've found check_kcov_mode() which has this !in_task() clause, but I'm not entirely sure how failing that leads to the above mentioned failure.
Quoted 30 lines
--- kernel/kcov.c | 31 +++++++++++++++++++++++++++++++ lib/Kconfig.debug | 8 ++++++++ 2 files changed, 39 insertions(+)kernel/kcov.c +10
-0@@ -11,6 +11,7 @@#include <linux/fs.h> #include <linux/hashtable.h> #include <linux/init.h> +#include <linux/jiffies.h> #include <linux/kmsan-checks.h> #include <linux/mm.h> #include <linux/preempt.h> @@ -1057,6 +1058,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
kernel/kcov.c u64 kcov_common_handle(void) · line 1079
Quoted 10 lines
kernel/kcov.c +10
-0+* 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 ;
barrier();
kernel/kcov.c u64 kcov_common_handle(void) · line 1081
Quoted 2 lines
kernel/kcov.c +2
-0+while ((jiffies - start) *MSEC_PER_SEC /HZ <300 ) + ;
barrier();
Quoted 4 lines
kernel/kcov.c +4
-0+ current->kcov_mode =0 ; + pr_err("done running self test\n"); +} +#endif
Dmitry Vyukov
reviewerRe: [PATCH v2 2/4] kcov: add interrupt handling self test
Quoted 38 lines · Peter Zijlstra
Quoted 25 lines · Dmitry Vyukov
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 <[email protected]>Reviewed-by Alexander Potapenko <[email protected]>---
Changed since v1:
- renamedKCOV_TESTtoKCOV_SELFTEST
- improved the config description
- loop for exactly 300ms in the testIn my local testing w/o the previous fix,
it immidiatly produced the following splat:kcov: running selftest
Quoted 10 lines
BUG: TASK stack guard page was hit at ffffc90000147ff8 Oops: stack guard page: 0000 [#1] PREEMPT SMP KASAN PTI ... kvm_set_cpu_l1tf_flush_l1d+0x5/0x20 sysvec_call_function+0x15/0xb0 asm_sysvec_call_function+0x1a/0x20 kcov_init+0xe4/0x130 do_one_initcall+0xbc/0x470 kernel_init_freeable+0x4fc/0x930 kernel_init+0x1c/0x2b0
Quoted 5 lines
So I'm not entirely sure how the above BUG comes about, nor how this selftest tickles it. Could you elaborate?
I've found
check_kcov_mode()which has this !in_task() clause, but I'm not entirely sure how failing that leads to the above mentioned failure.
I've tried to explain it in the test comment, maybe I need to improve it:
+ * 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.
Basically, we setup current task kcov in a way that any attempt to trace in __sanitizer_cov_trace_pc() will crash, and then just loop waiting for interrupts.
A more legit way to achieve the same would be to properly setup kcov for tracing from within the kernel, then call outermost interrupt entry function, then check we traced nothing. But that would require a non-trivial amount of new complex code, and e.g. the top-most interrupt entry function is not exported and is arch-specific.
Quoted 57 lines
Quoted 30 lines
--- kernel/kcov.c | 31 +++++++++++++++++++++++++++++++ lib/Kconfig.debug | 8 ++++++++ 2 files changed, 39 insertions(+)kernel/kcov.c +10
-0@@ -11,6 +11,7 @@#include <linux/fs.h> #include <linux/hashtable.h> #include <linux/init.h> +#include <linux/jiffies.h> #include <linux/kmsan-checks.h> #include <linux/mm.h> #include <linux/preempt.h> @@ -1057,6 +1058,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 kernel/kcov.c u64 kcov_common_handle(void) · line 1079
Quoted 10 lines
kernel/kcov.c +10
-0+* 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 ;barrier();kernel/kcov.c u64 kcov_common_handle(void) · line 1081
Quoted 2 lines
kernel/kcov.c +2
-0+while ((jiffies - start) *MSEC_PER_SEC /HZ <300 ) + ;barrier();kernel/kcov.c u64 kcov_common_handle(void) · line 1085
Quoted 4 lines
kernel/kcov.c +4
-0+ current->kcov_mode =0 ; + pr_err("done running self test\n"); +} +#endif --
You received this message because you are subscribed to the Google Groups "syzkaller" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/syzkaller/20240619111309.GJ31592%40noisy.programming.kicks-ass.net.
Re: [PATCH v2 2/4] kcov: add interrupt handling self test
Quoted 47 lines · Dmitry Vyukov
Quoted 38 lines · Peter Zijlstra
Quoted 25 lines · Dmitry Vyukov
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 <[email protected]>Reviewed-by Alexander Potapenko <[email protected]>---
Changed since v1:
- renamedKCOV_TESTtoKCOV_SELFTEST
- improved the config description
- loop for exactly 300ms in the testIn my local testing w/o the previous fix,
it immidiatly produced the following splat:kcov: running selftest
Quoted 10 lines
BUG: TASK stack guard page was hit at ffffc90000147ff8 Oops: stack guard page: 0000 [#1] PREEMPT SMP KASAN PTI ... kvm_set_cpu_l1tf_flush_l1d+0x5/0x20 sysvec_call_function+0x15/0xb0 asm_sysvec_call_function+0x1a/0x20 kcov_init+0xe4/0x130 do_one_initcall+0xbc/0x470 kernel_init_freeable+0x4fc/0x930 kernel_init+0x1c/0x2b0Quoted 5 lines
So I'm not entirely sure how the above BUG comes about, nor how this selftest tickles it. Could you elaborate?
I've found
check_kcov_mode()which has this !in_task() clause, but I'm not entirely sure how failing that leads to the above mentioned failure.I've tried to explain it in the test comment, maybe I need to improve it:
kernel/kcov.c u64 kcov_common_handle(void) · line 1076
Quoted 3 lines
kernel/kcov.c +3
-0+* 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.
Ah, I'm just slow today.. did not connect the dots. No this is fine.
Quoted 9 lines
Basically, we setup current task kcov in a way that any attempt to trace in
__sanitizer_cov_trace_pc()will crash, and then just loop waiting for interrupts.A more legit way to achieve the same would be to properly setup kcov for tracing from within the kernel, then call outermost interrupt entry function, then check we traced nothing. But that would require a non-trivial amount of new complex code, and e.g. the top-most interrupt entry function is not exported and is arch-specific.
Yeah, polling jiffies should be fine I suppose.
[tip: x86/build] kcov: Add interrupt handling self test
In reply to Dmitry VyukovThe following commit has been merged into the x86/build branch of tip:
The following commit has been merged into the x86/build branch of tip:
Commit-ID: 6cd0dd934b03d4ee4094ac474108723e2f2ed7d6 Gitweb: https://git.kernel.org/tip/6cd0dd934b03d4ee4094ac474108723e2f2ed7d6 Author: Dmitry Vyukov <[email protected]> AuthorDate: Tue, 11 Jun 2024 09:50:31 +02:00 Committer: Thomas Gleixner <[email protected]> CommitterDate: Thu, 08 Aug 2024 17:36:35 +02:00
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.
--- kernel/kcov.c | 31 +++++++++++++++++++++++++++++++ lib/Kconfig.debug | 8 ++++++++ 2 files changed, 39 insertions(+)
kernel/kcov.c +31 -0
@@ -11,6 +11,7 @@#include <linux/fs.h> #include <linux/hashtable.h> #include <linux/init.h> +#include <linux/jiffies.h> #include <linux/kmsan-checks.h> #include <linux/mm.h> #include <linux/preempt.h>
@@ -1058,6 +1059,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;
@@ -1077,6 +1104,10 @@ static int __init kcov_init(void)*/ debugfs_create_file_unsafe ("kcov" ,0600 ,NULL ,NULL , &kcov_fops); +#ifdef CONFIG_KCOV_SELFTEST +selftest (); +#endif +return 0 ; }
lib/Kconfig.debug +8 -0
@@ -2173,6 +2173,14 @@ config KCOV_IRQ_AREA_SIZE 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
Dmitry Vyukov
reviewerPATCH v2 3/4 module: Fix KCOV-ignored file name
In reply to Dmitry VyukovModule.c was renamed to main.c, but the Makefile directive was copy-pasted verbatim with the old file name. Fix up the file name.
--- kernel/module/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/module/Makefile +1 -1
@@ -5,7 +5,7 @@ # These are called from save_stack_trace() on slub debug path, # and produce insane amounts of uninteresting coverage. -KCOV_INSTRUMENT_module.o := n +KCOV_INSTRUMENT_main.o := n obj-y += main.o obj-y += strict_rwx.o
Signature · 1 line
2.45.2.505.gda0bf45e8d-goog
Re: [PATCH v2 3/4] module: Fix KCOV-ignored file name
Quoted 5 lines · Dmitry Vyukov
Module.cwas renamed tomain.c, but theMakefiledirective was copy-pasted verbatim with the old file name. Fix up the file name.
Quoted 7 lines
Signed-off-by Dmitry Vyukov <[email protected]>Reviewed-by Alexander Potapenko <[email protected]>Fixes cfc1d277891e ("module: Move all into module/")Cc Aaron Tomlin <[email protected]>
Quoted 20 lines
--- kernel/module/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)kernel/module/Makefile +1
-2@@ -5,7 +5,7 @@ # These are called from save_stack_trace() on slub debug path, # and produce insane amounts of uninteresting coverage. -KCOV_INSTRUMENT_module.o := n +KCOV_INSTRUMENT_main.o := n obj-y += main.o obj-y += strict_rwx.o --2.45.2.505.gda0bf45e8d-goog
Re: [PATCH v2 3/4] module: Fix KCOV-ignored file name
In reply to Dmitry VyukovQuoted 30 lines · Dmitry Vyukov' via syzkaller
Module.cwas renamed tomain.c, but theMakefiledirective was copy-pasted verbatim with the old file name. Fix up the file name.Signed-off-by Dmitry Vyukov <[email protected]>Reviewed-by Alexander Potapenko <[email protected]>Fixes cfc1d277891e ("module: Move all into module/")Cc Aaron Tomlin <[email protected]>--- kernel/module/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)kernel/module/Makefile +1
-2@@ -5,7 +5,7 @@ # These are called from save_stack_trace() on slub debug path, # and produce insane amounts of uninteresting coverage. -KCOV_INSTRUMENT_module.o := n +KCOV_INSTRUMENT_main.o := n obj-y += main.o obj-y += strict_rwx.o --
Quoted 1 line
2.45.2.505.gda0bf45e8d-goog
[tip: x86/build] module: Fix KCOV-ignored file name
In reply to Dmitry VyukovThe following commit has been merged into the x86/build branch of tip:
The following commit has been merged into the x86/build branch of tip:
Commit-ID: f34d086fb7102fec895fd58b9e816b981b284c17 Gitweb: https://git.kernel.org/tip/f34d086fb7102fec895fd58b9e816b981b284c17 Author: Dmitry Vyukov <[email protected]> AuthorDate: Tue, 11 Jun 2024 09:50:32 +02:00 Committer: Thomas Gleixner <[email protected]> CommitterDate: Thu, 08 Aug 2024 17:36:35 +02:00
module: Fix KCOV-ignored file name
module.c was renamed to main.c, but the Makefile directive was copy-pasted verbatim with the old file name. Fix up the file name.
--- kernel/module/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/module/Makefile +1 -1
@@ -5,7 +5,7 @@ # These are called from save_stack_trace() on slub debug path, # and produce insane amounts of uninteresting coverage. -KCOV_INSTRUMENT_module.o := n +KCOV_INSTRUMENT_main.o := n obj-y += main.o obj-y += strict_rwx.o
Dmitry Vyukov
reviewerPATCH v2 4/4 x86: Ignore stack unwinding in KCOV
In reply to Dmitry VyukovStack unwinding produces large amounts of uninteresting coverage. It's called from KASAN kmalloc/kfree hooks, fault injection, etc. It's not particularly useful and is not a function of system call args. Ignore that code.
--- arch/x86/kernel/Makefile | 8 ++++++++ 1 file changed, 8 insertions(+)
arch/x86/kernel/Makefile +8 -0
@@ -39,6 +39,14 @@ KMSAN_SANITIZE_sev.o := n # first second. KCOV_INSTRUMENT_head$(BITS).o := n KCOV_INSTRUMENT_sev.o := n +# These are called from save_stack_trace() on debug paths, +# and produce large amounts of uninteresting coverage. +KCOV_INSTRUMENT_stacktrace.o := n +KCOV_INSTRUMENT_dumpstack.o := n +KCOV_INSTRUMENT_dumpstack_$(BITS).o := n +KCOV_INSTRUMENT_unwind_orc.o := n +KCOV_INSTRUMENT_unwind_frame.o := n +KCOV_INSTRUMENT_unwind_guess.o := n CFLAGS_irq.o := -I $(src)/../include/asm/trace
Signature · 1 line
2.45.2.505.gda0bf45e8d-goog
Re: [PATCH v2 4/4] x86: Ignore stack unwinding in KCOV
Quoted 26 lines · Dmitry Vyukov' via syzkaller
Stack unwinding produces large amounts of uninteresting coverage. It's called from KASAN kmalloc/kfree hooks, fault injection, etc. It's not particularly useful and is not a function of system call args. Ignore that code.
Signed-off-by Dmitry Vyukov <[email protected]>Reviewed-by Alexander Potapenko <[email protected]>Reviewed-by Marco Elver <[email protected]>--- arch/x86/kernel/Makefile | 8 ++++++++ 1 file changed, 8 insertions(+)arch/x86/kernel/Makefile +2
-0@@ -39,6 +39,14 @@ KMSAN_SANITIZE_sev.o := n # first second. KCOV_INSTRUMENT_head$(BITS).o := n KCOV_INSTRUMENT_sev.o := n +# These are called from save_stack_trace() on debug paths, +# and produce large amounts of uninteresting coverage.
arch/x86/kernel/Makefile KMSAN_SANITIZE_sev.o := n
Quoted 10 lines
arch/x86/kernel/Makefile +6
-1+KCOV_INSTRUMENT_stacktrace.o := n +KCOV_INSTRUMENT_dumpstack.o := n +KCOV_INSTRUMENT_dumpstack_$(BITS).o := n +KCOV_INSTRUMENT_unwind_orc.o := n +KCOV_INSTRUMENT_unwind_frame.o := n +KCOV_INSTRUMENT_unwind_guess.o := n CFLAGS_irq.o := -I $(src)/../include/asm/trace --
Re: [PATCH v2 4/4] x86: Ignore stack unwinding in KCOV
In reply to Dmitry VyukovQuoted 4 lines · Dmitry Vyukov
Stack unwinding produces large amounts of uninteresting coverage. It's called from KASAN kmalloc/kfree hooks, fault injection, etc. It's not particularly useful and is not a function of system call args. Ignore that code.
This stems from KCOV's purpose being guiding syzkaller as opposed to it being a more general coverage tool, right?
Is that spelled out anywhere?
Anyway,
Quoted 32 lines
Signed-off-by Dmitry Vyukov <[email protected]>Reviewed-by Alexander Potapenko <[email protected]>Reviewed-by Marco Elver <[email protected]>--- arch/x86/kernel/Makefile | 8 ++++++++ 1 file changed, 8 insertions(+)arch/x86/kernel/Makefile +8
-0@@ -39,6 +39,14 @@ KMSAN_SANITIZE_sev.o := n # first second. KCOV_INSTRUMENT_head$(BITS).o := n KCOV_INSTRUMENT_sev.o := n +# These are called from save_stack_trace() on debug paths, +# and produce large amounts of uninteresting coverage. +KCOV_INSTRUMENT_stacktrace.o := n +KCOV_INSTRUMENT_dumpstack.o := n +KCOV_INSTRUMENT_dumpstack_$(BITS).o := n +KCOV_INSTRUMENT_unwind_orc.o := n +KCOV_INSTRUMENT_unwind_frame.o := n +KCOV_INSTRUMENT_unwind_guess.o := n CFLAGS_irq.o := -I $(src)/../include/asm/traceSignature · 1 line
2.45.2.505.gda0bf45e8d-goog
Dmitry Vyukov
reviewerRe: [PATCH v2 4/4] x86: Ignore stack unwinding in KCOV
Quoted 11 lines · Peter Zijlstra
Quoted 4 lines · Dmitry Vyukov
Stack unwinding produces large amounts of uninteresting coverage. It's called from KASAN kmalloc/kfree hooks, fault injection, etc. It's not particularly useful and is not a function of system call args. Ignore that code.
This stems from KCOV's purpose being guiding syzkaller as opposed to it being a more general coverage tool, right?
Is that spelled out anywhere?
It may be used for other similar purposes as well, e.g. collecting unit test coverage (not the whole kernel, but a single specific test provided that even other tests can run and collect their own coverage in parallel).
It's spelled explicitly in the docs:
https://elixir.bootlin.com/linux/latest/source/Documentation/dev-tools/kcov.rst
"""
KCOV collects and exposes kernel code coverage information in a form suitable for coverage-guided fuzzing .... Coverage collection is enabled on a task basis, and
thus KCOV can capture precise coverage of a single system call.
Note that KCOV does not aim to collect as much coverage as possible. It aims to collect more or less stable coverage that is a function of syscall inputs. To achieve this goal, it does not collect coverage in soft/hard interrupts... """
Quoted 3 lines
Anyway,
Thanks for your reviews, Peter!
Quoted 37 lines
Quoted 30 lines
Signed-off-by Dmitry Vyukov <[email protected]>Reviewed-by Alexander Potapenko <[email protected]>Reviewed-by Marco Elver <[email protected]>--- arch/x86/kernel/Makefile | 8 ++++++++ 1 file changed, 8 insertions(+)arch/x86/kernel/Makefile +8
-1@@ -39,6 +39,14 @@ KMSAN_SANITIZE_sev.o := n # first second. KCOV_INSTRUMENT_head$(BITS).o := n KCOV_INSTRUMENT_sev.o := n +# These are called from save_stack_trace() on debug paths, +# and produce large amounts of uninteresting coverage. +KCOV_INSTRUMENT_stacktrace.o := n +KCOV_INSTRUMENT_dumpstack.o := n +KCOV_INSTRUMENT_dumpstack_$(BITS).o := n +KCOV_INSTRUMENT_unwind_orc.o := n +KCOV_INSTRUMENT_unwind_frame.o := n +KCOV_INSTRUMENT_unwind_guess.o := n CFLAGS_irq.o := -I $(src)/../include/asm/trace --Quoted 2 lines
2.45.2.505.gda0bf45e8d-goog
--
You received this message because you are subscribed to the Google Groups "syzkaller" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/syzkaller/20240619112332.GL31592%40noisy.programming.kicks-ass.net.
[tip: x86/build] x86: Ignore stack unwinding in KCOV
In reply to Dmitry VyukovThe following commit has been merged into the x86/build branch of tip:
The following commit has been merged into the x86/build branch of tip:
Commit-ID: ae94b263f5f69c180347e795fbefa051b65aacc3 Gitweb: https://git.kernel.org/tip/ae94b263f5f69c180347e795fbefa051b65aacc3 Author: Dmitry Vyukov <[email protected]> AuthorDate: Tue, 11 Jun 2024 09:50:33 +02:00 Committer: Thomas Gleixner <[email protected]> CommitterDate: Thu, 08 Aug 2024 17:36:35 +02:00
x86: Ignore stack unwinding in KCOV
Stack unwinding produces large amounts of uninteresting coverage. It's called from KASAN kmalloc/kfree hooks, fault injection, etc. It's not particularly useful and is not a function of system call args. Ignore that code.
--- arch/x86/kernel/Makefile | 8 ++++++++ 1 file changed, 8 insertions(+)
arch/x86/kernel/Makefile +8 -0
@@ -35,6 +35,14 @@ KMSAN_SANITIZE_nmi.o := n # If instrumentation of the following files is enabled, boot hangs during # first second. KCOV_INSTRUMENT_head$(BITS).o := n +# These are called from save_stack_trace() on debug paths, +# and produce large amounts of uninteresting coverage. +KCOV_INSTRUMENT_stacktrace.o := n +KCOV_INSTRUMENT_dumpstack.o := n +KCOV_INSTRUMENT_dumpstack_$(BITS).o := n +KCOV_INSTRUMENT_unwind_orc.o := n +KCOV_INSTRUMENT_unwind_frame.o := n +KCOV_INSTRUMENT_unwind_guess.o := n CFLAGS_irq.o := -I $(src)/../include/asm/trace
Dmitry Vyukov
reviewerQuoted 22 lines · Dmitry Vyukov
Fix spurious KCOV coverage from interrupts and add a test. Ignore some additional files that lead to large amounts of uninteresting coverage.
As a reference point, tracing a simple open system call produces ~10K PCs with these changes instead of ~45K PCs.Dmitry Vyukov (4):
x86/entry: Remove unwanted instrumentation incommon_interrupt()
kcov: add interrupt handling self test
module: Fix KCOV-ignored file name
x86: Ignore stack unwinding in KCOVarch/x86/include/asm/hardirq.h | 8 ++++++-- arch/x86/include/asm/idtentry.h | 6 +++--- arch/x86/kernel/Makefile | 8 ++++++++ kernel/kcov.c | 31 +++++++++++++++++++++++++++++++ kernel/module/Makefile | 2 +- lib/Kconfig.debug | 8 ++++++++ 6 files changed, 57 insertions(+), 6 deletions(-)
Quoted 3 lines
base-commit:
83a7eefedc9b56fe7bfeff13b6c7356688ffa670--
2.45.2.505.gda0bf45e8d-goog
Thomas, Ingo, Borislav, Dave,
Can you take this via x86 tree please?
Dmitry Vyukov
reviewerQuoted 21 lines · Dmitry Vyukov
Quoted 21 lines
Fix spurious KCOV coverage from interrupts and add a test. Ignore some additional files that lead to large amounts of uninteresting coverage.
As a reference point, tracing a simple open system call produces ~10K PCs with these changes instead of ~45K PCs.Dmitry Vyukov (4):
x86/entry: Remove unwanted instrumentation incommon_interrupt()
kcov: add interrupt handling self test
module: Fix KCOV-ignored file name
x86: Ignore stack unwinding in KCOVarch/x86/include/asm/hardirq.h | 8 ++++++-- arch/x86/include/asm/idtentry.h | 6 +++--- arch/x86/kernel/Makefile | 8 ++++++++ kernel/kcov.c | 31 +++++++++++++++++++++++++++++++ kernel/module/Makefile | 2 +- lib/Kconfig.debug | 8 ++++++++ 6 files changed, 57 insertions(+), 6 deletions(-)
Quoted 7 lines
Quoted 3 lines
base-commit:
83a7eefedc9b56fe7bfeff13b6c7356688ffa670--
2.45.2.505.gda0bf45e8d-googThomas, Ingo, Borislav, Dave,
Can you take this via x86 tree please?
Or is it OK to take this via mm tree (where KCOV changes usually go)?
Borislav Petkov
maintainerQuoted 1 line · Dmitry Vyukov
Or is it OK to take this via mm tree (where KCOV changes usually go)?
Be patient, pls, you're on the TODO list.
Signature · 4 lines
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquetteAndrey Konovalov
reviewerQuoted 5 lines · Borislav Petkov
Quoted 1 line · Dmitry Vyukov
Or is it OK to take this via mm tree (where KCOV changes usually go)?
Be patient, pls, you're on the TODO list.
Hi Borislav,
I was wondering what's the status of these patches? They didn't make it into 6.11 and I also still don't see them in linux-next.
Thank you!
Quoted 11 lines · Andrey Konovalov
Quoted 5 lines · Borislav Petkov
Quoted 1 line · Dmitry Vyukov
Or is it OK to take this via mm tree (where KCOV changes usually go)?
Be patient, pls, you're on the TODO list.
Hi Borislav,
I was wondering what's the status of these patches? They didn't make it into 6.11 and I also still don't see them in linux-next.
Sorry. That fell through the cracks. I'm picking it up now.