x86: Add apic->x86_32_early_logical_apicid()
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>
This commit is contained in:
Родитель
7632611f53
Коммит
acb8bc09c6
|
@ -354,6 +354,20 @@ struct apic {
|
||||||
void (*icr_write)(u32 low, u32 high);
|
void (*icr_write)(u32 low, u32 high);
|
||||||
void (*wait_icr_idle)(void);
|
void (*wait_icr_idle)(void);
|
||||||
u32 (*safe_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
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -501,6 +515,11 @@ extern struct apic apic_noop;
|
||||||
|
|
||||||
extern struct apic apic_default;
|
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.
|
* Set up the logical destination ID.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1250,8 +1250,13 @@ void __cpuinit setup_local_APIC(void)
|
||||||
|
|
||||||
#ifdef CONFIG_X86_32
|
#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) =
|
early_per_cpu(x86_cpu_to_logical_apicid, cpu) =
|
||||||
logical_smp_processor_id();
|
logical_smp_processor_id();
|
||||||
#endif
|
#endif
|
||||||
|
@ -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_cpu_to_apicid, cpu) = apicid;
|
||||||
early_per_cpu(x86_bios_cpu_apicid, cpu) = apicid;
|
early_per_cpu(x86_bios_cpu_apicid, cpu) = apicid;
|
||||||
#endif
|
#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_possible(cpu, true);
|
||||||
set_cpu_present(cpu, true);
|
set_cpu_present(cpu, true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -191,4 +191,8 @@ struct apic apic_noop = {
|
||||||
.icr_write = noop_apic_icr_write,
|
.icr_write = noop_apic_icr_write,
|
||||||
.wait_icr_idle = noop_apic_wait_icr_idle,
|
.wait_icr_idle = noop_apic_wait_icr_idle,
|
||||||
.safe_wait_icr_idle = noop_safe_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
|
||||||
};
|
};
|
||||||
|
|
|
@ -251,4 +251,6 @@ struct apic apic_bigsmp = {
|
||||||
.icr_write = native_apic_icr_write,
|
.icr_write = native_apic_icr_write,
|
||||||
.wait_icr_idle = native_apic_wait_icr_idle,
|
.wait_icr_idle = native_apic_wait_icr_idle,
|
||||||
.safe_wait_icr_idle = native_safe_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,
|
||||||
};
|
};
|
||||||
|
|
|
@ -682,6 +682,8 @@ struct apic __refdata apic_es7000_cluster = {
|
||||||
.icr_write = native_apic_icr_write,
|
.icr_write = native_apic_icr_write,
|
||||||
.wait_icr_idle = native_apic_wait_icr_idle,
|
.wait_icr_idle = native_apic_wait_icr_idle,
|
||||||
.safe_wait_icr_idle = native_safe_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 = {
|
struct apic __refdata apic_es7000 = {
|
||||||
|
@ -744,4 +746,6 @@ struct apic __refdata apic_es7000 = {
|
||||||
.icr_write = native_apic_icr_write,
|
.icr_write = native_apic_icr_write,
|
||||||
.wait_icr_idle = native_apic_wait_icr_idle,
|
.wait_icr_idle = native_apic_wait_icr_idle,
|
||||||
.safe_wait_icr_idle = native_safe_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,
|
||||||
};
|
};
|
||||||
|
|
|
@ -539,4 +539,6 @@ struct apic __refdata apic_numaq = {
|
||||||
.icr_write = native_apic_icr_write,
|
.icr_write = native_apic_icr_write,
|
||||||
.wait_icr_idle = native_apic_wait_icr_idle,
|
.wait_icr_idle = native_apic_wait_icr_idle,
|
||||||
.safe_wait_icr_idle = native_safe_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,
|
||||||
};
|
};
|
||||||
|
|
|
@ -166,6 +166,8 @@ struct apic apic_default = {
|
||||||
.icr_write = native_apic_icr_write,
|
.icr_write = native_apic_icr_write,
|
||||||
.wait_icr_idle = native_apic_wait_icr_idle,
|
.wait_icr_idle = native_apic_wait_icr_idle,
|
||||||
.safe_wait_icr_idle = native_safe_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;
|
extern struct apic apic_numaq;
|
||||||
|
|
|
@ -552,4 +552,6 @@ struct apic apic_summit = {
|
||||||
.icr_write = native_apic_icr_write,
|
.icr_write = native_apic_icr_write,
|
||||||
.wait_icr_idle = native_apic_wait_icr_idle,
|
.wait_icr_idle = native_apic_wait_icr_idle,
|
||||||
.safe_wait_icr_idle = native_safe_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,
|
||||||
};
|
};
|
||||||
|
|
Загрузка…
Ссылка в новой задаче