forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-13 9d77db3c730780c8ef5ccd4b66403ff5675cfe4e
kernel/arch/x86/kernel/apic/apic.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Local APIC handling, local APIC timers
34 *
....@@ -20,7 +21,7 @@
2021 #include <linux/acpi_pmtmr.h>
2122 #include <linux/clockchips.h>
2223 #include <linux/interrupt.h>
23
-#include <linux/bootmem.h>
24
+#include <linux/memblock.h>
2425 #include <linux/ftrace.h>
2526 #include <linux/ioport.h>
2627 #include <linux/export.h>
....@@ -39,13 +40,14 @@
3940 #include <asm/irq_remapping.h>
4041 #include <asm/perf_event.h>
4142 #include <asm/x86_init.h>
42
-#include <asm/pgalloc.h>
4343 #include <linux/atomic.h>
4444 #include <asm/barrier.h>
4545 #include <asm/mpspec.h>
4646 #include <asm/i8259.h>
4747 #include <asm/proto.h>
48
+#include <asm/traps.h>
4849 #include <asm/apic.h>
50
+#include <asm/acpi.h>
4951 #include <asm/io_apic.h>
5052 #include <asm/desc.h>
5153 #include <asm/hpet.h>
....@@ -64,10 +66,10 @@
6466 unsigned disabled_cpus;
6567
6668 /* Processor that is doing the boot up */
67
-unsigned int boot_cpu_physical_apicid = -1U;
69
+unsigned int boot_cpu_physical_apicid __ro_after_init = -1U;
6870 EXPORT_SYMBOL_GPL(boot_cpu_physical_apicid);
6971
70
-u8 boot_cpu_apic_version;
72
+u8 boot_cpu_apic_version __ro_after_init;
7173
7274 /*
7375 * The highest APIC ID seen during enumeration.
....@@ -84,13 +86,13 @@
8486 * disable_cpu_apicid=<int>, mostly used for the kdump 2nd kernel to
8587 * avoid undefined behaviour caused by sending INIT from AP to BSP.
8688 */
87
-static unsigned int disabled_cpu_apicid __read_mostly = BAD_APICID;
89
+static unsigned int disabled_cpu_apicid __ro_after_init = BAD_APICID;
8890
8991 /*
9092 * This variable controls which CPUs receive external NMIs. By default,
9193 * external NMIs are delivered only to the BSP.
9294 */
93
-static int apic_extnmi = APIC_EXTNMI_BSP;
95
+static int apic_extnmi __ro_after_init = APIC_EXTNMI_BSP;
9496
9597 /*
9698 * Map cpu index to physical APIC ID
....@@ -113,7 +115,7 @@
113115 DEFINE_EARLY_PER_CPU_READ_MOSTLY(int, x86_cpu_to_logical_apicid, BAD_APICID);
114116
115117 /* Local APIC was disabled by the BIOS and enabled by the kernel */
116
-static int enabled_via_apicbase;
118
+static int enabled_via_apicbase __ro_after_init;
117119
118120 /*
119121 * Handle interrupt mode configuration register (IMCR).
....@@ -166,39 +168,39 @@
166168 {
167169 apic_calibrate_pmtmr = 1;
168170 notsc_setup(NULL);
169
- return 0;
171
+ return 1;
170172 }
171173 __setup("apicpmtimer", setup_apicpmtimer);
172174 #endif
173175
174
-unsigned long mp_lapic_addr;
175
-int disable_apic;
176
+unsigned long mp_lapic_addr __ro_after_init;
177
+int disable_apic __ro_after_init;
176178 /* Disable local APIC timer from the kernel commandline or via dmi quirk */
177179 static int disable_apic_timer __initdata;
178180 /* Local APIC timer works in C2 */
179
-int local_apic_timer_c2_ok;
181
+int local_apic_timer_c2_ok __ro_after_init;
180182 EXPORT_SYMBOL_GPL(local_apic_timer_c2_ok);
181183
182184 /*
183185 * Debug level, exported for io_apic.c
184186 */
185
-int apic_verbosity;
187
+int apic_verbosity __ro_after_init;
186188
187
-int pic_mode;
189
+int pic_mode __ro_after_init;
188190
189191 /* Have we found an MP table */
190
-int smp_found_config;
192
+int smp_found_config __ro_after_init;
191193
192194 static struct resource lapic_resource = {
193195 .name = "Local APIC",
194196 .flags = IORESOURCE_MEM | IORESOURCE_BUSY,
195197 };
196198
197
-unsigned int lapic_timer_frequency = 0;
199
+unsigned int lapic_timer_period = 0;
198200
199201 static void apic_pm_activate(void);
200202
201
-static unsigned long apic_phys;
203
+static unsigned long apic_phys __ro_after_init;
202204
203205 /*
204206 * Get the LAPIC version
....@@ -225,6 +227,11 @@
225227 if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
226228 boot_cpu_data.x86 >= 0xf)
227229 return 1;
230
+
231
+ /* Hygon systems use modern APIC */
232
+ if (boot_cpu_data.x86_vendor == X86_VENDOR_HYGON)
233
+ return 1;
234
+
228235 return lapic_get_version() >= 0x14;
229236 }
230237
....@@ -403,10 +410,9 @@
403410 if (vector && !eilvt_entry_is_changeable(vector, new))
404411 /* may not change if vectors are different */
405412 return rsvd;
406
- rsvd = atomic_cmpxchg(&eilvt_offsets[offset], rsvd, new);
407
- } while (rsvd != new);
413
+ } while (!atomic_try_cmpxchg(&eilvt_offsets[offset], &rsvd, new));
408414
409
- rsvd &= ~APIC_EILVT_MASKED;
415
+ rsvd = new & ~APIC_EILVT_MASKED;
410416 if (rsvd && rsvd != vector)
411417 pr_info("LVT offset %d assigned for vector 0x%02x\n",
412418 offset, rsvd);
....@@ -496,7 +502,7 @@
496502 if (evt->features & CLOCK_EVT_FEAT_DUMMY)
497503 return 0;
498504
499
- __setup_APIC_LVTT(lapic_timer_frequency, oneshot, 1);
505
+ __setup_APIC_LVTT(lapic_timer_period, oneshot, 1);
500506 return 0;
501507 }
502508
....@@ -541,65 +547,33 @@
541547 };
542548 static DEFINE_PER_CPU(struct clock_event_device, lapic_events);
543549
544
-#define DEADLINE_MODEL_MATCH_FUNC(model, func) \
545
- { X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, (unsigned long)&func }
546
-
547
-#define DEADLINE_MODEL_MATCH_REV(model, rev) \
548
- { X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, (unsigned long)rev }
549
-
550
-static __init u32 hsx_deadline_rev(void)
551
-{
552
- switch (boot_cpu_data.x86_stepping) {
553
- case 0x02: return 0x3a; /* EP */
554
- case 0x04: return 0x0f; /* EX */
555
- }
556
-
557
- return ~0U;
558
-}
559
-
560
-static __init u32 bdx_deadline_rev(void)
561
-{
562
- switch (boot_cpu_data.x86_stepping) {
563
- case 0x02: return 0x00000011;
564
- case 0x03: return 0x0700000e;
565
- case 0x04: return 0x0f00000c;
566
- case 0x05: return 0x0e000003;
567
- }
568
-
569
- return ~0U;
570
-}
571
-
572
-static __init u32 skx_deadline_rev(void)
573
-{
574
- switch (boot_cpu_data.x86_stepping) {
575
- case 0x03: return 0x01000136;
576
- case 0x04: return 0x02000014;
577
- }
578
-
579
- if (boot_cpu_data.x86_stepping > 4)
580
- return 0;
581
-
582
- return ~0U;
583
-}
584
-
585550 static const struct x86_cpu_id deadline_match[] __initconst = {
586
- DEADLINE_MODEL_MATCH_FUNC( INTEL_FAM6_HASWELL_X, hsx_deadline_rev),
587
- DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_BROADWELL_X, 0x0b000020),
588
- DEADLINE_MODEL_MATCH_FUNC( INTEL_FAM6_BROADWELL_XEON_D, bdx_deadline_rev),
589
- DEADLINE_MODEL_MATCH_FUNC( INTEL_FAM6_SKYLAKE_X, skx_deadline_rev),
551
+ X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(HASWELL_X, X86_STEPPINGS(0x2, 0x2), 0x3a), /* EP */
552
+ X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(HASWELL_X, X86_STEPPINGS(0x4, 0x4), 0x0f), /* EX */
590553
591
- DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_HASWELL_CORE, 0x22),
592
- DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_HASWELL_ULT, 0x20),
593
- DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_HASWELL_GT3E, 0x17),
554
+ X86_MATCH_INTEL_FAM6_MODEL( BROADWELL_X, 0x0b000020),
594555
595
- DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_BROADWELL_CORE, 0x25),
596
- DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_BROADWELL_GT3E, 0x17),
556
+ X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(BROADWELL_D, X86_STEPPINGS(0x2, 0x2), 0x00000011),
557
+ X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(BROADWELL_D, X86_STEPPINGS(0x3, 0x3), 0x0700000e),
558
+ X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(BROADWELL_D, X86_STEPPINGS(0x4, 0x4), 0x0f00000c),
559
+ X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(BROADWELL_D, X86_STEPPINGS(0x5, 0x5), 0x0e000003),
597560
598
- DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_SKYLAKE_MOBILE, 0xb2),
599
- DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_SKYLAKE_DESKTOP, 0xb2),
561
+ X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(SKYLAKE_X, X86_STEPPINGS(0x3, 0x3), 0x01000136),
562
+ X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(SKYLAKE_X, X86_STEPPINGS(0x4, 0x4), 0x02000014),
563
+ X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(SKYLAKE_X, X86_STEPPINGS(0x5, 0xf), 0),
600564
601
- DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_KABYLAKE_MOBILE, 0x52),
602
- DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_KABYLAKE_DESKTOP, 0x52),
565
+ X86_MATCH_INTEL_FAM6_MODEL( HASWELL, 0x22),
566
+ X86_MATCH_INTEL_FAM6_MODEL( HASWELL_L, 0x20),
567
+ X86_MATCH_INTEL_FAM6_MODEL( HASWELL_G, 0x17),
568
+
569
+ X86_MATCH_INTEL_FAM6_MODEL( BROADWELL, 0x25),
570
+ X86_MATCH_INTEL_FAM6_MODEL( BROADWELL_G, 0x17),
571
+
572
+ X86_MATCH_INTEL_FAM6_MODEL( SKYLAKE_L, 0xb2),
573
+ X86_MATCH_INTEL_FAM6_MODEL( SKYLAKE, 0xb2),
574
+
575
+ X86_MATCH_INTEL_FAM6_MODEL( KABYLAKE_L, 0x52),
576
+ X86_MATCH_INTEL_FAM6_MODEL( KABYLAKE, 0x52),
603577
604578 {},
605579 };
....@@ -618,14 +592,7 @@
618592 if (!m)
619593 return true;
620594
621
- /*
622
- * Function pointers will have the MSB set due to address layout,
623
- * immediate revisions will not.
624
- */
625
- if ((long)m->driver_data < 0)
626
- rev = ((u32 (*)(void))(m->driver_data))();
627
- else
628
- rev = (u32)m->driver_data;
595
+ rev = (u32)m->driver_data;
629596
630597 if (boot_cpu_data.microcode >= rev)
631598 return true;
....@@ -777,8 +744,8 @@
777744
778745 res = (((u64)deltapm) * mult) >> 22;
779746 do_div(res, 1000000);
780
- pr_warning("APIC calibration not consistent "
781
- "with PM-Timer: %ldms instead of 100ms\n",(long)res);
747
+ pr_warn("APIC calibration not consistent "
748
+ "with PM-Timer: %ldms instead of 100ms\n", (long)res);
782749
783750 /* Correct the lapic counter value */
784751 res = (((u64)(*delta)) * pm_100ms);
....@@ -800,6 +767,64 @@
800767 return 0;
801768 }
802769
770
+static int __init lapic_init_clockevent(void)
771
+{
772
+ if (!lapic_timer_period)
773
+ return -1;
774
+
775
+ /* Calculate the scaled math multiplication factor */
776
+ lapic_clockevent.mult = div_sc(lapic_timer_period/APIC_DIVISOR,
777
+ TICK_NSEC, lapic_clockevent.shift);
778
+ lapic_clockevent.max_delta_ns =
779
+ clockevent_delta2ns(0x7FFFFFFF, &lapic_clockevent);
780
+ lapic_clockevent.max_delta_ticks = 0x7FFFFFFF;
781
+ lapic_clockevent.min_delta_ns =
782
+ clockevent_delta2ns(0xF, &lapic_clockevent);
783
+ lapic_clockevent.min_delta_ticks = 0xF;
784
+
785
+ return 0;
786
+}
787
+
788
+bool __init apic_needs_pit(void)
789
+{
790
+ /*
791
+ * If the frequencies are not known, PIT is required for both TSC
792
+ * and apic timer calibration.
793
+ */
794
+ if (!tsc_khz || !cpu_khz)
795
+ return true;
796
+
797
+ /* Is there an APIC at all or is it disabled? */
798
+ if (!boot_cpu_has(X86_FEATURE_APIC) || disable_apic)
799
+ return true;
800
+
801
+ /*
802
+ * If interrupt delivery mode is legacy PIC or virtual wire without
803
+ * configuration, the local APIC timer wont be set up. Make sure
804
+ * that the PIT is initialized.
805
+ */
806
+ if (apic_intr_mode == APIC_PIC ||
807
+ apic_intr_mode == APIC_VIRTUAL_WIRE_NO_CONFIG)
808
+ return true;
809
+
810
+ /* Virt guests may lack ARAT, but still have DEADLINE */
811
+ if (!boot_cpu_has(X86_FEATURE_ARAT))
812
+ return true;
813
+
814
+ /* Deadline timer is based on TSC so no further PIT action required */
815
+ if (boot_cpu_has(X86_FEATURE_TSC_DEADLINE_TIMER))
816
+ return false;
817
+
818
+ /* APIC timer disabled? */
819
+ if (disable_apic_timer)
820
+ return true;
821
+ /*
822
+ * The APIC timer frequency is known already, no PIT calibration
823
+ * required. If unknown, let the PIT be initialized.
824
+ */
825
+ return lapic_timer_period == 0;
826
+}
827
+
803828 static int __init calibrate_APIC_clock(void)
804829 {
805830 struct clock_event_device *levt = this_cpu_ptr(&lapic_events);
....@@ -809,25 +834,21 @@
809834 long delta, deltatsc;
810835 int pm_referenced = 0;
811836
812
- /**
813
- * check if lapic timer has already been calibrated by platform
814
- * specific routine, such as tsc calibration code. if so, we just fill
837
+ if (boot_cpu_has(X86_FEATURE_TSC_DEADLINE_TIMER))
838
+ return 0;
839
+
840
+ /*
841
+ * Check if lapic timer has already been calibrated by platform
842
+ * specific routine, such as tsc calibration code. If so just fill
815843 * in the clockevent structure and return.
816844 */
817
-
818
- if (boot_cpu_has(X86_FEATURE_TSC_DEADLINE_TIMER)) {
819
- return 0;
820
- } else if (lapic_timer_frequency) {
845
+ if (!lapic_init_clockevent()) {
821846 apic_printk(APIC_VERBOSE, "lapic timer already calibrated %d\n",
822
- lapic_timer_frequency);
823
- lapic_clockevent.mult = div_sc(lapic_timer_frequency/APIC_DIVISOR,
824
- TICK_NSEC, lapic_clockevent.shift);
825
- lapic_clockevent.max_delta_ns =
826
- clockevent_delta2ns(0x7FFFFF, &lapic_clockevent);
827
- lapic_clockevent.max_delta_ticks = 0x7FFFFF;
828
- lapic_clockevent.min_delta_ns =
829
- clockevent_delta2ns(0xF, &lapic_clockevent);
830
- lapic_clockevent.min_delta_ticks = 0xF;
847
+ lapic_timer_period);
848
+ /*
849
+ * Direct calibration methods must have an always running
850
+ * local APIC timer, no need for broadcast timer.
851
+ */
831852 lapic_clockevent.features &= ~CLOCK_EVT_FEAT_DUMMY;
832853 return 0;
833854 }
....@@ -904,22 +925,13 @@
904925 pm_referenced = !calibrate_by_pmtimer(lapic_cal_pm2 - lapic_cal_pm1,
905926 &delta, &deltatsc);
906927
907
- /* Calculate the scaled math multiplication factor */
908
- lapic_clockevent.mult = div_sc(delta, TICK_NSEC * LAPIC_CAL_LOOPS,
909
- lapic_clockevent.shift);
910
- lapic_clockevent.max_delta_ns =
911
- clockevent_delta2ns(0x7FFFFFFF, &lapic_clockevent);
912
- lapic_clockevent.max_delta_ticks = 0x7FFFFFFF;
913
- lapic_clockevent.min_delta_ns =
914
- clockevent_delta2ns(0xF, &lapic_clockevent);
915
- lapic_clockevent.min_delta_ticks = 0xF;
916
-
917
- lapic_timer_frequency = (delta * APIC_DIVISOR) / LAPIC_CAL_LOOPS;
928
+ lapic_timer_period = (delta * APIC_DIVISOR) / LAPIC_CAL_LOOPS;
929
+ lapic_init_clockevent();
918930
919931 apic_printk(APIC_VERBOSE, "..... delta %ld\n", delta);
920932 apic_printk(APIC_VERBOSE, "..... mult: %u\n", lapic_clockevent.mult);
921933 apic_printk(APIC_VERBOSE, "..... calibration result: %u\n",
922
- lapic_timer_frequency);
934
+ lapic_timer_period);
923935
924936 if (boot_cpu_has(X86_FEATURE_TSC)) {
925937 apic_printk(APIC_VERBOSE, "..... CPU clock speed is "
....@@ -930,15 +942,15 @@
930942
931943 apic_printk(APIC_VERBOSE, "..... host bus clock speed is "
932944 "%u.%04u MHz.\n",
933
- lapic_timer_frequency / (1000000 / HZ),
934
- lapic_timer_frequency % (1000000 / HZ));
945
+ lapic_timer_period / (1000000 / HZ),
946
+ lapic_timer_period % (1000000 / HZ));
935947
936948 /*
937949 * Do a sanity check on the APIC calibration result
938950 */
939
- if (lapic_timer_frequency < (1000000 / HZ)) {
951
+ if (lapic_timer_period < (1000000 / HZ)) {
940952 local_irq_enable();
941
- pr_warning("APIC frequency too slow, disabling apic timer\n");
953
+ pr_warn("APIC frequency too slow, disabling apic timer\n");
942954 return -1;
943955 }
944956
....@@ -982,7 +994,7 @@
982994 local_irq_enable();
983995
984996 if (levt->features & CLOCK_EVT_FEAT_DUMMY) {
985
- pr_warning("APIC timer disabled due to verification failure\n");
997
+ pr_warn("APIC timer disabled due to verification failure\n");
986998 return -1;
987999 }
9881000
....@@ -1056,8 +1068,8 @@
10561068 * spurious.
10571069 */
10581070 if (!evt->event_handler) {
1059
- pr_warning("Spurious LAPIC timer interrupt on cpu %d\n",
1060
- smp_processor_id());
1071
+ pr_warn("Spurious LAPIC timer interrupt on cpu %d\n",
1072
+ smp_processor_id());
10611073 /* Switch it off */
10621074 lapic_timer_shutdown(evt);
10631075 return;
....@@ -1079,23 +1091,14 @@
10791091 * [ if a single-CPU system runs an SMP kernel then we call the local
10801092 * interrupt as well. Thus we cannot inline the local irq ... ]
10811093 */
1082
-__visible void __irq_entry smp_apic_timer_interrupt(struct pt_regs *regs)
1094
+DEFINE_IDTENTRY_SYSVEC(sysvec_apic_timer_interrupt)
10831095 {
10841096 struct pt_regs *old_regs = set_irq_regs(regs);
10851097
1086
- /*
1087
- * NOTE! We'd better ACK the irq immediately,
1088
- * because timer handling can be slow.
1089
- *
1090
- * update_process_times() expects us to have done irq_enter().
1091
- * Besides, if we don't timer interrupts ignore the global
1092
- * interrupt lock, which is the WrongThing (tm) to do.
1093
- */
1094
- entering_ack_irq();
1098
+ ack_APIC_irq();
10951099 trace_local_timer_entry(LOCAL_TIMER_VECTOR);
10961100 local_apic_timer_interrupt();
10971101 trace_local_timer_exit(LOCAL_TIMER_VECTOR);
1098
- exiting_irq();
10991102
11001103 set_irq_regs(old_regs);
11011104 }
....@@ -1185,25 +1188,38 @@
11851188 }
11861189
11871190 /**
1191
+ * apic_soft_disable - Clears and software disables the local APIC on hotplug
1192
+ *
1193
+ * Contrary to disable_local_APIC() this does not touch the enable bit in
1194
+ * MSR_IA32_APICBASE. Clearing that bit on systems based on the 3 wire APIC
1195
+ * bus would require a hardware reset as the APIC would lose track of bus
1196
+ * arbitration. On systems with FSB delivery APICBASE could be disabled,
1197
+ * but it has to be guaranteed that no interrupt is sent to the APIC while
1198
+ * in that state and it's not clear from the SDM whether it still responds
1199
+ * to INIT/SIPI messages. Stay on the safe side and use software disable.
1200
+ */
1201
+void apic_soft_disable(void)
1202
+{
1203
+ u32 value;
1204
+
1205
+ clear_local_APIC();
1206
+
1207
+ /* Soft disable APIC (implies clearing of registers for 82489DX!). */
1208
+ value = apic_read(APIC_SPIV);
1209
+ value &= ~APIC_SPIV_APIC_ENABLED;
1210
+ apic_write(APIC_SPIV, value);
1211
+}
1212
+
1213
+/**
11881214 * disable_local_APIC - clear and disable the local APIC
11891215 */
11901216 void disable_local_APIC(void)
11911217 {
1192
- unsigned int value;
1193
-
11941218 /* APIC hasn't been mapped yet */
11951219 if (!x2apic_mode && !apic_phys)
11961220 return;
11971221
1198
- clear_local_APIC();
1199
-
1200
- /*
1201
- * Disable APIC (implies clearing of registers
1202
- * for 82489DX!).
1203
- */
1204
- value = apic_read(APIC_SPIV);
1205
- value &= ~APIC_SPIV_APIC_ENABLED;
1206
- apic_write(APIC_SPIV, value);
1222
+ apic_soft_disable();
12071223
12081224 #ifdef CONFIG_X86_32
12091225 /*
....@@ -1268,9 +1284,9 @@
12681284 APIC_INT_LEVELTRIG | APIC_DM_INIT);
12691285 }
12701286
1271
-enum apic_intr_mode_id apic_intr_mode;
1287
+enum apic_intr_mode_id apic_intr_mode __ro_after_init;
12721288
1273
-static int __init apic_intr_mode_select(void)
1289
+static int __init __apic_intr_mode_select(void)
12741290 {
12751291 /* Check kernel option */
12761292 if (disable_apic) {
....@@ -1332,6 +1348,12 @@
13321348 return APIC_SYMMETRIC_IO;
13331349 }
13341350
1351
+/* Select the interrupt delivery mode for the BSP */
1352
+void __init apic_intr_mode_select(void)
1353
+{
1354
+ apic_intr_mode = __apic_intr_mode_select();
1355
+}
1356
+
13351357 /*
13361358 * An initial setup of the virtual wire mode.
13371359 */
....@@ -1381,12 +1403,12 @@
13811403 apic_write(APIC_LVT1, value);
13821404 }
13831405
1406
+static void __init apic_bsp_setup(bool upmode);
1407
+
13841408 /* Init the interrupt delivery mode for the BSP */
13851409 void __init apic_intr_mode_init(void)
13861410 {
13871411 bool upmode = IS_ENABLED(CONFIG_UP_LATE_INIT);
1388
-
1389
- apic_intr_mode = apic_intr_mode_select();
13901412
13911413 switch (apic_intr_mode) {
13921414 case APIC_PIC:
....@@ -1409,6 +1431,9 @@
14091431 pr_info("APIC: Switch to symmetric I/O mode setup in no SMP routine\n");
14101432 break;
14111433 }
1434
+
1435
+ if (x86_platform.apic_post_init)
1436
+ x86_platform.apic_post_init();
14121437
14131438 apic_bsp_setup(upmode);
14141439 }
....@@ -1533,7 +1558,6 @@
15331558 int cpu = smp_processor_id();
15341559 unsigned int value;
15351560
1536
-
15371561 if (disable_apic) {
15381562 disable_ioapic_support();
15391563 return;
....@@ -1556,8 +1580,6 @@
15561580 apic_write(APIC_ESR, 0);
15571581 }
15581582 #endif
1559
- perf_events_lapic_init();
1560
-
15611583 /*
15621584 * Double-check whether this APIC is really registered.
15631585 * This is meaningless in clustered apic mode, so we skip it.
....@@ -1590,11 +1612,14 @@
15901612 #endif
15911613
15921614 /*
1593
- * Set Task Priority to 'accept all'. We never change this
1594
- * later on.
1615
+ * Set Task Priority to 'accept all except vectors 0-31'. An APIC
1616
+ * vector in the 16-31 range could be delivered if TPR == 0, but we
1617
+ * would think it's an exception and terrible things will happen. We
1618
+ * never change this later on.
15951619 */
15961620 value = apic_read(APIC_TASKPRI);
15971621 value &= ~APIC_TPRI_MASK;
1622
+ value |= 0x10;
15981623 apic_write(APIC_TASKPRI, value);
15991624
16001625 /* Clear eventually stale ISR/IRR bits */
....@@ -1643,6 +1668,8 @@
16431668 */
16441669 value |= SPURIOUS_APIC_VECTOR;
16451670 apic_write(APIC_SPIV, value);
1671
+
1672
+ perf_events_lapic_init();
16461673
16471674 /*
16481675 * Set up LVT0, LVT1:
....@@ -1755,11 +1782,11 @@
17551782 int apicid = native_apic_msr_read(APIC_ID);
17561783
17571784 if (apicid >= 255) {
1758
- pr_warning("Apicid: %08x, cannot enforce nox2apic\n",
1759
- apicid);
1785
+ pr_warn("Apicid: %08x, cannot enforce nox2apic\n",
1786
+ apicid);
17601787 return 0;
17611788 }
1762
- pr_warning("x2apic already enabled.\n");
1789
+ pr_warn("x2apic already enabled.\n");
17631790 __x2apic_disable();
17641791 }
17651792 setup_clear_cpu_cap(X86_FEATURE_X2APIC);
....@@ -1929,7 +1956,7 @@
19291956 */
19301957 features = cpuid_edx(1);
19311958 if (!(features & (1 << X86_FEATURE_APIC))) {
1932
- pr_warning("Could not enable APIC!\n");
1959
+ pr_warn("Could not enable APIC!\n");
19331960 return -1;
19341961 }
19351962 set_cpu_cap(&boot_cpu_data, X86_FEATURE_APIC);
....@@ -1986,6 +2013,8 @@
19862013 (boot_cpu_data.x86 >= 15))
19872014 break;
19882015 goto no_apic;
2016
+ case X86_VENDOR_HYGON:
2017
+ break;
19892018 case X86_VENDOR_INTEL:
19902019 if (boot_cpu_data.x86 == 6 || boot_cpu_data.x86 == 15 ||
19912020 (boot_cpu_data.x86 == 5 && boot_cpu_has(X86_FEATURE_APIC)))
....@@ -2090,15 +2119,21 @@
20902119 * Local APIC interrupts
20912120 */
20922121
2093
-/*
2094
- * This interrupt should _never_ happen with our APIC/SMP architecture
2122
+/**
2123
+ * spurious_interrupt - Catch all for interrupts raised on unused vectors
2124
+ * @regs: Pointer to pt_regs on stack
2125
+ * @vector: The vector number
2126
+ *
2127
+ * This is invoked from ASM entry code to catch all interrupts which
2128
+ * trigger on an entry which is routed to the common_spurious idtentry
2129
+ * point.
2130
+ *
2131
+ * Also called from sysvec_spurious_apic_interrupt().
20952132 */
2096
-__visible void __irq_entry smp_spurious_interrupt(struct pt_regs *regs)
2133
+DEFINE_IDTENTRY_IRQ(spurious_interrupt)
20972134 {
2098
- u8 vector = ~regs->orig_ax;
20992135 u32 v;
21002136
2101
- entering_irq();
21022137 trace_spurious_apic_entry(vector);
21032138
21042139 inc_irq_stat(irq_spurious_count);
....@@ -2128,13 +2163,17 @@
21282163 }
21292164 out:
21302165 trace_spurious_apic_exit(vector);
2131
- exiting_irq();
2166
+}
2167
+
2168
+DEFINE_IDTENTRY_SYSVEC(sysvec_spurious_apic_interrupt)
2169
+{
2170
+ __spurious_interrupt(regs, SPURIOUS_APIC_VECTOR);
21322171 }
21332172
21342173 /*
21352174 * This interrupt should never happen with our APIC/SMP architecture
21362175 */
2137
-__visible void __irq_entry smp_error_interrupt(struct pt_regs *regs)
2176
+DEFINE_IDTENTRY_SYSVEC(sysvec_error_interrupt)
21382177 {
21392178 static const char * const error_interrupt_reason[] = {
21402179 "Send CS error", /* APIC Error Bit 0 */
....@@ -2148,7 +2187,6 @@
21482187 };
21492188 u32 v, i = 0;
21502189
2151
- entering_irq();
21522190 trace_error_apic_entry(ERROR_APIC_VECTOR);
21532191
21542192 /* First tickle the hardware, only then report what went on. -- REW */
....@@ -2172,7 +2210,6 @@
21722210 apic_printk(APIC_DEBUG, KERN_CONT "\n");
21732211
21742212 trace_error_apic_exit(ERROR_APIC_VECTOR);
2175
- exiting_irq();
21762213 }
21772214
21782215 /**
....@@ -2287,7 +2324,7 @@
22872324 #ifdef CONFIG_SMP
22882325 /**
22892326 * apic_id_is_primary_thread - Check whether APIC ID belongs to a primary thread
2290
- * @id: APIC ID to check
2327
+ * @apicid: APIC ID to check
22912328 */
22922329 bool apic_id_is_primary_thread(unsigned int apicid)
22932330 {
....@@ -2360,9 +2397,8 @@
23602397 disabled_cpu_apicid == apicid) {
23612398 int thiscpu = num_processors + disabled_cpus;
23622399
2363
- pr_warning("APIC: Disabling requested cpu."
2364
- " Processor %d/0x%x ignored.\n",
2365
- thiscpu, apicid);
2400
+ pr_warn("APIC: Disabling requested cpu."
2401
+ " Processor %d/0x%x ignored.\n", thiscpu, apicid);
23662402
23672403 disabled_cpus++;
23682404 return -ENODEV;
....@@ -2376,8 +2412,7 @@
23762412 apicid != boot_cpu_physical_apicid) {
23772413 int thiscpu = max + disabled_cpus - 1;
23782414
2379
- pr_warning(
2380
- "APIC: NR_CPUS/possible_cpus limit of %i almost"
2415
+ pr_warn("APIC: NR_CPUS/possible_cpus limit of %i almost"
23812416 " reached. Keeping one slot for boot cpu."
23822417 " Processor %d/0x%x ignored.\n", max, thiscpu, apicid);
23832418
....@@ -2388,9 +2423,8 @@
23882423 if (num_processors >= nr_cpu_ids) {
23892424 int thiscpu = max + disabled_cpus;
23902425
2391
- pr_warning("APIC: NR_CPUS/possible_cpus limit of %i "
2392
- "reached. Processor %d/0x%x ignored.\n",
2393
- max, thiscpu, apicid);
2426
+ pr_warn("APIC: NR_CPUS/possible_cpus limit of %i reached. "
2427
+ "Processor %d/0x%x ignored.\n", max, thiscpu, apicid);
23942428
23952429 disabled_cpus++;
23962430 return -EINVAL;
....@@ -2420,13 +2454,13 @@
24202454 * Validate version
24212455 */
24222456 if (version == 0x0) {
2423
- pr_warning("BIOS bug: APIC version is 0 for CPU %d/0x%x, fixing up to 0x10\n",
2424
- cpu, apicid);
2457
+ pr_warn("BIOS bug: APIC version is 0 for CPU %d/0x%x, fixing up to 0x10\n",
2458
+ cpu, apicid);
24252459 version = 0x10;
24262460 }
24272461
24282462 if (version != boot_cpu_apic_version) {
2429
- pr_warning("BIOS bug: APIC version mismatch, boot CPU: %x, CPU %d: version %x\n",
2463
+ pr_warn("BIOS bug: APIC version mismatch, boot CPU: %x, CPU %d: version %x\n",
24302464 boot_cpu_apic_version, cpu, version);
24312465 }
24322466
....@@ -2492,11 +2526,8 @@
24922526 /**
24932527 * apic_bsp_setup - Setup function for local apic and io-apic
24942528 * @upmode: Force UP mode (for APIC_init_uniprocessor)
2495
- *
2496
- * Returns:
2497
- * apic_id of BSP APIC
24982529 */
2499
-void __init apic_bsp_setup(bool upmode)
2530
+static void __init apic_bsp_setup(bool upmode)
25002531 {
25012532 connect_bsp_APIC();
25022533 if (upmode)
....@@ -2583,6 +2614,13 @@
25832614 #endif
25842615
25852616 local_irq_save(flags);
2617
+
2618
+ /*
2619
+ * Mask IOAPIC before disabling the local APIC to prevent stale IRR
2620
+ * entries on some implementations.
2621
+ */
2622
+ mask_ioapic_entries();
2623
+
25862624 disable_local_APIC();
25872625
25882626 irq_remapping_disable();
....@@ -2799,7 +2837,7 @@
27992837 apic_verbosity = APIC_VERBOSE;
28002838 #ifdef CONFIG_X86_64
28012839 else {
2802
- pr_warning("APIC Verbosity level %s not recognised"
2840
+ pr_warn("APIC Verbosity level %s not recognised"
28032841 " use apic=verbose or apic=debug\n", arg);
28042842 return -EINVAL;
28052843 }