}
 }
 
-/*
- * AMD Erratum 400 aware idle routine. We handle it the same way as C3 power
- * states (local apic timer and TSC stop).
- *
- * XXX this function is completely buggered vs RCU and tracing.
- */
-static void amd_e400_idle(void)
-{
-       /*
-        * We cannot use static_cpu_has_bug() here because X86_BUG_AMD_APIC_C1E
-        * gets set after static_cpu_has() places have been converted via
-        * alternatives.
-        */
-       if (!boot_cpu_has_bug(X86_BUG_AMD_APIC_C1E)) {
-               default_idle();
-               return;
-       }
-
-       tick_broadcast_enter();
-
-       default_idle();
-
-       tick_broadcast_exit();
-}
-
 /*
  * Prefer MWAIT over HALT if MWAIT is supported, MWAIT_CPUID leaf
  * exists and whenever MONITOR/MWAIT extensions are present there is at
        if (!cpu_has(c, X86_FEATURE_MWAIT))
                return 0;
 
-       /* Monitor has a bug. Fallback to HALT */
-       if (boot_cpu_has_bug(X86_BUG_MONITOR))
+       /* Monitor has a bug or APIC stops in C1E. Fallback to HALT */
+       if (boot_cpu_has_bug(X86_BUG_MONITOR) || boot_cpu_has_bug(X86_BUG_AMD_APIC_C1E))
                return 0;
 
        cpuid(CPUID_MWAIT_LEAF, &eax, &ebx, &ecx, &edx);
        if (x86_idle_set() || boot_option_idle_override == IDLE_POLL)
                return;
 
-       if (boot_cpu_has_bug(X86_BUG_AMD_E400)) {
-               pr_info("using AMD E400 aware idle routine\n");
-               static_call_update(x86_idle, amd_e400_idle);
-       } else if (prefer_mwait_c1_over_halt(c)) {
+       if (prefer_mwait_c1_over_halt(c)) {
                pr_info("using mwait in idle threads\n");
                static_call_update(x86_idle, mwait_idle);
        } else if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST)) {
                pr_info("using TDX aware idle routine\n");
                static_call_update(x86_idle, tdx_safe_halt);
-       } else
+       } else {
                static_call_update(x86_idle, default_idle);
+       }
 }
 
 void amd_e400_c1e_apic_setup(void)
 
        if (!boot_cpu_has(X86_FEATURE_NONSTOP_TSC))
                mark_tsc_unstable("TSC halt in AMD C1E");
-       pr_info("System has AMD C1E enabled\n");
+
+       if (IS_ENABLED(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST_IDLE))
+               static_branch_enable(&arch_needs_tick_broadcast);
+       pr_info("System has AMD C1E erratum E400. Workaround enabled.\n");
 }
 
 static int __init idle_setup(char *str)