]> Git Repo - J-linux.git/commitdiff
Merge tag 'x86-build-2024-09-17' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <[email protected]>
Tue, 17 Sep 2024 10:40:34 +0000 (12:40 +0200)
committerLinus Torvalds <[email protected]>
Tue, 17 Sep 2024 10:40:34 +0000 (12:40 +0200)
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()

1  2 
kernel/kcov.c
lib/Kconfig.debug

diff --combined kernel/kcov.c
index 274b6b7c718de6ba3eb90d3593ac494b30b25688,d9d4a0c041855732b61d2d5e2771006bb4fb9209..28a6be6e64fdd721d49c4040ed10ce33f9d890a1
@@@ -11,6 -11,7 +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>
@@@ -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;
         * 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;
         */
        debugfs_create_file_unsafe("kcov", 0600, NULL, NULL, &kcov_fops);
  
+ #ifdef CONFIG_KCOV_SELFTEST
+       selftest();
+ #endif
        return 0;
  }
  
diff --combined lib/Kconfig.debug
index a40aa606cd04f3a5cad1c7be5058de2f62e98044,270e367b3e6f5931b5012d72dc0c86bdfae1285f..26354671b37df6387198ed2c217d0b1f52182984
@@@ -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
This page took 0.09306 seconds and 4 git commands to generate.