Skip to content

Commit

Permalink
x86: Add apic->x86_32_early_logical_apicid()
Browse files Browse the repository at this point in the history
On x86_32, the mapping between cpu and logical apic ID differs
depending on the specific apic implementation in use.  The
mapping is initialized while bringing up CPUs; however, this
makes early inits ignore memory topology.

Add a x86_32 specific apic->x86_32_early_logical_apicid() which
is called early during boot to query the mapping.  The mapping
is later verified against the result of init_apic_ldr().  The
method is allowed to return BAD_APICID if it can't be determined
early.

noop variant which always returns BAD_APICID is implemented and
added to all x86_32 apic implementations.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: eric.dumazet@gmail.com
Cc: yinghai@kernel.org
Cc: brgerst@gmail.com
Cc: gorcunov@gmail.com
Cc: penberg@kernel.org
Cc: shaohui.zheng@intel.com
Cc: rientjes@google.com
LKML-Reference: <1295789862-25482-8-git-send-email-tj@kernel.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
  • Loading branch information
Tejun Heo authored and Ingo Molnar committed Jan 28, 2011
1 parent 7632611 commit acb8bc0
Show file tree
Hide file tree
Showing 8 changed files with 45 additions and 2 deletions.
19 changes: 19 additions & 0 deletions arch/x86/include/asm/apic.h
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,20 @@ struct apic {
void (*icr_write)(u32 low, u32 high);
void (*wait_icr_idle)(void);
u32 (*safe_wait_icr_idle)(void);

#ifdef CONFIG_X86_32
/*
* Called very early during boot from get_smp_config(). It should
* return the logical apicid. x86_[bios]_cpu_to_apicid is
* initialized before this function is called.
*
* If logical apicid can't be determined that early, the function
* may return BAD_APICID. Logical apicid will be configured after
* init_apic_ldr() while bringing up CPUs. Note that NUMA affinity
* won't be applied properly during early boot in this case.
*/
int (*x86_32_early_logical_apicid)(int cpu);
#endif
};

/*
Expand Down Expand Up @@ -501,6 +515,11 @@ extern struct apic apic_noop;

extern struct apic apic_default;

static inline int noop_x86_32_early_logical_apicid(int cpu)
{
return BAD_APICID;
}

/*
* Set up the logical destination ID.
*
Expand Down
12 changes: 10 additions & 2 deletions arch/x86/kernel/apic/apic.c
Original file line number Diff line number Diff line change
Expand Up @@ -1250,8 +1250,13 @@ void __cpuinit setup_local_APIC(void)

#ifdef CONFIG_X86_32
/*
* APIC LDR is initialized. Fetch and store logical_apic_id.
* APIC LDR is initialized. If logical_apicid mapping was
* initialized during get_smp_config(), make sure it matches the
* actual value.
*/
i = early_per_cpu(x86_cpu_to_logical_apicid, cpu);
WARN_ON(i != BAD_APICID && i != logical_smp_processor_id());
/* always use the value from LDR */
early_per_cpu(x86_cpu_to_logical_apicid, cpu) =
logical_smp_processor_id();
#endif
Expand Down Expand Up @@ -1991,7 +1996,10 @@ void __cpuinit generic_processor_info(int apicid, int version)
early_per_cpu(x86_cpu_to_apicid, cpu) = apicid;
early_per_cpu(x86_bios_cpu_apicid, cpu) = apicid;
#endif

#ifdef CONFIG_X86_32
early_per_cpu(x86_cpu_to_logical_apicid, cpu) =
apic->x86_32_early_logical_apicid(cpu);
#endif
set_cpu_possible(cpu, true);
set_cpu_present(cpu, true);
}
Expand Down
4 changes: 4 additions & 0 deletions arch/x86/kernel/apic/apic_noop.c
Original file line number Diff line number Diff line change
Expand Up @@ -191,4 +191,8 @@ struct apic apic_noop = {
.icr_write = noop_apic_icr_write,
.wait_icr_idle = noop_apic_wait_icr_idle,
.safe_wait_icr_idle = noop_safe_apic_wait_icr_idle,

#ifdef CONFIG_X86_32
.x86_32_early_logical_apicid = noop_x86_32_early_logical_apicid,
#endif
};
2 changes: 2 additions & 0 deletions arch/x86/kernel/apic/bigsmp_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -251,4 +251,6 @@ struct apic apic_bigsmp = {
.icr_write = native_apic_icr_write,
.wait_icr_idle = native_apic_wait_icr_idle,
.safe_wait_icr_idle = native_safe_apic_wait_icr_idle,

.x86_32_early_logical_apicid = noop_x86_32_early_logical_apicid,
};
4 changes: 4 additions & 0 deletions arch/x86/kernel/apic/es7000_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -682,6 +682,8 @@ struct apic __refdata apic_es7000_cluster = {
.icr_write = native_apic_icr_write,
.wait_icr_idle = native_apic_wait_icr_idle,
.safe_wait_icr_idle = native_safe_apic_wait_icr_idle,

.x86_32_early_logical_apicid = noop_x86_32_early_logical_apicid,
};

struct apic __refdata apic_es7000 = {
Expand Down Expand Up @@ -744,4 +746,6 @@ struct apic __refdata apic_es7000 = {
.icr_write = native_apic_icr_write,
.wait_icr_idle = native_apic_wait_icr_idle,
.safe_wait_icr_idle = native_safe_apic_wait_icr_idle,

.x86_32_early_logical_apicid = noop_x86_32_early_logical_apicid,
};
2 changes: 2 additions & 0 deletions arch/x86/kernel/apic/numaq_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -539,4 +539,6 @@ struct apic __refdata apic_numaq = {
.icr_write = native_apic_icr_write,
.wait_icr_idle = native_apic_wait_icr_idle,
.safe_wait_icr_idle = native_safe_apic_wait_icr_idle,

.x86_32_early_logical_apicid = noop_x86_32_early_logical_apicid,
};
2 changes: 2 additions & 0 deletions arch/x86/kernel/apic/probe_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,8 @@ struct apic apic_default = {
.icr_write = native_apic_icr_write,
.wait_icr_idle = native_apic_wait_icr_idle,
.safe_wait_icr_idle = native_safe_apic_wait_icr_idle,

.x86_32_early_logical_apicid = noop_x86_32_early_logical_apicid,
};

extern struct apic apic_numaq;
Expand Down
2 changes: 2 additions & 0 deletions arch/x86/kernel/apic/summit_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -552,4 +552,6 @@ struct apic apic_summit = {
.icr_write = native_apic_icr_write,
.wait_icr_idle = native_apic_wait_icr_idle,
.safe_wait_icr_idle = native_safe_apic_wait_icr_idle,

.x86_32_early_logical_apicid = noop_x86_32_early_logical_apicid,
};

0 comments on commit acb8bc0

Please sign in to comment.