The following commit has been merged into the x86/cc branch of tip: Commit-ID: db0936830a2fcc35e2b283275acf61b6d3ae1e11 Gitweb: https://git.kernel.org/tip/db0936830a2fcc35e2b283275acf61b6d3ae1e11 Author: Kirill A. Shutemov <kirill.shutemov@xxxxxxxxxxxxxxx> AuthorDate: Fri, 14 Jun 2024 12:59:00 +03:00 Committer: Borislav Petkov (AMD) <bp@xxxxxxxxx> CommitterDate: Mon, 17 Jun 2024 17:46:17 +02:00 x86/acpi: Do not attempt to bring up secondary CPUs in the kexec case ACPI MADT doesn't allow to offline a CPU after it was onlined. This limits kexec: the second kernel won't be able to use more than one CPU. To prevent a kexec kernel from onlining secondary CPUs, invalidate the mailbox address in the ACPI MADT wakeup structure which prevents a kexec kernel to use it. This is safe as the booting kernel has the mailbox address cached already and acpi_wakeup_cpu() uses the cached value to bring up the secondary CPUs. Note: This is a Linux specific convention and not covered by the ACPI specification. Signed-off-by: Kirill A. Shutemov <kirill.shutemov@xxxxxxxxxxxxxxx> Signed-off-by: Borislav Petkov (AMD) <bp@xxxxxxxxx> Reviewed-by: Kai Huang <kai.huang@xxxxxxxxx> Reviewed-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@xxxxxxxxxxxxxxx> Reviewed-by: Thomas Gleixner <tglx@xxxxxxxxxxxxx> Acked-by: Rafael J. Wysocki <rafael.j.wysocki@xxxxxxxxx> Tested-by: Tao Liu <ltao@xxxxxxxxxx> Link: https://lore.kernel.org/r/20240614095904.1345461-16-kirill.shutemov@xxxxxxxxxxxxxxx --- arch/x86/kernel/acpi/madt_wakeup.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/arch/x86/kernel/acpi/madt_wakeup.c b/arch/x86/kernel/acpi/madt_wakeup.c index 004801b..30820f9 100644 --- a/arch/x86/kernel/acpi/madt_wakeup.c +++ b/arch/x86/kernel/acpi/madt_wakeup.c @@ -14,6 +14,11 @@ static struct acpi_madt_multiproc_wakeup_mailbox *acpi_mp_wake_mailbox __ro_afte static int acpi_wakeup_cpu(u32 apicid, unsigned long start_ip) { + if (!acpi_mp_wake_mailbox_paddr) { + pr_warn_once("No MADT mailbox: cannot bringup secondary CPUs. Booting with kexec?\n"); + return -EOPNOTSUPP; + } + /* * Remap mailbox memory only for the first call to acpi_wakeup_cpu(). * @@ -64,6 +69,28 @@ static int acpi_wakeup_cpu(u32 apicid, unsigned long start_ip) return 0; } +static void acpi_mp_disable_offlining(struct acpi_madt_multiproc_wakeup *mp_wake) +{ + cpu_hotplug_disable_offlining(); + + /* + * ACPI MADT doesn't allow to offline a CPU after it was onlined. This + * limits kexec: the second kernel won't be able to use more than one CPU. + * + * To prevent a kexec kernel from onlining secondary CPUs invalidate the + * mailbox address in the ACPI MADT wakeup structure which prevents a + * kexec kernel to use it. + * + * This is safe as the booting kernel has the mailbox address cached + * already and acpi_wakeup_cpu() uses the cached value to bring up the + * secondary CPUs. + * + * Note: This is a Linux specific convention and not covered by the + * ACPI specification. + */ + mp_wake->mailbox_address = 0; +} + int __init acpi_parse_mp_wake(union acpi_subtable_headers *header, const unsigned long end) { @@ -77,7 +104,7 @@ int __init acpi_parse_mp_wake(union acpi_subtable_headers *header, acpi_mp_wake_mailbox_paddr = mp_wake->mailbox_address; - cpu_hotplug_disable_offlining(); + acpi_mp_disable_offlining(mp_wake); apic_update_callback(wakeup_secondary_cpu_64, acpi_wakeup_cpu);