x86/timer: Don't skip PIT setup when APIC is disabled or in legacy mode
[sfrench/cifs-2.6.git] / arch / x86 / kernel / apic / apic.c
index 28446fa6bf1851d54da7f6ab9fa79648966712e8..4b0f9117e1cd8ce68f1f7514e5f8584f327f23a2 100644 (file)
@@ -830,8 +830,17 @@ bool __init apic_needs_pit(void)
        if (!tsc_khz || !cpu_khz)
                return true;
 
-       /* Is there an APIC at all? */
-       if (!boot_cpu_has(X86_FEATURE_APIC))
+       /* Is there an APIC at all or is it disabled? */
+       if (!boot_cpu_has(X86_FEATURE_APIC) || disable_apic)
+               return true;
+
+       /*
+        * If interrupt delivery mode is legacy PIC or virtual wire without
+        * configuration, the local APIC timer wont be set up. Make sure
+        * that the PIT is initialized.
+        */
+       if (apic_intr_mode == APIC_PIC ||
+           apic_intr_mode == APIC_VIRTUAL_WIRE_NO_CONFIG)
                return true;
 
        /* Virt guests may lack ARAT, but still have DEADLINE */
@@ -1322,7 +1331,7 @@ void __init sync_Arb_IDs(void)
 
 enum apic_intr_mode_id apic_intr_mode __ro_after_init;
 
-static int __init apic_intr_mode_select(void)
+static int __init __apic_intr_mode_select(void)
 {
        /* Check kernel option */
        if (disable_apic) {
@@ -1384,6 +1393,12 @@ static int __init apic_intr_mode_select(void)
        return APIC_SYMMETRIC_IO;
 }
 
+/* Select the interrupt delivery mode for the BSP */
+void __init apic_intr_mode_select(void)
+{
+       apic_intr_mode = __apic_intr_mode_select();
+}
+
 /*
  * An initial setup of the virtual wire mode.
  */
@@ -1440,8 +1455,6 @@ void __init apic_intr_mode_init(void)
 {
        bool upmode = IS_ENABLED(CONFIG_UP_LATE_INIT);
 
-       apic_intr_mode = apic_intr_mode_select();
-
        switch (apic_intr_mode) {
        case APIC_PIC:
                pr_info("APIC: Keep in PIC mode(8259)\n");