forked from TencentOS/TencentOS-kernel
x86/mpparse, kexec: switch apic driver early if x2apic is pre-enabled
Following kernel panic is observed when doing kexec/kdump on machines that use mptable, and supports x2apic: [ 0.010090] Intel MultiProcessor Specification v1.4 [ 0.010688] MPTABLE: OEM ID: BOCHSCPU [ 0.010886] MPTABLE: Product ID: 0.1 [ 0.011119] MPTABLE: APIC at: 0xFEE00000 [ 0.011332] BUG: unable to handle page fault for address: ffffffffff5fc020 [ 0.011702] #PF: supervisor read access in kernel mode [ 0.011981] #PF: error_code(0x0000) - not-present page [ 0.012256] PGD 25e15067 P4D 25e15067 PUD 25e17067 PMD 25e18067 PTE 0 [ 0.012603] Oops: 0000 [#1] SMP NOPTI [ 0.012801] CPU: 0 PID: 0 Comm: swapper Not tainted 5.14.10-300.fc35.x86_64 #1 [ 0.013189] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1.fc35 04/01/2014 [ 0.013658] RIP: 0010:native_apic_mem_read+0x2/0x10 [ 0.013924] Code: 14 25 20 cd e3 82 c3 90 bf 30 08 00 00 ff 14 25 18 cd e3 82 c3 cc cc cc 89 ff 89 b7 00 c0 5f ff c3 0f 1f 80 00 00 00 00 89 ff <8b> 87 00 c0 5f ff c3 0f 1f 80 00 00 00 0 [ 0.014930] RSP: 0000:ffffffff82e03e18 EFLAGS: 00010046 [ 0.015211] RAX: ffffffff81064840 RBX: ffffffffff240b6c RCX: ffffffff82f17428 [ 0.015593] RDX: c0000000ffffdfff RSI: 00000000ffffdfff RDI: 0000000000000020 [ 0.015977] RBP: ffff888023200000 R08: 0000000000000000 R09: ffffffff82e03c50 [ 0.016385] R10: ffffffff82e03c48 R11: ffffffff82f47468 R12: ffffffffff240b40 [ 0.016768] R13: ffffffffff200b30 R14: 0000000000000000 R15: 00000000000000d4 [ 0.017155] FS: 0000000000000000(0000) GS:ffffffff8365b000(0000) knlGS:0000000000000000 [ 0.017589] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 0.017899] CR2: ffffffffff5fc020 CR3: 0000000025e10000 CR4: 00000000000006b0 [ 0.018284] Call Trace: [ 0.018417] ? read_apic_id+0x15/0x30 [ 0.018616] ? register_lapic_address+0x76/0x97 [ 0.018864] ? default_get_smp_config+0x28b/0x42d [ 0.019119] ? dmi_check_system+0x1c/0x60 [ 0.019337] ? acpi_boot_init+0x1d/0x4c3 [ 0.019550] ? setup_arch+0xb37/0xc2a [ 0.019749] ? slab_is_available+0x5/0x10 [ 0.019969] ? start_kernel+0x61/0x980 [ 0.020173] ? load_ucode_bsp+0x4c/0xcd [ 0.020380] ? secondary_startup_64_no_verify+0xc2/0xcb [ 0.020664] Modules linked in: [ 0.020830] CR2: ffffffffff5fc020 [ 0.021012] random: get_random_bytes called from oops_exit+0x35/0x60 with crng_init=0 [ 0.021015] ---[ end trace c9e569df3bdbefd3 ]--- Checking following init order we have: setup_arch() check_x2apic() <-- x2apic is enabled by first kernel before kexec, this set x2apic_mode = 1, make sure later probes will recognize pre-enabled x2apic. .... acpi_boot_init(); <-- With ACPI MADT, this will switch apic driver to x2apic, but it will do nothing with mptable. x86_dtb_init(); get_smp_config(); default_get_smp_config(); check_physptr(); smp_read_mpc(); register_lapic_address(); <-- panic here init_apic_mappings(); .... The problem here is mpparse need to read some boot info from apic, so calls register_lapic_address() early. But without MADT, apic driver is still apic_flat, it attempts to use the MMIO interface which is never mapped since: commit 0450193bffed6 ("x86, x2apic: Don't map lapic addr for preenabled x2apic systems") Simply map it won't work either as in x2apic mode the MMIO interface is not really available (Intel SDM Volume 3A 10.12.2), later code will fail with other errors. So here we do the apic driver probe early. With pre-enabled x2apic, the probe will recognize it and switch to the right driver just fine. Such issue is currently only seen with kexec/kdump, which enabled the x2apic in first kernel and kept it enabled to 2nd kernel. This can be easily reproduced with qemu, use -no-acpi and enable x2apic. Signed-off-by: Kairui Song <kasong@tencent.com> Signed-off-by: Jianping Liu <frankjpliu@tencent.com>
This commit is contained in:
parent
83eb0d3945
commit
0f57be5819
|
|
@ -211,8 +211,16 @@ static int __init smp_read_mpc(struct mpc_table *mpc, unsigned early)
|
|||
return 0;
|
||||
|
||||
/* Initialize the lapic mapping */
|
||||
if (!acpi_lapic)
|
||||
if (!acpi_lapic) {
|
||||
/*
|
||||
* If MPS is in use with pre-enabled x2apic (eg. kexec), we need
|
||||
* to switch to the right apic driver early
|
||||
*/
|
||||
if (x2apic_mode)
|
||||
default_setup_apic_routing();
|
||||
|
||||
register_lapic_address(mpc->lapic);
|
||||
}
|
||||
|
||||
if (early)
|
||||
return 1;
|
||||
|
|
|
|||
Loading…
Reference in New Issue