x86: add x2apic config
Impact: cleanup so could deselect x2apic and INTR_REMAP will select x2apic Signed-off-by: Yinghai Lu <yinghai@kernel.org> Cc: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
parent
9f361c2219
commit
06cd9a7dc8
|
@ -235,6 +235,20 @@ config SMP
|
||||||
|
|
||||||
If you don't know what to do here, say N.
|
If you don't know what to do here, say N.
|
||||||
|
|
||||||
|
config X86_X2APIC
|
||||||
|
bool "Support x2apic"
|
||||||
|
depends on X86_LOCAL_APIC && X86_64
|
||||||
|
---help---
|
||||||
|
This enables x2apic support on CPUs that have this feature.
|
||||||
|
|
||||||
|
This allows 32-bit apic IDs (so it can support very large systems),
|
||||||
|
and accesses the local apic via MSRs not via mmio.
|
||||||
|
|
||||||
|
( On certain CPU models you may need to enable INTR_REMAP too,
|
||||||
|
to get functional x2apic mode. )
|
||||||
|
|
||||||
|
If you don't know what to do here, say N.
|
||||||
|
|
||||||
config SPARSE_IRQ
|
config SPARSE_IRQ
|
||||||
bool "Support sparse irq numbering"
|
bool "Support sparse irq numbering"
|
||||||
depends on PCI_MSI || HT_IRQ
|
depends on PCI_MSI || HT_IRQ
|
||||||
|
@ -1828,6 +1842,7 @@ config DMAR_FLOPPY_WA
|
||||||
config INTR_REMAP
|
config INTR_REMAP
|
||||||
bool "Support for Interrupt Remapping (EXPERIMENTAL)"
|
bool "Support for Interrupt Remapping (EXPERIMENTAL)"
|
||||||
depends on X86_64 && X86_IO_APIC && PCI_MSI && ACPI && EXPERIMENTAL
|
depends on X86_64 && X86_IO_APIC && PCI_MSI && ACPI && EXPERIMENTAL
|
||||||
|
select X86_X2APIC
|
||||||
---help---
|
---help---
|
||||||
Supports Interrupt remapping for IO-APIC and MSI devices.
|
Supports Interrupt remapping for IO-APIC and MSI devices.
|
||||||
To use x2apic mode in the CPU's which support x2APIC enhancements or
|
To use x2apic mode in the CPU's which support x2APIC enhancements or
|
||||||
|
|
|
@ -112,7 +112,7 @@ static inline u32 native_apic_msr_read(u32 reg)
|
||||||
return low;
|
return low;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef CONFIG_X86_32
|
#ifdef CONFIG_X86_X2APIC
|
||||||
extern int x2apic;
|
extern int x2apic;
|
||||||
extern void check_x2apic(void);
|
extern void check_x2apic(void);
|
||||||
extern void enable_x2apic(void);
|
extern void enable_x2apic(void);
|
||||||
|
@ -131,7 +131,19 @@ static inline int x2apic_enabled(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#define x2apic_enabled() 0
|
static inline void check_x2apic(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
static inline void enable_x2apic(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
static inline void enable_IR_x2apic(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
static inline int x2apic_enabled(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct apic_ops {
|
struct apic_ops {
|
||||||
|
@ -177,7 +189,7 @@ static inline u32 safe_apic_wait_icr_idle(void)
|
||||||
|
|
||||||
extern int get_physical_broadcast(void);
|
extern int get_physical_broadcast(void);
|
||||||
|
|
||||||
#ifdef CONFIG_X86_64
|
#ifdef CONFIG_X86_X2APIC
|
||||||
static inline void ack_x2APIC_irq(void)
|
static inline void ack_x2APIC_irq(void)
|
||||||
{
|
{
|
||||||
/* Docs say use 0 for future compatibility */
|
/* Docs say use 0 for future compatibility */
|
||||||
|
|
|
@ -117,8 +117,8 @@ obj-$(CONFIG_SWIOTLB) += pci-swiotlb_64.o # NB rename without _64
|
||||||
# 64 bit specific files
|
# 64 bit specific files
|
||||||
ifeq ($(CONFIG_X86_64),y)
|
ifeq ($(CONFIG_X86_64),y)
|
||||||
obj-y += genapic_64.o genapic_flat_64.o
|
obj-y += genapic_64.o genapic_flat_64.o
|
||||||
obj-y += genx2apic_cluster.o
|
obj-$(CONFIG_X86_X2APIC) += genx2apic_cluster.o
|
||||||
obj-y += genx2apic_phys.o
|
obj-$(CONFIG_X86_X2APIC) += genx2apic_phys.o
|
||||||
obj-$(CONFIG_X86_UV) += genx2apic_uv_x.o tlb_uv.o
|
obj-$(CONFIG_X86_UV) += genx2apic_uv_x.o tlb_uv.o
|
||||||
obj-$(CONFIG_X86_UV) += bios_uv.o uv_irq.o uv_sysfs.o
|
obj-$(CONFIG_X86_UV) += bios_uv.o uv_irq.o uv_sysfs.o
|
||||||
obj-$(CONFIG_X86_PM_TIMER) += pmtimer_64.o
|
obj-$(CONFIG_X86_PM_TIMER) += pmtimer_64.o
|
||||||
|
|
|
@ -112,11 +112,7 @@ static __init int setup_apicpmtimer(char *s)
|
||||||
__setup("apicpmtimer", setup_apicpmtimer);
|
__setup("apicpmtimer", setup_apicpmtimer);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_X86_64
|
#ifdef CONFIG_X86_X2APIC
|
||||||
#define HAVE_X2APIC
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_X2APIC
|
|
||||||
int x2apic;
|
int x2apic;
|
||||||
/* x2apic enabled before OS handover */
|
/* x2apic enabled before OS handover */
|
||||||
static int x2apic_preenabled;
|
static int x2apic_preenabled;
|
||||||
|
@ -269,7 +265,7 @@ static struct apic_ops xapic_ops = {
|
||||||
struct apic_ops __read_mostly *apic_ops = &xapic_ops;
|
struct apic_ops __read_mostly *apic_ops = &xapic_ops;
|
||||||
EXPORT_SYMBOL_GPL(apic_ops);
|
EXPORT_SYMBOL_GPL(apic_ops);
|
||||||
|
|
||||||
#ifdef HAVE_X2APIC
|
#ifdef CONFIG_X86_X2APIC
|
||||||
static void x2apic_wait_icr_idle(void)
|
static void x2apic_wait_icr_idle(void)
|
||||||
{
|
{
|
||||||
/* no need to wait for icr idle in x2apic */
|
/* no need to wait for icr idle in x2apic */
|
||||||
|
@ -1320,11 +1316,14 @@ void __cpuinit end_local_APIC_setup(void)
|
||||||
apic_pm_activate();
|
apic_pm_activate();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_X2APIC
|
#ifdef CONFIG_X86_X2APIC
|
||||||
void check_x2apic(void)
|
void check_x2apic(void)
|
||||||
{
|
{
|
||||||
int msr, msr2;
|
int msr, msr2;
|
||||||
|
|
||||||
|
if (!cpu_has_x2apic)
|
||||||
|
return;
|
||||||
|
|
||||||
rdmsr(MSR_IA32_APICBASE, msr, msr2);
|
rdmsr(MSR_IA32_APICBASE, msr, msr2);
|
||||||
|
|
||||||
if (msr & X2APIC_ENABLE) {
|
if (msr & X2APIC_ENABLE) {
|
||||||
|
@ -1338,6 +1337,9 @@ void enable_x2apic(void)
|
||||||
{
|
{
|
||||||
int msr, msr2;
|
int msr, msr2;
|
||||||
|
|
||||||
|
if (!x2apic)
|
||||||
|
return;
|
||||||
|
|
||||||
rdmsr(MSR_IA32_APICBASE, msr, msr2);
|
rdmsr(MSR_IA32_APICBASE, msr, msr2);
|
||||||
if (!(msr & X2APIC_ENABLE)) {
|
if (!(msr & X2APIC_ENABLE)) {
|
||||||
pr_info("Enabling x2apic\n");
|
pr_info("Enabling x2apic\n");
|
||||||
|
@ -1439,7 +1441,7 @@ end:
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif /* HAVE_X2APIC */
|
#endif /* CONFIG_X86_X2APIC */
|
||||||
|
|
||||||
#ifdef CONFIG_X86_64
|
#ifdef CONFIG_X86_64
|
||||||
/*
|
/*
|
||||||
|
@ -1570,7 +1572,7 @@ void __init early_init_lapic_mapping(void)
|
||||||
*/
|
*/
|
||||||
void __init init_apic_mappings(void)
|
void __init init_apic_mappings(void)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_X2APIC
|
#ifdef CONFIG_X86_X2APIC
|
||||||
if (x2apic) {
|
if (x2apic) {
|
||||||
boot_cpu_physical_apicid = read_apic_id();
|
boot_cpu_physical_apicid = read_apic_id();
|
||||||
return;
|
return;
|
||||||
|
@ -1634,9 +1636,7 @@ int __init APIC_init_uniprocessor(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_X2APIC
|
|
||||||
enable_IR_x2apic();
|
enable_IR_x2apic();
|
||||||
#endif
|
|
||||||
#ifdef CONFIG_X86_64
|
#ifdef CONFIG_X86_64
|
||||||
default_setup_apic_routing();
|
default_setup_apic_routing();
|
||||||
#endif
|
#endif
|
||||||
|
@ -2021,7 +2021,7 @@ static int lapic_resume(struct sys_device *dev)
|
||||||
|
|
||||||
local_irq_save(flags);
|
local_irq_save(flags);
|
||||||
|
|
||||||
#ifdef HAVE_X2APIC
|
#ifdef CONFIG_X86_X2APIC
|
||||||
if (x2apic)
|
if (x2apic)
|
||||||
enable_x2apic();
|
enable_x2apic();
|
||||||
else
|
else
|
||||||
|
|
|
@ -1051,7 +1051,7 @@ void __cpuinit cpu_init(void)
|
||||||
barrier();
|
barrier();
|
||||||
|
|
||||||
check_efer();
|
check_efer();
|
||||||
if (cpu != 0 && x2apic)
|
if (cpu != 0)
|
||||||
enable_x2apic();
|
enable_x2apic();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -35,8 +35,10 @@ static struct genapic *apic_probe[] __initdata = {
|
||||||
#ifdef CONFIG_X86_UV
|
#ifdef CONFIG_X86_UV
|
||||||
&apic_x2apic_uv_x,
|
&apic_x2apic_uv_x,
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef CONFIG_X86_X2APIC
|
||||||
&apic_x2apic_phys,
|
&apic_x2apic_phys,
|
||||||
&apic_x2apic_cluster,
|
&apic_x2apic_cluster,
|
||||||
|
#endif
|
||||||
&apic_physflat,
|
&apic_physflat,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
@ -46,10 +48,12 @@ static struct genapic *apic_probe[] __initdata = {
|
||||||
*/
|
*/
|
||||||
void __init default_setup_apic_routing(void)
|
void __init default_setup_apic_routing(void)
|
||||||
{
|
{
|
||||||
|
#ifdef CONFIG_X86_X2APIC
|
||||||
if (apic == &apic_x2apic_phys || apic == &apic_x2apic_cluster) {
|
if (apic == &apic_x2apic_phys || apic == &apic_x2apic_cluster) {
|
||||||
if (!intr_remapping_enabled)
|
if (!intr_remapping_enabled)
|
||||||
apic = &apic_flat;
|
apic = &apic_flat;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (apic == &apic_flat) {
|
if (apic == &apic_flat) {
|
||||||
if (max_physical_apicid >= 8)
|
if (max_physical_apicid >= 8)
|
||||||
|
|
|
@ -836,8 +836,7 @@ void __init setup_arch(char **cmdline_p)
|
||||||
#else
|
#else
|
||||||
num_physpages = max_pfn;
|
num_physpages = max_pfn;
|
||||||
|
|
||||||
if (cpu_has_x2apic)
|
check_x2apic();
|
||||||
check_x2apic();
|
|
||||||
|
|
||||||
/* How many end-of-memory variables you have, grandma! */
|
/* How many end-of-memory variables you have, grandma! */
|
||||||
/* need this before calling reserve_initrd */
|
/* need this before calling reserve_initrd */
|
||||||
|
|
|
@ -1128,8 +1128,8 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus)
|
||||||
current_thread_info()->cpu = 0; /* needed? */
|
current_thread_info()->cpu = 0; /* needed? */
|
||||||
set_cpu_sibling_map(0);
|
set_cpu_sibling_map(0);
|
||||||
|
|
||||||
#ifdef CONFIG_X86_64
|
|
||||||
enable_IR_x2apic();
|
enable_IR_x2apic();
|
||||||
|
#ifdef CONFIG_X86_64
|
||||||
default_setup_apic_routing();
|
default_setup_apic_routing();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue