Commit b58f2e6f authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] cpu_sibling_map fix

From: "Nakajima, Jun" <jun.nakajima@intel.com>

Restore the HT detection algorithm.  Make the processor package mapping
subarch-specific so that it can reflect the APIC ID info provided by BIOS
if required.
parent a5ab05a5
#include <linux/config.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/bitops.h>
#include <linux/smp.h>
......@@ -11,6 +13,12 @@
#include "cpu.h"
#ifdef CONFIG_X86_LOCAL_APIC
#include <asm/mpspec.h>
#include <asm/apic.h>
#include <mach_apic.h>
#endif
extern int trap_init_f00f_bug(void);
#ifdef CONFIG_X86_INTEL_USERCOPY
......@@ -277,6 +285,7 @@ static void __init init_intel(struct cpuinfo_x86 *c)
extern int phys_proc_id[NR_CPUS];
u32 eax, ebx, ecx, edx;
int index_lsb, index_msb, tmp;
int cpu = smp_processor_id();
cpuid(1, &eax, &ebx, &ecx, &edx);
......@@ -285,6 +294,8 @@ static void __init init_intel(struct cpuinfo_x86 *c)
if (smp_num_siblings == 1) {
printk(KERN_INFO "CPU: Hyper-Threading is disabled\n");
} else if (smp_num_siblings > 1 ) {
index_lsb = 0;
index_msb = 31;
/*
* At this point we only support two siblings per
* processor package.
......@@ -295,13 +306,19 @@ static void __init init_intel(struct cpuinfo_x86 *c)
smp_num_siblings = 1;
goto too_many_siblings;
}
/* cpuid returns the value latched in the HW at reset,
* not the APIC ID register's value. For any box
* whose BIOS changes APIC IDs, like clustered APIC
* systems, we must use hard_smp_processor_id.
* See Intel's IA-32 SW Dev's Manual Vol2 under CPUID.
*/
phys_proc_id[cpu] = hard_smp_processor_id() & ~(smp_num_siblings - 1);
tmp = smp_num_siblings;
while ((tmp & 1) == 0) {
tmp >>=1 ;
index_lsb++;
}
tmp = smp_num_siblings;
while ((tmp & 0x80000000 ) == 0) {
tmp <<=1 ;
index_msb--;
}
if (index_lsb != index_msb )
index_msb++;
phys_proc_id[cpu] = phys_pkg_id((ebx >> 24) & 0xFF, index_msb);
printk(KERN_INFO "CPU: Physical Processor ID: %d\n",
phys_proc_id[cpu]);
......
......@@ -45,6 +45,7 @@ struct genapic {
void (*setup_portio_remap)(void);
int (*check_phys_apicid_present)(int boot_cpu_physical_apicid);
void (*enable_apic_mode)(void);
u32 (*phys_pkg_id)(u32 cpuid_apic, int index_msb);
/* mpparse */
void (*mpc_oem_bus_info)(struct mpc_config_bus *, char *,
......@@ -105,6 +106,7 @@ struct genapic {
APICFUNC(send_IPI_allbutself), \
APICFUNC(send_IPI_all), \
APICFUNC(enable_apic_mode), \
APICFUNC(phys_pkg_id), \
}
extern struct genapic *genapic;
......
......@@ -173,4 +173,9 @@ static inline unsigned int cpu_mask_to_apicid(cpumask_const_t cpumask)
return apicid;
}
static inline u32 phys_pkg_id(u32 cpuid_apic, int index_msb)
{
return cpuid_apic >> index_msb;
}
#endif /* __ASM_MACH_APIC_H */
......@@ -127,4 +127,9 @@ static inline void enable_apic_mode(void)
{
}
static inline u32 phys_pkg_id(u32 cpuid_apic, int index_msb)
{
return cpuid_apic >> index_msb;
}
#endif /* __ASM_MACH_APIC_H */
......@@ -192,4 +192,9 @@ static inline unsigned int cpu_mask_to_apicid(cpumask_const_t cpumask)
return apicid;
}
static inline u32 phys_pkg_id(u32 cpuid_apic, int index_msb)
{
return cpuid_apic >> index_msb;
}
#endif /* __ASM_MACH_APIC_H */
......@@ -27,5 +27,6 @@
#define check_apicid_used (genapic->check_apicid_used)
#define cpu_mask_to_apicid (genapic->cpu_mask_to_apicid)
#define enable_apic_mode (genapic->enable_apic_mode)
#define phys_pkg_id (genapic->phys_pkg_id)
#endif /* __ASM_MACH_APIC_H */
......@@ -141,4 +141,10 @@ static inline unsigned int cpu_mask_to_apicid(cpumask_const_t cpumask)
return (int) 0xF;
}
/* No NUMA-Q box has a HT CPU, but it can't hurt to use the default code. */
static inline u32 phys_pkg_id(u32 cpuid_apic, int index_msb)
{
return cpuid_apic >> index_msb;
}
#endif /* __ASM_MACH_APIC_H */
......@@ -173,4 +173,15 @@ static inline unsigned int cpu_mask_to_apicid(cpumask_const_t cpumask)
return apicid;
}
/* cpuid returns the value latched in the HW at reset, not the APIC ID
* register's value. For any box whose BIOS changes APIC IDs, like
* clustered APIC systems, we must use hard_smp_processor_id.
*
* See Intel's IA-32 SW Dev's Manual Vol2 under CPUID.
*/
static inline u32 phys_pkg_id(u32 cpuid_apic, int index_msb)
{
return hard_smp_processor_id() >> index_msb;
}
#endif /* __ASM_MACH_APIC_H */
......@@ -88,4 +88,10 @@ static inline unsigned int cpu_mask_to_apicid(cpumask_const_t cpumask)
{
return cpus_coerce_const(cpumask);
}
static inline u32 phys_pkg_id(u32 cpuid_apic, int index_msb)
{
return cpuid_apic >> index_msb;
}
#endif /* __ASM_MACH_APIC_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment