On 5/28/20 11:37 PM, Dexuan Cui wrote: > parse_apic() allows the user to try a different apic driver than the > default one that's automatically chosen. It works for x86_32, but > doesn't work for x86_64 becauase it was removed in 2009 for x86_64 by: > commit 7b38725318f4 ("x86: remove subarchitecture support code"), > whose changelog doesn't explicitly describe the removal for x86_64. > > The patch adds back the functionality for x86_64. The intent is mainly > to work around an APIC emulation bug in Hyper-V in the case of kdump: > currently Hyper-V does not honor the disabled state of the local APICs, > and all the IOAPIC-based interrupts may not be delivered to the correct > virtual CPU, if the logical-mode APIC driver is used (the kdump > kernel usually uses the logical-mode APIC driver, since typically > only 1 CPU is active). Luckily the kdump issue can be worked around by > forcing the kdump kernel to use physical mode, before the fix to Hyper-V > becomes widely available. > > IMHO the patch is safe because the current default algorithm to choose > the apic driver is unchanged; the patch makes a difference only when > the user specifies the apic= kernel parameter, e.g. "apic=physical flat". > > Signed-off-by: Dexuan Cui <decui@xxxxxxxxxxxxx> > --- > arch/x86/kernel/apic/apic_flat_64.c | 27 ++++++++++++++++++++++++++- > 1 file changed, 26 insertions(+), 1 deletion(-) Hi, Looks like you will also need to update Documentation/admin-guide/kernel-parameters.txt, where it says: For X86-32, this can also be used to specify an APIC driver name. > diff --git a/arch/x86/kernel/apic/apic_flat_64.c b/arch/x86/kernel/apic/apic_flat_64.c > index 7862b152a052..efbec63bb01f 100644 > --- a/arch/x86/kernel/apic/apic_flat_64.c > +++ b/arch/x86/kernel/apic/apic_flat_64.c > @@ -23,9 +23,34 @@ static struct apic apic_flat; > struct apic *apic __ro_after_init = &apic_flat; > EXPORT_SYMBOL_GPL(apic); > > +static int cmdline_apic __initdata; > +static int __init parse_apic(char *arg) > +{ > + struct apic **drv; > + > + if (!arg) > + return -EINVAL; > + > + for (drv = __apicdrivers; drv < __apicdrivers_end; drv++) { > + if (!strcmp((*drv)->name, arg)) { > + apic = *drv; > + cmdline_apic = 1; > + return 0; > + } > + } > + > + /* Parsed again by __setup for debug/verbose */ > + return 0; > +} > +early_param("apic", parse_apic); > + > + > static int flat_acpi_madt_oem_check(char *oem_id, char *oem_table_id) > { > - return 1; > + if (!cmdline_apic) > + return 1; > + > + return apic == &apic_flat; > } > > /* > -- ~Randy