x86/mce: Address objtools noinstr complaints
authorThomas Gleixner <tglx@linutronix.de>
Tue, 21 Apr 2020 19:22:36 +0000 (21:22 +0200)
committerThomas Gleixner <tglx@linutronix.de>
Thu, 11 Jun 2020 13:15:02 +0000 (15:15 +0200)
Mark the relevant functions noinstr, use the plain non-instrumented MSR
accessors. The only odd part is the instrumentation_begin()/end() pair around the
indirect machine_check_vector() call as objtool can't figure that out. The
possible invoked functions are annotated correctly.

Also use notrace variant of nmi_enter/exit(). If MCEs happen then hardware
latency tracing is the least of the worries.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Alexandre Chartre <alexandre.chartre@oracle.com>
Acked-by: Peter Zijlstra <peterz@infradead.org>
Acked-by: Andy Lutomirski <luto@kernel.org>
Link: https://lkml.kernel.org/r/20200505135315.476734898@linutronix.de
arch/x86/kernel/cpu/mce/core.c
arch/x86/kernel/cpu/mce/p5.c
arch/x86/kernel/cpu/mce/winchip.c
kernel/time/timekeeping.c

index a72c013..a32a7e2 100644 (file)
@@ -130,7 +130,7 @@ static void (*quirk_no_way_out)(int bank, struct mce *m, struct pt_regs *regs);
 BLOCKING_NOTIFIER_HEAD(x86_mce_decoder_chain);
 
 /* Do initial initialization of a struct mce */
-void mce_setup(struct mce *m)
+noinstr void mce_setup(struct mce *m)
 {
        memset(m, 0, sizeof(struct mce));
        m->cpu = m->extcpu = smp_processor_id();
@@ -140,12 +140,12 @@ void mce_setup(struct mce *m)
        m->cpuid = cpuid_eax(1);
        m->socketid = cpu_data(m->extcpu).phys_proc_id;
        m->apicid = cpu_data(m->extcpu).initial_apicid;
-       rdmsrl(MSR_IA32_MCG_CAP, m->mcgcap);
+       m->mcgcap = __rdmsr(MSR_IA32_MCG_CAP);
 
        if (this_cpu_has(X86_FEATURE_INTEL_PPIN))
-               rdmsrl(MSR_PPIN, m->ppin);
+               m->ppin = __rdmsr(MSR_PPIN);
        else if (this_cpu_has(X86_FEATURE_AMD_PPIN))
-               rdmsrl(MSR_AMD_PPIN, m->ppin);
+               m->ppin = __rdmsr(MSR_AMD_PPIN);
 
        m->microcode = boot_cpu_data.microcode;
 }
@@ -1895,10 +1895,12 @@ bool filter_mce(struct mce *m)
 }
 
 /* Handle unconfigured int18 (should never happen) */
-static void unexpected_machine_check(struct pt_regs *regs)
+static noinstr void unexpected_machine_check(struct pt_regs *regs)
 {
+       instrumentation_begin();
        pr_err("CPU#%d: Unexpected int18 (Machine Check)\n",
               smp_processor_id());
+       instrumentation_end();
 }
 
 /* Call the installed machine check handler for this CPU setup. */
@@ -1915,14 +1917,22 @@ static __always_inline void exc_machine_check_kernel(struct pt_regs *regs)
                return;
 
        nmi_enter();
+       /*
+        * The call targets are marked noinstr, but objtool can't figure
+        * that out because it's an indirect call. Annotate it.
+        */
+       instrumentation_begin();
        machine_check_vector(regs);
+       instrumentation_end();
        nmi_exit();
 }
 
 static __always_inline void exc_machine_check_user(struct pt_regs *regs)
 {
        idtentry_enter(regs);
+       instrumentation_begin();
        machine_check_vector(regs);
+       instrumentation_end();
        idtentry_exit(regs);
 }
 
index eaebc4c..19e90ca 100644 (file)
 int mce_p5_enabled __read_mostly;
 
 /* Machine check handler for Pentium class Intel CPUs: */
-static void pentium_machine_check(struct pt_regs *regs)
+static noinstr void pentium_machine_check(struct pt_regs *regs)
 {
        u32 loaddr, hi, lotype;
 
+       instrumentation_begin();
        rdmsr(MSR_IA32_P5_MC_ADDR, loaddr, hi);
        rdmsr(MSR_IA32_P5_MC_TYPE, lotype, hi);
 
@@ -37,6 +38,7 @@ static void pentium_machine_check(struct pt_regs *regs)
        }
 
        add_taint(TAINT_MACHINE_CHECK, LOCKDEP_NOW_UNRELIABLE);
+       instrumentation_end();
 }
 
 /* Set up machine check reporting for processors with Intel style MCE: */
index 90e3d60..9c9f0ab 100644 (file)
 #include "internal.h"
 
 /* Machine check handler for WinChip C6: */
-static void winchip_machine_check(struct pt_regs *regs)
+static noinstr void winchip_machine_check(struct pt_regs *regs)
 {
+       instrumentation_begin();
        pr_emerg("CPU0: Machine Check Exception.\n");
        add_taint(TAINT_MACHINE_CHECK, LOCKDEP_NOW_UNRELIABLE);
+       instrumentation_end();
 }
 
 /* Set up machine check reporting on the Winchip C6 series */
index 9ebaab1..d20d489 100644 (file)
@@ -953,7 +953,7 @@ EXPORT_SYMBOL_GPL(ktime_get_real_seconds);
  * but without the sequence counter protect. This internal function
  * is called just when timekeeping lock is already held.
  */
-time64_t __ktime_get_real_seconds(void)
+noinstr time64_t __ktime_get_real_seconds(void)
 {
        struct timekeeper *tk = &tk_core.timekeeper;