Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > fc11cd6e1c513a17304da94a5390f3cd > files > 3924

kernel-2.6.18-194.11.1.el5.src.rpm

From: Bhavna Sarathy <bnagendr@redhat.com>
Date: Mon, 9 Nov 2009 20:48:26 -0500
Subject: [x86] fix boot crash with < 8-core AMD Magny-cours system
Message-id: <4AF8801A.8020508@redhat.com>
Patchwork-id: 21336
O-Subject: Re: [RHEL5.5 PATCH] Fix boot crash with < 8-core Magny-cours system
Bugzilla: 522215
RH-Acked-by: Prarit Bhargava <prarit@redhat.com>
RH-Acked-by: Christopher Lalancette <clalance@redhat.com>

BZ 522215

Detect use of extended APIC ID for AMD CPUs, and prevent kernel panic while booting
an 8-core Magny-cours on 32-bit RHEL5.x.

The reason is this:
- the kernel cannot switch to "bigsmp" APIC driver mode, because in RH5.4 x86
that mode is used only if num_processors > 8. - so the kernel uses
"0x0F" as the mask to get the APIC ID of the BSP.
Therefore, if the  BSP APIC ID happens to be 16, the kernel will incorrectly
assign boot_cpu_physical_apicid to 0. Later, in the same smp_boot_cpus()
function, the kernel will attempt to wake the boot CPU (which is already up and
running), and "hang"

Upstream links:
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=42937e81a82

commit 2cb078603abb612e3bcd428fb8122c3d39e08832

Brew build:
http://brewweb.devel.redhat.com/brew/taskinfo?taskID=1993083

Testing:
Patch tested on 2P Dinar system and HP Proliant G7 M-C system.

diff --git a/arch/i386/kernel/cpu/amd.c b/arch/i386/kernel/cpu/amd.c
index 58f5e41..522c1a0 100644
--- a/arch/i386/kernel/cpu/amd.c
+++ b/arch/i386/kernel/cpu/amd.c
@@ -105,6 +105,15 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
 	}
 #endif
 
+#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_PCI)
+	/* check CPU config space for extended APIC ID */
+	if (cpu_has_apic && c->x86 >= 0xf) {
+		unsigned int val;
+		val = read_pci_config(0, 24, 0, 0x68);
+		if ((val & ((1 << 17) | (1 << 18))) == ((1 << 17) | (1 << 18)))
+			set_bit(X86_FEATURE_EXTD_APICID, c->x86_capability);
+	}
+#endif
 	/*
 	 *	FIXME: We should handle the K5 here. Set up the write
 	 *	range and also turn on MSR 83 bits 4 and 31 (write alloc,
diff --git a/include/asm-i386/cpufeature.h b/include/asm-i386/cpufeature.h
index 633cc2d..4a305ef 100644
--- a/include/asm-i386/cpufeature.h
+++ b/include/asm-i386/cpufeature.h
@@ -79,6 +79,7 @@
 #define X86_FEATURE_TSC_RELIABLE (3*32+23) /* TSC is known to be reliable */
 #define X86_FEATURE_NONSTOP_TSC (3*32+24) /* TSC does not stop in C states */
 #define X86_FEATURE_ARAT	(3*32+25) /* Always Running APIC Timer */
+#define X86_FEATURE_EXTD_APICID	(3*32+26) /* has extended APICID (8 bits) */
 #define X86_FEATURE_AMD_DCM	(3*32+27) /* multi-node processor */
 
 /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
diff --git a/include/asm-i386/mach-default/mach_apicdef.h b/include/asm-i386/mach-default/mach_apicdef.h
index ae98413..c0f4a4a 100644
--- a/include/asm-i386/mach-default/mach_apicdef.h
+++ b/include/asm-i386/mach-default/mach_apicdef.h
@@ -8,7 +8,7 @@
 static inline unsigned get_apic_id(unsigned long x) 
 { 
 	unsigned int ver = GET_APIC_VERSION(apic_read(APIC_LVR));
-	if (APIC_XAPIC(ver))
+	if (APIC_XAPIC(ver) || boot_cpu_has(X86_FEATURE_EXTD_APICID))
 		return (((x)>>24)&0xFF);
 	else
 		return (((x)>>24)&0xF);