diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 29bbbce4f2fd..ced76f13d20d 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -418,6 +418,29 @@ void __init init_amd_e400_c1e_mask(void) zalloc_cpumask_var(&amd_e400_c1e_mask, GFP_KERNEL); } +void __init arch_post_acpi_subsys_init(void) +{ + u32 lo, hi; + + if (!boot_cpu_has_bug(X86_BUG_AMD_E400)) + return; + + /* + * AMD E400 detection needs to happen after ACPI has been enabled. If + * the machine is affected K8_INTP_C1E_ACTIVE_MASK bits are set in + * MSR_K8_INT_PENDING_MSG. + */ + rdmsr(MSR_K8_INT_PENDING_MSG, lo, hi); + if (!(lo & K8_INTP_C1E_ACTIVE_MASK)) + return; + + boot_cpu_set_bug(X86_BUG_AMD_APIC_C1E); + + if (!boot_cpu_has(X86_FEATURE_NONSTOP_TSC)) + mark_tsc_unstable("TSC halt in AMD C1E"); + pr_info("System has AMD C1E enabled\n"); +} + static int __init idle_setup(char *str) { if (!str) diff --git a/init/main.c b/init/main.c index 2858be732f6d..1d7038c1ee19 100644 --- a/init/main.c +++ b/init/main.c @@ -448,6 +448,8 @@ void __init parse_early_param(void) done = 1; } +void __init __weak arch_post_acpi_subsys_init(void) { } + void __init __weak smp_setup_processor_id(void) { } @@ -649,6 +651,7 @@ asmlinkage __visible void __init start_kernel(void) check_bugs(); acpi_subsystem_init(); + arch_post_acpi_subsys_init(); sfi_init_late(); if (efi_enabled(EFI_RUNTIME_SERVICES)) {