Commit 017892c3 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'x86-apic-for-linus' of...

Merge branch 'x86-apic-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip

* 'x86-apic-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  x86: Fix APIC ID sizing bug on larger systems, clean up MAX_APICS confusion
  x86, acpi: Parse all SRAT cpu entries even above the cpu number limitation
  x86, acpi: Add MAX_LOCAL_APIC for 32bit
  x86: io_apic: Split setup_ioapic_ids_from_mpc()
  x86: io_apic: Fix CONFIG_X86_IO_APIC=n breakage
  x86: apic: Move probe_nr_irqs_gsi() into ioapic_init_mappings()
  x86: Allow platforms to force enable apic
parents 42cbd8ef cb2ded37
...@@ -238,6 +238,7 @@ extern void setup_boot_APIC_clock(void); ...@@ -238,6 +238,7 @@ extern void setup_boot_APIC_clock(void);
extern void setup_secondary_APIC_clock(void); extern void setup_secondary_APIC_clock(void);
extern int APIC_init_uniprocessor(void); extern int APIC_init_uniprocessor(void);
extern void enable_NMI_through_LVT0(void); extern void enable_NMI_through_LVT0(void);
extern int apic_force_enable(void);
/* /*
* On 32bit this is mach-xxx local * On 32bit this is mach-xxx local
......
...@@ -145,6 +145,7 @@ ...@@ -145,6 +145,7 @@
#ifdef CONFIG_X86_32 #ifdef CONFIG_X86_32
# define MAX_IO_APICS 64 # define MAX_IO_APICS 64
# define MAX_LOCAL_APIC 256
#else #else
# define MAX_IO_APICS 128 # define MAX_IO_APICS 128
# define MAX_LOCAL_APIC 32768 # define MAX_LOCAL_APIC 32768
......
...@@ -159,7 +159,7 @@ struct io_apic_irq_attr; ...@@ -159,7 +159,7 @@ struct io_apic_irq_attr;
extern int io_apic_set_pci_routing(struct device *dev, int irq, extern int io_apic_set_pci_routing(struct device *dev, int irq,
struct io_apic_irq_attr *irq_attr); struct io_apic_irq_attr *irq_attr);
void setup_IO_APIC_irq_extra(u32 gsi); void setup_IO_APIC_irq_extra(u32 gsi);
extern void ioapic_init_mappings(void); extern void ioapic_and_gsi_init(void);
extern void ioapic_insert_resources(void); extern void ioapic_insert_resources(void);
extern struct IO_APIC_route_entry **alloc_ioapic_entries(void); extern struct IO_APIC_route_entry **alloc_ioapic_entries(void);
...@@ -168,10 +168,9 @@ extern int save_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries); ...@@ -168,10 +168,9 @@ extern int save_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries);
extern void mask_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries); extern void mask_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries);
extern int restore_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries); extern int restore_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries);
extern void probe_nr_irqs_gsi(void);
extern int get_nr_irqs_gsi(void); extern int get_nr_irqs_gsi(void);
extern void setup_ioapic_ids_from_mpc(void); extern void setup_ioapic_ids_from_mpc(void);
extern void setup_ioapic_ids_from_mpc_nocheck(void);
struct mp_ioapic_gsi{ struct mp_ioapic_gsi{
u32 gsi_base; u32 gsi_base;
...@@ -189,9 +188,8 @@ extern void __init pre_init_apic_IRQ0(void); ...@@ -189,9 +188,8 @@ extern void __init pre_init_apic_IRQ0(void);
#define io_apic_assign_pci_irqs 0 #define io_apic_assign_pci_irqs 0
#define setup_ioapic_ids_from_mpc x86_init_noop #define setup_ioapic_ids_from_mpc x86_init_noop
static const int timer_through_8259 = 0; static const int timer_through_8259 = 0;
static inline void ioapic_init_mappings(void) { } static inline void ioapic_and_gsi_init(void) { }
static inline void ioapic_insert_resources(void) { } static inline void ioapic_insert_resources(void) { }
static inline void probe_nr_irqs_gsi(void) { }
#define gsi_top (NR_IRQS_LEGACY) #define gsi_top (NR_IRQS_LEGACY)
static inline int mp_find_ioapic(u32 gsi) { return 0; } static inline int mp_find_ioapic(u32 gsi) { return 0; }
......
...@@ -5,8 +5,9 @@ ...@@ -5,8 +5,9 @@
#include <asm/mpspec_def.h> #include <asm/mpspec_def.h>
#include <asm/x86_init.h> #include <asm/x86_init.h>
#include <asm/apicdef.h>
extern int apic_version[MAX_APICS]; extern int apic_version[];
extern int pic_mode; extern int pic_mode;
#ifdef CONFIG_X86_32 #ifdef CONFIG_X86_32
...@@ -107,7 +108,7 @@ extern int mp_register_gsi(struct device *dev, u32 gsi, int edge_level, ...@@ -107,7 +108,7 @@ extern int mp_register_gsi(struct device *dev, u32 gsi, int edge_level,
int active_high_low); int active_high_low);
#endif /* CONFIG_ACPI */ #endif /* CONFIG_ACPI */
#define PHYSID_ARRAY_SIZE BITS_TO_LONGS(MAX_APICS) #define PHYSID_ARRAY_SIZE BITS_TO_LONGS(MAX_LOCAL_APIC)
struct physid_mask { struct physid_mask {
unsigned long mask[PHYSID_ARRAY_SIZE]; unsigned long mask[PHYSID_ARRAY_SIZE];
...@@ -122,31 +123,31 @@ typedef struct physid_mask physid_mask_t; ...@@ -122,31 +123,31 @@ typedef struct physid_mask physid_mask_t;
test_and_set_bit(physid, (map).mask) test_and_set_bit(physid, (map).mask)
#define physids_and(dst, src1, src2) \ #define physids_and(dst, src1, src2) \
bitmap_and((dst).mask, (src1).mask, (src2).mask, MAX_APICS) bitmap_and((dst).mask, (src1).mask, (src2).mask, MAX_LOCAL_APIC)
#define physids_or(dst, src1, src2) \ #define physids_or(dst, src1, src2) \
bitmap_or((dst).mask, (src1).mask, (src2).mask, MAX_APICS) bitmap_or((dst).mask, (src1).mask, (src2).mask, MAX_LOCAL_APIC)
#define physids_clear(map) \ #define physids_clear(map) \
bitmap_zero((map).mask, MAX_APICS) bitmap_zero((map).mask, MAX_LOCAL_APIC)
#define physids_complement(dst, src) \ #define physids_complement(dst, src) \
bitmap_complement((dst).mask, (src).mask, MAX_APICS) bitmap_complement((dst).mask, (src).mask, MAX_LOCAL_APIC)
#define physids_empty(map) \ #define physids_empty(map) \
bitmap_empty((map).mask, MAX_APICS) bitmap_empty((map).mask, MAX_LOCAL_APIC)
#define physids_equal(map1, map2) \ #define physids_equal(map1, map2) \
bitmap_equal((map1).mask, (map2).mask, MAX_APICS) bitmap_equal((map1).mask, (map2).mask, MAX_LOCAL_APIC)
#define physids_weight(map) \ #define physids_weight(map) \
bitmap_weight((map).mask, MAX_APICS) bitmap_weight((map).mask, MAX_LOCAL_APIC)
#define physids_shift_right(d, s, n) \ #define physids_shift_right(d, s, n) \
bitmap_shift_right((d).mask, (s).mask, n, MAX_APICS) bitmap_shift_right((d).mask, (s).mask, n, MAX_LOCAL_APIC)
#define physids_shift_left(d, s, n) \ #define physids_shift_left(d, s, n) \
bitmap_shift_left((d).mask, (s).mask, n, MAX_APICS) bitmap_shift_left((d).mask, (s).mask, n, MAX_LOCAL_APIC)
static inline unsigned long physids_coerce(physid_mask_t *map) static inline unsigned long physids_coerce(physid_mask_t *map)
{ {
...@@ -159,14 +160,6 @@ static inline void physids_promote(unsigned long physids, physid_mask_t *map) ...@@ -159,14 +160,6 @@ static inline void physids_promote(unsigned long physids, physid_mask_t *map)
map->mask[0] = physids; map->mask[0] = physids;
} }
/* Note: will create very large stack frames if physid_mask_t is big */
#define physid_mask_of_physid(physid) \
({ \
physid_mask_t __physid_mask = PHYSID_MASK_NONE; \
physid_set(physid, __physid_mask); \
__physid_mask; \
})
static inline void physid_set_mask_of_physid(int physid, physid_mask_t *map) static inline void physid_set_mask_of_physid(int physid, physid_mask_t *map)
{ {
physids_clear(*map); physids_clear(*map);
......
...@@ -15,13 +15,6 @@ ...@@ -15,13 +15,6 @@
#ifdef CONFIG_X86_32 #ifdef CONFIG_X86_32
# define MAX_MPC_ENTRY 1024 # define MAX_MPC_ENTRY 1024
# define MAX_APICS 256
#else
# if NR_CPUS <= 255
# define MAX_APICS 255
# else
# define MAX_APICS 32768
# endif
#endif #endif
/* Intel MP Floating Pointer Structure */ /* Intel MP Floating Pointer Structure */
......
...@@ -198,6 +198,11 @@ static void __cpuinit acpi_register_lapic(int id, u8 enabled) ...@@ -198,6 +198,11 @@ static void __cpuinit acpi_register_lapic(int id, u8 enabled)
{ {
unsigned int ver = 0; unsigned int ver = 0;
if (id >= (MAX_LOCAL_APIC-1)) {
printk(KERN_INFO PREFIX "skipped apicid that is too big\n");
return;
}
if (!enabled) { if (!enabled) {
++disabled_cpus; ++disabled_cpus;
return; return;
...@@ -910,13 +915,13 @@ static int __init acpi_parse_madt_lapic_entries(void) ...@@ -910,13 +915,13 @@ static int __init acpi_parse_madt_lapic_entries(void)
acpi_register_lapic_address(acpi_lapic_addr); acpi_register_lapic_address(acpi_lapic_addr);
count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_SAPIC, count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_SAPIC,
acpi_parse_sapic, MAX_APICS); acpi_parse_sapic, MAX_LOCAL_APIC);
if (!count) { if (!count) {
x2count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_X2APIC, x2count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_X2APIC,
acpi_parse_x2apic, MAX_APICS); acpi_parse_x2apic, MAX_LOCAL_APIC);
count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC, count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC,
acpi_parse_lapic, MAX_APICS); acpi_parse_lapic, MAX_LOCAL_APIC);
} }
if (!count && !x2count) { if (!count && !x2count) {
printk(KERN_ERR PREFIX "No LAPIC entries present\n"); printk(KERN_ERR PREFIX "No LAPIC entries present\n");
......
...@@ -1532,13 +1532,60 @@ static int __init detect_init_APIC(void) ...@@ -1532,13 +1532,60 @@ static int __init detect_init_APIC(void)
return 0; return 0;
} }
#else #else
static int apic_verify(void)
{
u32 features, h, l;
/*
* The APIC feature bit should now be enabled
* in `cpuid'
*/
features = cpuid_edx(1);
if (!(features & (1 << X86_FEATURE_APIC))) {
pr_warning("Could not enable APIC!\n");
return -1;
}
set_cpu_cap(&boot_cpu_data, X86_FEATURE_APIC);
mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
/* The BIOS may have set up the APIC at some other address */
rdmsr(MSR_IA32_APICBASE, l, h);
if (l & MSR_IA32_APICBASE_ENABLE)
mp_lapic_addr = l & MSR_IA32_APICBASE_BASE;
pr_info("Found and enabled local APIC!\n");
return 0;
}
int apic_force_enable(void)
{
u32 h, l;
if (disable_apic)
return -1;
/*
* Some BIOSes disable the local APIC in the APIC_BASE
* MSR. This can only be done in software for Intel P6 or later
* and AMD K7 (Model > 1) or later.
*/
rdmsr(MSR_IA32_APICBASE, l, h);
if (!(l & MSR_IA32_APICBASE_ENABLE)) {
pr_info("Local APIC disabled by BIOS -- reenabling.\n");
l &= ~MSR_IA32_APICBASE_BASE;
l |= MSR_IA32_APICBASE_ENABLE | APIC_DEFAULT_PHYS_BASE;
wrmsr(MSR_IA32_APICBASE, l, h);
enabled_via_apicbase = 1;
}
return apic_verify();
}
/* /*
* Detect and initialize APIC * Detect and initialize APIC
*/ */
static int __init detect_init_APIC(void) static int __init detect_init_APIC(void)
{ {
u32 h, l, features;
/* Disabled by kernel option? */ /* Disabled by kernel option? */
if (disable_apic) if (disable_apic)
return -1; return -1;
...@@ -1568,38 +1615,12 @@ static int __init detect_init_APIC(void) ...@@ -1568,38 +1615,12 @@ static int __init detect_init_APIC(void)
"you can enable it with \"lapic\"\n"); "you can enable it with \"lapic\"\n");
return -1; return -1;
} }
/* if (apic_force_enable())
* Some BIOSes disable the local APIC in the APIC_BASE return -1;
* MSR. This can only be done in software for Intel P6 or later } else {
* and AMD K7 (Model > 1) or later. if (apic_verify())
*/
rdmsr(MSR_IA32_APICBASE, l, h);
if (!(l & MSR_IA32_APICBASE_ENABLE)) {
pr_info("Local APIC disabled by BIOS -- reenabling.\n");
l &= ~MSR_IA32_APICBASE_BASE;
l |= MSR_IA32_APICBASE_ENABLE | APIC_DEFAULT_PHYS_BASE;
wrmsr(MSR_IA32_APICBASE, l, h);
enabled_via_apicbase = 1;
}
}
/*
* The APIC feature bit should now be enabled
* in `cpuid'
*/
features = cpuid_edx(1);
if (!(features & (1 << X86_FEATURE_APIC))) {
pr_warning("Could not enable APIC!\n");
return -1; return -1;
} }
set_cpu_cap(&boot_cpu_data, X86_FEATURE_APIC);
mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
/* The BIOS may have set up the APIC at some other address */
rdmsr(MSR_IA32_APICBASE, l, h);
if (l & MSR_IA32_APICBASE_ENABLE)
mp_lapic_addr = l & MSR_IA32_APICBASE_BASE;
pr_info("Found and enabled local APIC!\n");
apic_pm_activate(); apic_pm_activate();
...@@ -1687,7 +1708,7 @@ void __init init_apic_mappings(void) ...@@ -1687,7 +1708,7 @@ void __init init_apic_mappings(void)
* This initializes the IO-APIC and APIC hardware if this is * This initializes the IO-APIC and APIC hardware if this is
* a UP kernel. * a UP kernel.
*/ */
int apic_version[MAX_APICS]; int apic_version[MAX_LOCAL_APIC];
int __init APIC_init_uniprocessor(void) int __init APIC_init_uniprocessor(void)
{ {
......
...@@ -1933,8 +1933,7 @@ void disable_IO_APIC(void) ...@@ -1933,8 +1933,7 @@ void disable_IO_APIC(void)
* *
* by Matt Domsch <Matt_Domsch@dell.com> Tue Dec 21 12:25:05 CST 1999 * by Matt Domsch <Matt_Domsch@dell.com> Tue Dec 21 12:25:05 CST 1999
*/ */
void __init setup_ioapic_ids_from_mpc_nocheck(void)
void __init setup_ioapic_ids_from_mpc(void)
{ {
union IO_APIC_reg_00 reg_00; union IO_APIC_reg_00 reg_00;
physid_mask_t phys_id_present_map; physid_mask_t phys_id_present_map;
...@@ -1943,15 +1942,6 @@ void __init setup_ioapic_ids_from_mpc(void) ...@@ -1943,15 +1942,6 @@ void __init setup_ioapic_ids_from_mpc(void)
unsigned char old_id; unsigned char old_id;
unsigned long flags; unsigned long flags;
if (acpi_ioapic)
return;
/*
* Don't check I/O APIC IDs for xAPIC systems. They have
* no meaning without the serial APIC bus.
*/
if (!(boot_cpu_data.x86_vendor == X86_VENDOR_INTEL)
|| APIC_XAPIC(apic_version[boot_cpu_physical_apicid]))
return;
/* /*
* This is broken; anything with a real cpu count has to * This is broken; anything with a real cpu count has to
* circumvent this idiocy regardless. * circumvent this idiocy regardless.
...@@ -2005,7 +1995,6 @@ void __init setup_ioapic_ids_from_mpc(void) ...@@ -2005,7 +1995,6 @@ void __init setup_ioapic_ids_from_mpc(void)
physids_or(phys_id_present_map, phys_id_present_map, tmp); physids_or(phys_id_present_map, phys_id_present_map, tmp);
} }
/* /*
* We need to adjust the IRQ routing table * We need to adjust the IRQ routing table
* if the ID changed. * if the ID changed.
...@@ -2041,6 +2030,21 @@ void __init setup_ioapic_ids_from_mpc(void) ...@@ -2041,6 +2030,21 @@ void __init setup_ioapic_ids_from_mpc(void)
apic_printk(APIC_VERBOSE, " ok.\n"); apic_printk(APIC_VERBOSE, " ok.\n");
} }
} }
void __init setup_ioapic_ids_from_mpc(void)
{
if (acpi_ioapic)
return;
/*
* Don't check I/O APIC IDs for xAPIC systems. They have
* no meaning without the serial APIC bus.
*/
if (!(boot_cpu_data.x86_vendor == X86_VENDOR_INTEL)
|| APIC_XAPIC(apic_version[boot_cpu_physical_apicid]))
return;
setup_ioapic_ids_from_mpc_nocheck();
}
#endif #endif
int no_timer_check __initdata; int no_timer_check __initdata;
...@@ -3593,7 +3597,7 @@ int __init io_apic_get_redir_entries (int ioapic) ...@@ -3593,7 +3597,7 @@ int __init io_apic_get_redir_entries (int ioapic)
return reg_01.bits.entries + 1; return reg_01.bits.entries + 1;
} }
void __init probe_nr_irqs_gsi(void) static void __init probe_nr_irqs_gsi(void)
{ {
int nr; int nr;
...@@ -3910,7 +3914,7 @@ static struct resource * __init ioapic_setup_resources(int nr_ioapics) ...@@ -3910,7 +3914,7 @@ static struct resource * __init ioapic_setup_resources(int nr_ioapics)
return res; return res;
} }
void __init ioapic_init_mappings(void) void __init ioapic_and_gsi_init(void)
{ {
unsigned long ioapic_phys, idx = FIX_IO_APIC_BASE_0; unsigned long ioapic_phys, idx = FIX_IO_APIC_BASE_0;
struct resource *ioapic_res; struct resource *ioapic_res;
...@@ -3948,6 +3952,8 @@ void __init ioapic_init_mappings(void) ...@@ -3948,6 +3952,8 @@ void __init ioapic_init_mappings(void)
ioapic_res->end = ioapic_phys + IO_APIC_SLOT_SIZE - 1; ioapic_res->end = ioapic_phys + IO_APIC_SLOT_SIZE - 1;
ioapic_res++; ioapic_res++;
} }
probe_nr_irqs_gsi();
} }
void __init ioapic_insert_resources(void) void __init ioapic_insert_resources(void)
...@@ -4057,7 +4063,8 @@ void __init pre_init_apic_IRQ0(void) ...@@ -4057,7 +4063,8 @@ void __init pre_init_apic_IRQ0(void)
printk(KERN_INFO "Early APIC setup for system timer0\n"); printk(KERN_INFO "Early APIC setup for system timer0\n");
#ifndef CONFIG_SMP #ifndef CONFIG_SMP
phys_cpu_present_map = physid_mask_of_physid(boot_cpu_physical_apicid); physid_set_mask_of_physid(boot_cpu_physical_apicid,
&phys_cpu_present_map);
#endif #endif
/* Make sure the irq descriptor is set up */ /* Make sure the irq descriptor is set up */
cfg = alloc_irq_and_cfg_at(0, 0); cfg = alloc_irq_and_cfg_at(0, 0);
......
...@@ -1045,10 +1045,7 @@ void __init setup_arch(char **cmdline_p) ...@@ -1045,10 +1045,7 @@ void __init setup_arch(char **cmdline_p)
#endif #endif
init_apic_mappings(); init_apic_mappings();
ioapic_init_mappings(); ioapic_and_gsi_init();
/* need to wait for io_apic is mapped */
probe_nr_irqs_gsi();
kvm_guest_init(); kvm_guest_init();
......
...@@ -92,6 +92,7 @@ acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *cpu_affinity) ...@@ -92,6 +92,7 @@ acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *cpu_affinity)
/* mark this node as "seen" in node bitmap */ /* mark this node as "seen" in node bitmap */
BMAP_SET(pxm_bitmap, cpu_affinity->proximity_domain_lo); BMAP_SET(pxm_bitmap, cpu_affinity->proximity_domain_lo);
/* don't need to check apic_id here, because it is always 8 bits */
apicid_to_pxm[cpu_affinity->apic_id] = cpu_affinity->proximity_domain_lo; apicid_to_pxm[cpu_affinity->apic_id] = cpu_affinity->proximity_domain_lo;
printk(KERN_DEBUG "CPU %02x in proximity domain %02x\n", printk(KERN_DEBUG "CPU %02x in proximity domain %02x\n",
......
...@@ -134,6 +134,10 @@ acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa) ...@@ -134,6 +134,10 @@ acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa)
} }
apic_id = pa->apic_id; apic_id = pa->apic_id;
if (apic_id >= MAX_LOCAL_APIC) {
printk(KERN_INFO "SRAT: PXM %u -> APIC 0x%04x -> Node %u skipped apicid that is too big\n", pxm, apic_id, node);
return;
}
apicid_to_node[apic_id] = node; apicid_to_node[apic_id] = node;
node_set(node, cpu_nodes_parsed); node_set(node, cpu_nodes_parsed);
acpi_numa = 1; acpi_numa = 1;
...@@ -168,6 +172,12 @@ acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa) ...@@ -168,6 +172,12 @@ acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa)
apic_id = (pa->apic_id << 8) | pa->local_sapic_eid; apic_id = (pa->apic_id << 8) | pa->local_sapic_eid;
else else
apic_id = pa->apic_id; apic_id = pa->apic_id;
if (apic_id >= MAX_LOCAL_APIC) {
printk(KERN_INFO "SRAT: PXM %u -> APIC 0x%02x -> Node %u skipped apicid that is too big\n", pxm, apic_id, node);
return;
}
apicid_to_node[apic_id] = node; apicid_to_node[apic_id] = node;
node_set(node, cpu_nodes_parsed); node_set(node, cpu_nodes_parsed);
acpi_numa = 1; acpi_numa = 1;
......
...@@ -48,9 +48,9 @@ static void __init mp_sfi_register_lapic_address(unsigned long address) ...@@ -48,9 +48,9 @@ static void __init mp_sfi_register_lapic_address(unsigned long address)
/* All CPUs enumerated by SFI must be present and enabled */ /* All CPUs enumerated by SFI must be present and enabled */
static void __cpuinit mp_sfi_register_lapic(u8 id) static void __cpuinit mp_sfi_register_lapic(u8 id)
{ {
if (MAX_APICS - id <= 0) { if (MAX_LOCAL_APIC - id <= 0) {
pr_warning("Processor #%d invalid (max %d)\n", pr_warning("Processor #%d invalid (max %d)\n",
id, MAX_APICS); id, MAX_LOCAL_APIC);
return; return;
} }
......
...@@ -171,7 +171,7 @@ static void __init MP_processor_info(struct mpc_cpu *m) ...@@ -171,7 +171,7 @@ static void __init MP_processor_info(struct mpc_cpu *m)
ver = m->apicver; ver = m->apicver;
if ((ver >= 0x14 && m->apicid >= 0xff) || m->apicid >= 0xf) { if ((ver >= 0x14 && m->apicid >= 0xff) || m->apicid >= 0xf) {
printk(KERN_ERR "Processor #%d INVALID. (Max ID: %d).\n", printk(KERN_ERR "Processor #%d INVALID. (Max ID: %d).\n",
m->apicid, MAX_APICS); m->apicid, MAX_LOCAL_APIC);
return; return;
} }
......
...@@ -275,13 +275,23 @@ acpi_table_parse_srat(enum acpi_srat_type id, ...@@ -275,13 +275,23 @@ acpi_table_parse_srat(enum acpi_srat_type id,
int __init acpi_numa_init(void) int __init acpi_numa_init(void)
{ {
int ret = 0; int ret = 0;
int nr_cpu_entries = nr_cpu_ids;
#ifdef CONFIG_X86
/*
* Should not limit number with cpu num that is from NR_CPUS or nr_cpus=
* SRAT cpu entries could have different order with that in MADT.
* So go over all cpu entries in SRAT to get apicid to node mapping.
*/
nr_cpu_entries = MAX_LOCAL_APIC;
#endif
/* SRAT: Static Resource Affinity Table */ /* SRAT: Static Resource Affinity Table */
if (!acpi_table_parse(ACPI_SIG_SRAT, acpi_parse_srat)) { if (!acpi_table_parse(ACPI_SIG_SRAT, acpi_parse_srat)) {
acpi_table_parse_srat(ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY, acpi_table_parse_srat(ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY,
acpi_parse_x2apic_affinity, nr_cpu_ids); acpi_parse_x2apic_affinity, nr_cpu_entries);
acpi_table_parse_srat(ACPI_SRAT_TYPE_CPU_AFFINITY, acpi_table_parse_srat(ACPI_SRAT_TYPE_CPU_AFFINITY,
acpi_parse_processor_affinity, nr_cpu_ids); acpi_parse_processor_affinity, nr_cpu_entries);
ret = acpi_table_parse_srat(ACPI_SRAT_TYPE_MEMORY_AFFINITY, ret = acpi_table_parse_srat(ACPI_SRAT_TYPE_MEMORY_AFFINITY,
acpi_parse_memory_affinity, acpi_parse_memory_affinity,
NR_NODE_MEMBLKS); NR_NODE_MEMBLKS);
......
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