@@ -29,7 +29,7 @@ mci_action_add_pageoffline(int bank, str
mce_check_addr_t mc_check_addr = NULL;
-void mce_register_addrcheck(mce_check_addr_t cbfunc)
+void __init mce_register_addrcheck(mce_check_addr_t cbfunc)
{
mc_check_addr = cbfunc;
}
@@ -84,7 +84,7 @@ static void cf_check unexpected_machine_
static x86_mce_vector_t _machine_check_vector = unexpected_machine_check;
-void x86_mce_vector_register(x86_mce_vector_t hdlr)
+void __init x86_mce_vector_register(x86_mce_vector_t hdlr)
{
_machine_check_vector = hdlr;
}
@@ -107,7 +107,7 @@ void do_machine_check(const struct cpu_u
*/
static x86_mce_callback_t mc_callback_bank_extended = NULL;
-void x86_mce_callback_register(x86_mce_callback_t cbfunc)
+void __init x86_mce_callback_register(x86_mce_callback_t cbfunc)
{
mc_callback_bank_extended = cbfunc;
}
@@ -118,7 +118,7 @@ void x86_mce_callback_register(x86_mce_c
*/
static mce_recoverable_t mc_recoverable_scan = NULL;
-void mce_recoverable_register(mce_recoverable_t cbfunc)
+void __init mce_recoverable_register(mce_recoverable_t cbfunc)
{
mc_recoverable_scan = cbfunc;
}
@@ -181,7 +181,7 @@ static void mcabank_clear(int banknum)
*/
static mce_need_clearbank_t mc_need_clearbank_scan = NULL;
-void mce_need_clearbank_register(mce_need_clearbank_t cbfunc)
+void __init mce_need_clearbank_register(mce_need_clearbank_t cbfunc)
{
mc_need_clearbank_scan = cbfunc;
}
@@ -798,7 +798,7 @@ void mcheck_init(struct cpuinfo_x86 *c,
{
case X86_VENDOR_AMD:
case X86_VENDOR_HYGON:
- inited = amd_mcheck_init(c);
+ inited = amd_mcheck_init(c, bsp);
break;
case X86_VENDOR_INTEL:
@@ -1913,11 +1913,8 @@ static void cf_check mce_softirq(void)
* will help to collect and log those MCE errors.
* Round2: Do all MCE processing logic as normal.
*/
-void mce_handler_init(void)
+void __init mce_handler_init(void)
{
- if ( smp_processor_id() != 0 )
- return;
-
/* callback register, do we really need so many callback? */
/* mce handler data initialization */
spin_lock_init(&mce_logout_lock);
@@ -43,7 +43,7 @@ extern uint8_t cmci_apic_vector;
extern bool lmce_support;
/* Init functions */
-enum mcheck_type amd_mcheck_init(const struct cpuinfo_x86 *c);
+enum mcheck_type amd_mcheck_init(const struct cpuinfo_x86 *c, bool bsp);
enum mcheck_type intel_mcheck_init(struct cpuinfo_x86 *c, bool bsp);
void amd_nonfatal_mcheck_init(struct cpuinfo_x86 *c);
@@ -272,7 +272,7 @@ int vmce_amd_rdmsr(const struct vcpu *v,
}
enum mcheck_type
-amd_mcheck_init(const struct cpuinfo_x86 *c)
+amd_mcheck_init(const struct cpuinfo_x86 *c, bool bsp)
{
uint32_t i;
enum mcequirk_amd_flags quirkflag = 0;
@@ -282,9 +282,12 @@ amd_mcheck_init(const struct cpuinfo_x86
/* Assume that machine check support is available.
* The minimum provided support is at least the K8. */
- mce_handler_init();
- x86_mce_vector_register(mcheck_cmn_handler);
- mce_need_clearbank_register(amd_need_clearbank_scan);
+ if ( bsp )
+ {
+ mce_handler_init();
+ x86_mce_vector_register(mcheck_cmn_handler);
+ mce_need_clearbank_register(amd_need_clearbank_scan);
+ }
for ( i = 0; i < this_cpu(nr_mce_banks); i++ )
{
@@ -324,9 +327,12 @@ amd_mcheck_init(const struct cpuinfo_x86
ppin_msr = MSR_AMD_PPIN;
}
- x86_mce_callback_register(amd_f10_handler);
- mce_recoverable_register(mc_amd_recoverable_scan);
- mce_register_addrcheck(mc_amd_addrcheck);
+ if ( bsp )
+ {
+ x86_mce_callback_register(amd_f10_handler);
+ mce_recoverable_register(mc_amd_recoverable_scan);
+ mce_register_addrcheck(mc_amd_addrcheck);
+ }
return c->x86_vendor == X86_VENDOR_HYGON ?
mcheck_hygon : mcheck_amd_famXX;
@@ -820,7 +820,7 @@ static void intel_mce_post_reset(void)
return;
}
-static void intel_init_mce(void)
+static void intel_init_mce(bool bsp)
{
uint64_t msr_content;
int i;
@@ -846,6 +846,9 @@ static void intel_init_mce(void)
if ( firstbank ) /* if cmci enabled, firstbank = 0 */
wrmsrl(MSR_IA32_MC0_STATUS, 0x0ULL);
+ if ( !bsp )
+ return;
+
x86_mce_vector_register(mcheck_cmn_handler);
mce_recoverable_register(intel_recoverable_scan);
mce_need_clearbank_register(intel_need_clearbank_scan);
@@ -985,9 +988,10 @@ enum mcheck_type intel_mcheck_init(struc
intel_init_mca(c);
- mce_handler_init();
+ if ( bsp )
+ mce_handler_init();
- intel_init_mce();
+ intel_init_mce(bsp);
intel_init_cmci(c);
Several function pointers are registered over and over again, when setting them once on the BSP suffices. Arrange for this in the vendor init functions and mark involved registration functions __init. Signed-off-by: Jan Beulich <jbeulich@suse.com>