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/init.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/bitops.h> #include <linux/bitops.h>
#include <linux/smp.h> #include <linux/smp.h>
...@@ -11,6 +13,12 @@ ...@@ -11,6 +13,12 @@
#include "cpu.h" #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); extern int trap_init_f00f_bug(void);
#ifdef CONFIG_X86_INTEL_USERCOPY #ifdef CONFIG_X86_INTEL_USERCOPY
...@@ -277,6 +285,7 @@ static void __init init_intel(struct cpuinfo_x86 *c) ...@@ -277,6 +285,7 @@ static void __init init_intel(struct cpuinfo_x86 *c)
extern int phys_proc_id[NR_CPUS]; extern int phys_proc_id[NR_CPUS];
u32 eax, ebx, ecx, edx; u32 eax, ebx, ecx, edx;
int index_lsb, index_msb, tmp;
int cpu = smp_processor_id(); int cpu = smp_processor_id();
cpuid(1, &eax, &ebx, &ecx, &edx); cpuid(1, &eax, &ebx, &ecx, &edx);
...@@ -285,6 +294,8 @@ static void __init init_intel(struct cpuinfo_x86 *c) ...@@ -285,6 +294,8 @@ static void __init init_intel(struct cpuinfo_x86 *c)
if (smp_num_siblings == 1) { if (smp_num_siblings == 1) {
printk(KERN_INFO "CPU: Hyper-Threading is disabled\n"); printk(KERN_INFO "CPU: Hyper-Threading is disabled\n");
} else if (smp_num_siblings > 1 ) { } else if (smp_num_siblings > 1 ) {
index_lsb = 0;
index_msb = 31;
/* /*
* At this point we only support two siblings per * At this point we only support two siblings per
* processor package. * processor package.
...@@ -295,13 +306,19 @@ static void __init init_intel(struct cpuinfo_x86 *c) ...@@ -295,13 +306,19 @@ static void __init init_intel(struct cpuinfo_x86 *c)
smp_num_siblings = 1; smp_num_siblings = 1;
goto too_many_siblings; goto too_many_siblings;
} }
/* cpuid returns the value latched in the HW at reset, tmp = smp_num_siblings;
* not the APIC ID register's value. For any box while ((tmp & 1) == 0) {
* whose BIOS changes APIC IDs, like clustered APIC tmp >>=1 ;
* systems, we must use hard_smp_processor_id. index_lsb++;
* See Intel's IA-32 SW Dev's Manual Vol2 under CPUID. }
*/ tmp = smp_num_siblings;
phys_proc_id[cpu] = hard_smp_processor_id() & ~(smp_num_siblings - 1); 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", printk(KERN_INFO "CPU: Physical Processor ID: %d\n",
phys_proc_id[cpu]); phys_proc_id[cpu]);
......
...@@ -45,6 +45,7 @@ struct genapic { ...@@ -45,6 +45,7 @@ struct genapic {
void (*setup_portio_remap)(void); void (*setup_portio_remap)(void);
int (*check_phys_apicid_present)(int boot_cpu_physical_apicid); int (*check_phys_apicid_present)(int boot_cpu_physical_apicid);
void (*enable_apic_mode)(void); void (*enable_apic_mode)(void);
u32 (*phys_pkg_id)(u32 cpuid_apic, int index_msb);
/* mpparse */ /* mpparse */
void (*mpc_oem_bus_info)(struct mpc_config_bus *, char *, void (*mpc_oem_bus_info)(struct mpc_config_bus *, char *,
...@@ -105,6 +106,7 @@ struct genapic { ...@@ -105,6 +106,7 @@ struct genapic {
APICFUNC(send_IPI_allbutself), \ APICFUNC(send_IPI_allbutself), \
APICFUNC(send_IPI_all), \ APICFUNC(send_IPI_all), \
APICFUNC(enable_apic_mode), \ APICFUNC(enable_apic_mode), \
APICFUNC(phys_pkg_id), \
} }
extern struct genapic *genapic; extern struct genapic *genapic;
......
...@@ -173,4 +173,9 @@ static inline unsigned int cpu_mask_to_apicid(cpumask_const_t cpumask) ...@@ -173,4 +173,9 @@ static inline unsigned int cpu_mask_to_apicid(cpumask_const_t cpumask)
return apicid; return apicid;
} }
static inline u32 phys_pkg_id(u32 cpuid_apic, int index_msb)
{
return cpuid_apic >> index_msb;
}
#endif /* __ASM_MACH_APIC_H */ #endif /* __ASM_MACH_APIC_H */
...@@ -127,4 +127,9 @@ static inline void enable_apic_mode(void) ...@@ -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 */ #endif /* __ASM_MACH_APIC_H */
...@@ -192,4 +192,9 @@ static inline unsigned int cpu_mask_to_apicid(cpumask_const_t cpumask) ...@@ -192,4 +192,9 @@ static inline unsigned int cpu_mask_to_apicid(cpumask_const_t cpumask)
return apicid; return apicid;
} }
static inline u32 phys_pkg_id(u32 cpuid_apic, int index_msb)
{
return cpuid_apic >> index_msb;
}
#endif /* __ASM_MACH_APIC_H */ #endif /* __ASM_MACH_APIC_H */
...@@ -27,5 +27,6 @@ ...@@ -27,5 +27,6 @@
#define check_apicid_used (genapic->check_apicid_used) #define check_apicid_used (genapic->check_apicid_used)
#define cpu_mask_to_apicid (genapic->cpu_mask_to_apicid) #define cpu_mask_to_apicid (genapic->cpu_mask_to_apicid)
#define enable_apic_mode (genapic->enable_apic_mode) #define enable_apic_mode (genapic->enable_apic_mode)
#define phys_pkg_id (genapic->phys_pkg_id)
#endif /* __ASM_MACH_APIC_H */ #endif /* __ASM_MACH_APIC_H */
...@@ -141,4 +141,10 @@ static inline unsigned int cpu_mask_to_apicid(cpumask_const_t cpumask) ...@@ -141,4 +141,10 @@ static inline unsigned int cpu_mask_to_apicid(cpumask_const_t cpumask)
return (int) 0xF; 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 */ #endif /* __ASM_MACH_APIC_H */
...@@ -173,4 +173,15 @@ static inline unsigned int cpu_mask_to_apicid(cpumask_const_t cpumask) ...@@ -173,4 +173,15 @@ static inline unsigned int cpu_mask_to_apicid(cpumask_const_t cpumask)
return apicid; 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 */ #endif /* __ASM_MACH_APIC_H */
...@@ -88,4 +88,10 @@ static inline unsigned int cpu_mask_to_apicid(cpumask_const_t cpumask) ...@@ -88,4 +88,10 @@ static inline unsigned int cpu_mask_to_apicid(cpumask_const_t cpumask)
{ {
return cpus_coerce_const(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 */ #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