@@ -1318,8 +1318,7 @@ static int __init __apic_intr_mode_select(void)
1318
1318
if (!boot_cpu_has (X86_FEATURE_APIC ) &&
1319
1319
APIC_INTEGRATED (boot_cpu_apic_version )) {
1320
1320
apic_is_disabled = true;
1321
- pr_err (FW_BUG "Local APIC %d not detected, force emulation\n" ,
1322
- boot_cpu_physical_apicid );
1321
+ pr_err (FW_BUG "Local APIC not detected, force emulation\n" );
1323
1322
return APIC_PIC ;
1324
1323
}
1325
1324
#endif
@@ -1340,12 +1339,6 @@ static int __init __apic_intr_mode_select(void)
1340
1339
pr_info ("APIC: SMP mode deactivated\n" );
1341
1340
return APIC_SYMMETRIC_IO_NO_ROUTING ;
1342
1341
}
1343
-
1344
- if (read_apic_id () != boot_cpu_physical_apicid ) {
1345
- panic ("Boot APIC ID in local APIC unexpected (%d vs %d)" ,
1346
- read_apic_id (), boot_cpu_physical_apicid );
1347
- /* Or can we switch back to PIC here? */
1348
- }
1349
1342
#endif
1350
1343
1351
1344
return APIC_SYMMETRIC_IO ;
@@ -1741,6 +1734,23 @@ void apic_ap_setup(void)
1741
1734
end_local_APIC_setup ();
1742
1735
}
1743
1736
1737
+ static __init void apic_read_boot_cpu_id (bool x2apic )
1738
+ {
1739
+ /*
1740
+ * This can be invoked from check_x2apic() before the APIC has been
1741
+ * selected. But that code knows for sure that the BIOS enabled
1742
+ * X2APIC.
1743
+ */
1744
+ if (x2apic ) {
1745
+ boot_cpu_physical_apicid = native_apic_msr_read (APIC_ID );
1746
+ boot_cpu_apic_version = GET_APIC_VERSION (native_apic_msr_read (APIC_LVR ));
1747
+ } else {
1748
+ boot_cpu_physical_apicid = read_apic_id ();
1749
+ boot_cpu_apic_version = GET_APIC_VERSION (apic_read (APIC_LVR ));
1750
+ }
1751
+ }
1752
+
1753
+
1744
1754
#ifdef CONFIG_X86_X2APIC
1745
1755
int x2apic_mode ;
1746
1756
EXPORT_SYMBOL_GPL (x2apic_mode );
@@ -1921,6 +1931,7 @@ void __init check_x2apic(void)
1921
1931
x2apic_state = X2APIC_ON_LOCKED ;
1922
1932
else
1923
1933
x2apic_state = X2APIC_ON ;
1934
+ apic_read_boot_cpu_id (true);
1924
1935
} else if (!boot_cpu_has (X86_FEATURE_X2APIC )) {
1925
1936
x2apic_state = X2APIC_DISABLED ;
1926
1937
}
@@ -2109,15 +2120,11 @@ static int __init detect_init_APIC(void)
2109
2120
*/
2110
2121
void __init init_apic_mappings (void )
2111
2122
{
2112
- unsigned int new_apicid ;
2113
-
2114
2123
if (apic_validate_deadline_timer ())
2115
2124
pr_info ("TSC deadline timer available\n" );
2116
2125
2117
- if (x2apic_mode ) {
2118
- boot_cpu_physical_apicid = read_apic_id ();
2126
+ if (x2apic_mode )
2119
2127
return ;
2120
- }
2121
2128
2122
2129
/* If no local APIC can be found return early */
2123
2130
if (!smp_found_config && detect_init_APIC ()) {
@@ -2134,39 +2141,19 @@ void __init init_apic_mappings(void)
2134
2141
if (!acpi_lapic && !smp_found_config )
2135
2142
register_lapic_address (apic_phys );
2136
2143
}
2137
-
2138
- /*
2139
- * Fetch the APIC ID of the BSP in case we have a
2140
- * default configuration (or the MP table is broken).
2141
- */
2142
- new_apicid = read_apic_id ();
2143
- if (boot_cpu_physical_apicid != new_apicid ) {
2144
- boot_cpu_physical_apicid = new_apicid ;
2145
- /*
2146
- * yeah -- we lie about apic_version
2147
- * in case if apic was disabled via boot option
2148
- * but it's not a problem for SMP compiled kernel
2149
- * since apic_intr_mode_select is prepared for such
2150
- * a case and disable smp mode
2151
- */
2152
- boot_cpu_apic_version = GET_APIC_VERSION (apic_read (APIC_LVR ));
2153
- }
2154
2144
}
2155
2145
2156
2146
void __init register_lapic_address (unsigned long address )
2157
2147
{
2158
2148
mp_lapic_addr = address ;
2159
2149
2160
- if (!x2apic_mode ) {
2161
- set_fixmap_nocache (FIX_APIC_BASE , address );
2162
- apic_mmio_base = APIC_BASE ;
2163
- apic_printk (APIC_VERBOSE , "mapped APIC to %16lx (%16lx)\n" ,
2164
- APIC_BASE , address );
2165
- }
2166
- if (boot_cpu_physical_apicid == -1U ) {
2167
- boot_cpu_physical_apicid = read_apic_id ();
2168
- boot_cpu_apic_version = GET_APIC_VERSION (apic_read (APIC_LVR ));
2169
- }
2150
+ if (x2apic_mode )
2151
+ return ;
2152
+
2153
+ set_fixmap_nocache (FIX_APIC_BASE , address );
2154
+ apic_mmio_base = APIC_BASE ;
2155
+ apic_printk (APIC_VERBOSE , "mapped APIC to %16lx (%16lx)\n" , APIC_BASE , address );
2156
+ apic_read_boot_cpu_id (false);
2170
2157
}
2171
2158
2172
2159
/*
@@ -2446,31 +2433,15 @@ int generic_processor_info(int apicid, int version)
2446
2433
phys_cpu_present_map );
2447
2434
2448
2435
/*
2449
- * boot_cpu_physical_apicid is designed to have the apicid
2450
- * returned by read_apic_id(), i.e, the apicid of the
2451
- * currently booting-up processor. However, on some platforms,
2452
- * it is temporarily modified by the apicid reported as BSP
2453
- * through MP table. Concretely:
2454
- *
2455
- * - arch/x86/kernel/mpparse.c: MP_processor_info()
2456
- * - arch/x86/mm/amdtopology.c: amd_numa_init()
2457
- *
2458
- * This function is executed with the modified
2459
- * boot_cpu_physical_apicid. So, disabled_cpu_apicid kernel
2460
- * parameter doesn't work to disable APs on kdump 2nd kernel.
2461
- *
2462
- * Since fixing handling of boot_cpu_physical_apicid requires
2463
- * another discussion and tests on each platform, we leave it
2464
- * for now and here we use read_apic_id() directly in this
2465
- * function, generic_processor_info().
2436
+ * boot_cpu_physical_apicid is guaranteed to contain the boot CPU
2437
+ * APIC ID read from the local APIC when this function is invoked.
2466
2438
*/
2467
- if (disabled_cpu_apicid != BAD_APICID &&
2468
- disabled_cpu_apicid != read_apic_id () &&
2439
+ if (disabled_cpu_apicid != boot_cpu_physical_apicid &&
2469
2440
disabled_cpu_apicid == apicid ) {
2470
2441
int thiscpu = num_processors + disabled_cpus ;
2471
2442
2472
- pr_warn ("APIC: Disabling requested cpu."
2473
- " Processor %d/0x%x ignored.\n" , thiscpu , apicid );
2443
+ pr_warn ("APIC: Disabling requested cpu. Processor %d/0x%x ignored.\n" ,
2444
+ thiscpu , apicid );
2474
2445
2475
2446
disabled_cpus ++ ;
2476
2447
return - ENODEV ;
@@ -2626,15 +2597,6 @@ static void __init apic_bsp_up_setup(void)
2626
2597
{
2627
2598
#ifdef CONFIG_X86_64
2628
2599
apic_write (APIC_ID , apic -> set_apic_id (boot_cpu_physical_apicid ));
2629
- #else
2630
- /*
2631
- * Hack: In case of kdump, after a crash, kernel might be booting
2632
- * on a cpu with non-zero lapic id. But boot_cpu_physical_apicid
2633
- * might be zero if read from MP tables. Get it from LAPIC.
2634
- */
2635
- # ifdef CONFIG_CRASH_DUMP
2636
- boot_cpu_physical_apicid = read_apic_id ();
2637
- # endif
2638
2600
#endif
2639
2601
physid_set_mask_of_physid (boot_cpu_physical_apicid , & phys_cpu_present_map );
2640
2602
}
0 commit comments