[stable 3.0 v2] x86/apic: Work around boot failure on HP ProLiantDL980 G7 Server systems

From: Zhang, Lin-Bao (Linux Kernel R&D)
Date: Wed Feb 27 2013 - 06:08:48 EST

Hi Greg,

This patch is specially for 3.0 by integrating upstream commit cb214ede7657db458fd0b2a25ea0b28dbf900ebc
and ea0dcf903e7d76aa5d483d876215fedcfdfe140f .
I fixed patch format warning and re-send it as v2. Thanks .

./scripts/checkpatch.pl x2apic_FADT_check_for_3.0.66v2.patch
total: 0 errors, 0 warnings, 31 lines checked

x2apic_FADT_check_for_3.0.66v2.patch has no obvious style problems and is ready for submission.

From: Zhang Lin-Bao <linbao.zhang@xxxxxx>
x86/apic: Work around boot failure on HP ProLiant DL980 G7 Server systems

commit cb214ede7657db458fd0b2a25ea0b28dbf900ebc and ea0dcf903e7d76aa5d483d876215fedcfdfe140f upstream.

HP ProLiant DL980 G7 Server boots a regular kernel,
there will be intermittent lost interrupts which could
result in a hang or (in extreme cases) data loss.

The reason is that this system only supports x2apic physical
mode, while the kernel boots with a logical-cluster default

This bug can be worked around by specifying "x2apic_phys" or
"nox2apic" boot option, but we want to handle this system without
requiring manual workarounds.

As all apicids are less than 255, BIOS need to pass the control
to the OS with xapic mode, according to x2apic-spec, chapter 2.9.

Current code handle x2apic when BIOS pass with xapic mode:
When user specify x2apic_phys, or FADT indicates PHYSICAL.
1. During madt oem check, apic driver is set with xapic logical or
xapic phys driver at first.
2. enable_IR_x2apic() will enable x2apic_mode.
3. if user specify x2apic_phys, x2apic_phys_probe() will install
right x2apic phys driver and use x2apic phys mode.
otherwise will skip and let x2apic_cluster_probe to take over
to install x2apic cluster driver (wrong one) even FADT indicates
PHYSICAL, because x2apic_phys_probe does not check FADT PHYSICAL.

Add checking x2apic_fadt_phys in x2apic_phys_probe() to fix the problem.

Signed-off-by: Stoney Wang <song-bo.wang@xxxxxx>
[ updated the changelog and simplified the code ]
Signed-off-by: Yinghai Lu <yinghai@xxxxxxxxxx>
Signed-off-by: Linbao.zhang@xxxxxx
[ make a patch specially for 3.0.66]
Cc: stable@xxxxxxxxxx
Link: http://lkml.kernel.org/r/1360263182-16226-1-git-send-email-yinghai@xxxxxxxxxx
Signed-off-by: Ingo Molnar <mingo@xxxxxxxxxx>

arch/x86/kernel/apic/x2apic_phys.c | 17 ++++++++++++-----
1 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/arch/x86/kernel/apic/x2apic_phys.c b/arch/x86/kernel/apic/x2apic_phys.c
index f5373df..0f8cb3a 100644
--- a/arch/x86/kernel/apic/x2apic_phys.c
+++ b/arch/x86/kernel/apic/x2apic_phys.c
@@ -20,12 +20,19 @@ static int set_x2apic_phys_mode(char *arg)
early_param("x2apic_phys", set_x2apic_phys_mode);

+static bool x2apic_fadt_phys(void)
+ if ((acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID) &&
+ (acpi_gbl_FADT.flags & ACPI_FADT_APIC_PHYSICAL)) {
+ printk(KERN_DEBUG "System requires x2apic physical mode\n");
+ return true;
+ }
+ return false;
static int x2apic_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
- if (x2apic_phys)
- return x2apic_enabled();
- else
- return 0;
+ return x2apic_enabled() && (x2apic_phys || x2apic_fadt_phys());

static void
@@ -108,7 +115,7 @@ static void init_x2apic_ldr(void)

static int x2apic_phys_probe(void)
- if (x2apic_mode && x2apic_phys)
+ if (x2apic_mode && (x2apic_phys || x2apic_fadt_phys()))
return 1;

return apic == &apic_x2apic_phys;

-- Bob(LinBao Zhang)
HP linux kernel enginner
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/