x86: add x2apic config
authorYinghai Lu <yinghai@kernel.org>
Tue, 17 Feb 2009 01:29:58 +0000 (17:29 -0800)
committerIngo Molnar <mingo@elte.hu>
Tue, 17 Feb 2009 11:22:20 +0000 (12:22 +0100)
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>
arch/x86/Kconfig
arch/x86/include/asm/apic.h
arch/x86/kernel/Makefile
arch/x86/kernel/apic.c
arch/x86/kernel/cpu/common.c
arch/x86/kernel/genapic_64.c
arch/x86/kernel/setup.c
arch/x86/kernel/smpboot.c

index 1042d69b267d4489e78365b27ec158d10d06d0c7..bce241fe1d2de169450ddb3efdd6434bbc92f71f 100644 (file)
@@ -235,6 +235,20 @@ config SMP
 
          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
        bool "Support sparse irq numbering"
        depends on PCI_MSI || HT_IRQ
@@ -1828,6 +1842,7 @@ config DMAR_FLOPPY_WA
 config INTR_REMAP
        bool "Support for Interrupt Remapping (EXPERIMENTAL)"
        depends on X86_64 && X86_IO_APIC && PCI_MSI && ACPI && EXPERIMENTAL
+       select X86_X2APIC
        ---help---
          Supports Interrupt remapping for IO-APIC and MSI devices.
          To use x2apic mode in the CPU's which support x2APIC enhancements or
index fba49f66228f740f7bc328fca85ee853f23bae66..dc1db99cd40e928c195b07736de40269b74ab1ee 100644 (file)
@@ -112,7 +112,7 @@ static inline u32 native_apic_msr_read(u32 reg)
        return low;
 }
 
-#ifndef CONFIG_X86_32
+#ifdef CONFIG_X86_X2APIC
 extern int x2apic;
 extern void check_x2apic(void);
 extern void enable_x2apic(void);
@@ -131,7 +131,19 @@ static inline int x2apic_enabled(void)
        return 0;
 }
 #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
 
 struct apic_ops {
@@ -177,7 +189,7 @@ static inline u32 safe_apic_wait_icr_idle(void)
 
 extern int get_physical_broadcast(void);
 
-#ifdef CONFIG_X86_64
+#ifdef CONFIG_X86_X2APIC
 static inline void ack_x2APIC_irq(void)
 {
        /* Docs say use 0 for future compatibility */
index 24f357e7557a186f750699965f39f8e22dce7140..1cefd218f764093d46d8200b360b915c548c76c6 100644 (file)
@@ -117,8 +117,8 @@ obj-$(CONFIG_SWIOTLB)                       += pci-swiotlb_64.o # NB rename without _64
 # 64 bit specific files
 ifeq ($(CONFIG_X86_64),y)
         obj-y                          += genapic_64.o genapic_flat_64.o
-        obj-y                          += genx2apic_cluster.o
-        obj-y                          += genx2apic_phys.o
+        obj-$(CONFIG_X86_X2APIC)       += genx2apic_cluster.o
+        obj-$(CONFIG_X86_X2APIC)       += genx2apic_phys.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_PM_TIMER)     += pmtimer_64.o
index a894eea9d51af37a8de42378bff49659691c75ca..004aa1c31e4f42e20ee4b7a45ee47d3a8b02836f 100644 (file)
@@ -112,11 +112,7 @@ static __init int setup_apicpmtimer(char *s)
 __setup("apicpmtimer", setup_apicpmtimer);
 #endif
 
-#ifdef CONFIG_X86_64
-#define HAVE_X2APIC
-#endif
-
-#ifdef HAVE_X2APIC
+#ifdef CONFIG_X86_X2APIC
 int x2apic;
 /* x2apic enabled before OS handover */
 static int x2apic_preenabled;
@@ -269,7 +265,7 @@ static struct apic_ops xapic_ops = {
 struct apic_ops __read_mostly *apic_ops = &xapic_ops;
 EXPORT_SYMBOL_GPL(apic_ops);
 
-#ifdef HAVE_X2APIC
+#ifdef CONFIG_X86_X2APIC
 static void x2apic_wait_icr_idle(void)
 {
        /* no need to wait for icr idle in x2apic */
@@ -1320,11 +1316,14 @@ void __cpuinit end_local_APIC_setup(void)
        apic_pm_activate();
 }
 
-#ifdef HAVE_X2APIC
+#ifdef CONFIG_X86_X2APIC
 void check_x2apic(void)
 {
        int msr, msr2;
 
+       if (!cpu_has_x2apic)
+               return;
+
        rdmsr(MSR_IA32_APICBASE, msr, msr2);
 
        if (msr & X2APIC_ENABLE) {
@@ -1338,6 +1337,9 @@ void enable_x2apic(void)
 {
        int msr, msr2;
 
+       if (!x2apic)
+               return;
+
        rdmsr(MSR_IA32_APICBASE, msr, msr2);
        if (!(msr & X2APIC_ENABLE)) {
                pr_info("Enabling x2apic\n");
@@ -1439,7 +1441,7 @@ end:
 
        return;
 }
-#endif /* HAVE_X2APIC */
+#endif /* CONFIG_X86_X2APIC */
 
 #ifdef CONFIG_X86_64
 /*
@@ -1570,7 +1572,7 @@ void __init early_init_lapic_mapping(void)
  */
 void __init init_apic_mappings(void)
 {
-#ifdef HAVE_X2APIC
+#ifdef CONFIG_X86_X2APIC
        if (x2apic) {
                boot_cpu_physical_apicid = read_apic_id();
                return;
@@ -1634,9 +1636,7 @@ int __init APIC_init_uniprocessor(void)
        }
 #endif
 
-#ifdef HAVE_X2APIC
        enable_IR_x2apic();
-#endif
 #ifdef CONFIG_X86_64
        default_setup_apic_routing();
 #endif
@@ -2021,7 +2021,7 @@ static int lapic_resume(struct sys_device *dev)
 
        local_irq_save(flags);
 
-#ifdef HAVE_X2APIC
+#ifdef CONFIG_X86_X2APIC
        if (x2apic)
                enable_x2apic();
        else
index 4db150ed446d1c64523ae25160c9267db5b1cdda..4b5d13e472d67f5368358782b697f3991d71b936 100644 (file)
@@ -1051,7 +1051,7 @@ void __cpuinit cpu_init(void)
        barrier();
 
        check_efer();
-       if (cpu != 0 && x2apic)
+       if (cpu != 0)
                enable_x2apic();
 
        /*
index 820dea5d0ebeaef6afc0adf794af4c363f7a8570..cdc4772d9c874fadb29ac4a31c78c53586180158 100644 (file)
@@ -35,8 +35,10 @@ static struct genapic *apic_probe[] __initdata = {
 #ifdef CONFIG_X86_UV
        &apic_x2apic_uv_x,
 #endif
+#ifdef CONFIG_X86_X2APIC
        &apic_x2apic_phys,
        &apic_x2apic_cluster,
+#endif
        &apic_physflat,
        NULL,
 };
@@ -46,10 +48,12 @@ static struct genapic *apic_probe[] __initdata = {
  */
 void __init default_setup_apic_routing(void)
 {
+#ifdef CONFIG_X86_X2APIC
        if (apic == &apic_x2apic_phys || apic == &apic_x2apic_cluster) {
                if (!intr_remapping_enabled)
                        apic = &apic_flat;
        }
+#endif
 
        if (apic == &apic_flat) {
                if (max_physical_apicid >= 8)
index 8fce6c7145146f86f4d05b78c39434d154b0c667..43d964411c0de4587b3a8ed8b0179be94b575ebe 100644 (file)
@@ -836,8 +836,7 @@ void __init setup_arch(char **cmdline_p)
 #else
        num_physpages = max_pfn;
 
-       if (cpu_has_x2apic)
-               check_x2apic();
+       check_x2apic();
 
        /* How many end-of-memory variables you have, grandma! */
        /* need this before calling reserve_initrd */
index 10834954e3014595fa6cf0087740b755fad66c32..b5f2b698973f7de079b23f51552c9bd446f0d5dd 100644 (file)
@@ -1128,8 +1128,8 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus)
        current_thread_info()->cpu = 0;  /* needed? */
        set_cpu_sibling_map(0);
 
-#ifdef CONFIG_X86_64
        enable_IR_x2apic();
+#ifdef CONFIG_X86_64
        default_setup_apic_routing();
 #endif