Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

x86/apic: Disable x2apic on resume if the kernel expects so

When resuming from s2ram, firmware may re-enable x2apic mode, which may have
been disabled by the kernel during boot either because it doesn't support IRQ
remapping or for other reasons. This causes the kernel to continue using the
xapic interface, while the hardware is in x2apic mode, which causes hangs.
This happens on defconfig + bare metal + s2ram.

Fix this in lapic_resume() by disabling x2apic if the kernel expects it to be
disabled, i.e. when x2apic_mode = 0.

The ACPI v6.6 spec, Section 16.3 [1] says firmware restores either the
pre-sleep configuration or initial boot configuration for each CPU, including
MSR state:

When executing from the power-on reset vector as a result of waking from an
S2 or S3 sleep state, the platform firmware performs only the hardware
initialization required to restore the system to either the state the
platform was in prior to the initial operating system boot, or to the
pre-sleep configuration state. In multiprocessor systems, non-boot
processors should be placed in the same state as prior to the initial
operating system boot.

(further ahead)

If this is an S2 or S3 wake, then the platform runtime firmware restores
minimum context of the system before jumping to the waking vector. This
includes:

CPU configuration. Platform runtime firmware restores the pre-sleep
configuration or initial boot configuration of each CPU (MSR, MTRR,
firmware update, SMBase, and so on). Interrupts must be disabled (for
IA-32 processors, disabled by CLI instruction).

(and other things)

So at least as per the spec, re-enablement of x2apic by the firmware is
allowed if "x2apic on" is a part of the initial boot configuration.

[1] https://uefi.org/specs/ACPI/6.6/16_Waking_and_Sleeping.html#initialization

[ bp: Massage. ]

Fixes: 6e1cb38a2aef ("x64, x2apic/intr-remap: add x2apic support, including enabling interrupt-remapping")
Co-developed-by: Rahul Bukte <rahul.bukte@sony.com>
Signed-off-by: Rahul Bukte <rahul.bukte@sony.com>
Signed-off-by: Shashank Balaji <shashank.mahadasyam@sony.com>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Reviewed-by: Thomas Gleixner <tglx@kernel.org>
Reviewed-by: Sohil Mehta <sohil.mehta@intel.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260306-x2apic-fix-v2-1-bee99c12efa3@sony.com

authored by

Shashank Balaji and committed by
Borislav Petkov (AMD)
8cc7dd77 1f318b96

+6
+6
arch/x86/kernel/apic/apic.c
··· 1894 1894 1895 1895 static inline void try_to_enable_x2apic(int remap_mode) { } 1896 1896 static inline void __x2apic_enable(void) { } 1897 + static inline void __x2apic_disable(void) { } 1897 1898 #endif /* !CONFIG_X86_X2APIC */ 1898 1899 1899 1900 void __init enable_IR_x2apic(void) ··· 2457 2456 if (x2apic_mode) { 2458 2457 __x2apic_enable(); 2459 2458 } else { 2459 + if (x2apic_enabled()) { 2460 + pr_warn_once("x2apic: re-enabled by firmware during resume. Disabling\n"); 2461 + __x2apic_disable(); 2462 + } 2463 + 2460 2464 /* 2461 2465 * Make sure the APICBASE points to the right address 2462 2466 *