mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-01 06:33:07 +00:00
x86/mce: Address objtools noinstr complaints
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
This commit is contained in:
parent
75347bb253
commit
865d3a9afe
4 changed files with 22 additions and 8 deletions
|
@ -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);
|
BLOCKING_NOTIFIER_HEAD(x86_mce_decoder_chain);
|
||||||
|
|
||||||
/* Do initial initialization of a struct mce */
|
/* 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));
|
memset(m, 0, sizeof(struct mce));
|
||||||
m->cpu = m->extcpu = smp_processor_id();
|
m->cpu = m->extcpu = smp_processor_id();
|
||||||
|
@ -140,12 +140,12 @@ void mce_setup(struct mce *m)
|
||||||
m->cpuid = cpuid_eax(1);
|
m->cpuid = cpuid_eax(1);
|
||||||
m->socketid = cpu_data(m->extcpu).phys_proc_id;
|
m->socketid = cpu_data(m->extcpu).phys_proc_id;
|
||||||
m->apicid = cpu_data(m->extcpu).initial_apicid;
|
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))
|
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))
|
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;
|
m->microcode = boot_cpu_data.microcode;
|
||||||
}
|
}
|
||||||
|
@ -1895,10 +1895,12 @@ bool filter_mce(struct mce *m)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle unconfigured int18 (should never happen) */
|
/* 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",
|
pr_err("CPU#%d: Unexpected int18 (Machine Check)\n",
|
||||||
smp_processor_id());
|
smp_processor_id());
|
||||||
|
instrumentation_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Call the installed machine check handler for this CPU setup. */
|
/* 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;
|
return;
|
||||||
|
|
||||||
nmi_enter();
|
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);
|
machine_check_vector(regs);
|
||||||
|
instrumentation_end();
|
||||||
nmi_exit();
|
nmi_exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
static __always_inline void exc_machine_check_user(struct pt_regs *regs)
|
static __always_inline void exc_machine_check_user(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
idtentry_enter(regs);
|
idtentry_enter(regs);
|
||||||
|
instrumentation_begin();
|
||||||
machine_check_vector(regs);
|
machine_check_vector(regs);
|
||||||
|
instrumentation_end();
|
||||||
idtentry_exit(regs);
|
idtentry_exit(regs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,10 +21,11 @@
|
||||||
int mce_p5_enabled __read_mostly;
|
int mce_p5_enabled __read_mostly;
|
||||||
|
|
||||||
/* Machine check handler for Pentium class Intel CPUs: */
|
/* 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;
|
u32 loaddr, hi, lotype;
|
||||||
|
|
||||||
|
instrumentation_begin();
|
||||||
rdmsr(MSR_IA32_P5_MC_ADDR, loaddr, hi);
|
rdmsr(MSR_IA32_P5_MC_ADDR, loaddr, hi);
|
||||||
rdmsr(MSR_IA32_P5_MC_TYPE, lotype, 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);
|
add_taint(TAINT_MACHINE_CHECK, LOCKDEP_NOW_UNRELIABLE);
|
||||||
|
instrumentation_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set up machine check reporting for processors with Intel style MCE: */
|
/* Set up machine check reporting for processors with Intel style MCE: */
|
||||||
|
|
|
@ -17,10 +17,12 @@
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
/* Machine check handler for WinChip C6: */
|
/* 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");
|
pr_emerg("CPU0: Machine Check Exception.\n");
|
||||||
add_taint(TAINT_MACHINE_CHECK, LOCKDEP_NOW_UNRELIABLE);
|
add_taint(TAINT_MACHINE_CHECK, LOCKDEP_NOW_UNRELIABLE);
|
||||||
|
instrumentation_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set up machine check reporting on the Winchip C6 series */
|
/* Set up machine check reporting on the Winchip C6 series */
|
||||||
|
|
|
@ -953,7 +953,7 @@ EXPORT_SYMBOL_GPL(ktime_get_real_seconds);
|
||||||
* but without the sequence counter protect. This internal function
|
* but without the sequence counter protect. This internal function
|
||||||
* is called just when timekeeping lock is already held.
|
* 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;
|
struct timekeeper *tk = &tk_core.timekeeper;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue