[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] x86: x2apic: Large cleanup



# HG changeset patch
# User Keir Fraser <keir@xxxxxxx>
# Date 1291922374 0
# Node ID d9fc83a64a82624e24876250dd88b2cd9528d266
# Parent  49d2aa5cee4ecc2411d8d638e4ee32c10e9b2761
x86: x2apic: Large cleanup

Signed-off-by: Keir Fraser <keir@xxxxxxx>
---
 xen/arch/x86/apic.c                    |  116 ++++++++++++---------------------
 xen/arch/x86/cpu/common.c              |    9 +-
 xen/arch/x86/genapic/x2apic.c          |   98 +++++++++++----------------
 xen/arch/x86/setup.c                   |    6 -
 xen/arch/x86/smpboot.c                 |    3 
 xen/drivers/passthrough/vtd/intremap.c |    9 --
 xen/include/asm-x86/apic.h             |   17 ----
 xen/include/asm-x86/genapic.h          |   37 ----------
 8 files changed, 99 insertions(+), 196 deletions(-)

diff -r 49d2aa5cee4e -r d9fc83a64a82 xen/arch/x86/apic.c
--- a/xen/arch/x86/apic.c       Thu Dec 09 16:17:33 2010 +0000
+++ b/xen/arch/x86/apic.c       Thu Dec 09 19:19:34 2010 +0000
@@ -76,11 +76,11 @@ static int enable_local_apic __initdata 
  */
 int apic_verbosity;
 
+static int opt_x2apic = 1;
+boolean_param("x2apic", opt_x2apic);
+
 int x2apic_enabled __read_mostly = 0;
 int directed_eoi_enabled __read_mostly = 0;
-
-/* x2APIC is enabled in BIOS */
-static int x2apic_preenabled;
 
 /*
  * The following vectors are part of the Linux architecture, there
@@ -953,30 +953,24 @@ no_apic:
     return -1;
 }
 
-void check_x2apic_preenabled(void)
-{
+void x2apic_setup(void)
+{
+    struct IO_APIC_route_entry **ioapic_entries = NULL;
     uint64_t msr_content;
 
-    if ( !x2apic_is_available() )
+    if ( smp_processor_id() != 0 )
+    {
+        if ( x2apic_enabled )
+            __enable_x2apic();
         return;
-
+    }
+
+    if ( !cpu_has_x2apic )
+        return;
+
+    /* Check whether x2apic mode was already enabled by the BIOS. */
     rdmsrl(MSR_IA32_APICBASE, msr_content);
     if ( msr_content & MSR_IA32_APICBASE_EXTD )
-    {
-        printk("x2APIC mode is already enabled by BIOS.\n");
-        x2apic_preenabled = 1;
-        x2apic_enabled = 1;
-    }
-}
-
-static void enable_bsp_x2apic(void)
-{
-    struct IO_APIC_route_entry **ioapic_entries = NULL;
-    const struct genapic *x2apic_genapic = NULL;
-
-    ASSERT(smp_processor_id() == 0);
-
-    if ( x2apic_preenabled )
     {
         /*
          * Interrupt remapping should be also enabled by BIOS when
@@ -986,39 +980,33 @@ static void enable_bsp_x2apic(void)
         if ( !intremap_enabled() )
             panic("Interrupt remapping is not enabled by BIOS while "
                   "x2APIC is already enabled by BIOS!\n");
-    }
-
-    x2apic_genapic = apic_x2apic_probe();
-    if ( x2apic_genapic )
-        genapic = x2apic_genapic;
-    else
-    {
-        if ( x2apic_cmdline_disable() )
+
+        printk("x2APIC mode is already enabled by BIOS.\n");
+        x2apic_enabled = 1;
+    }
+
+    if ( !opt_x2apic )
+    {
+        if ( !x2apic_enabled )
         {
-            if ( x2apic_preenabled )
-            {
-                /* Ignore x2apic=0, and set default x2apic mode */
-                genapic = &apic_x2apic_cluster;
-                printk("x2APIC: already enabled by BIOS, ignore x2apic=0.\n");
-            }
-            else
-            {
-                printk("Not enable x2APIC due to x2apic=0 is set.\n");
-                return;
-            }
-        }
-        else
+            printk("Not enabling x2APIC: disabled by cmdline.\n");
+            return;
+        }        
+        printk("x2APIC: Already enabled by BIOS: Ignoring cmdline disable.\n");
+    }
+
+    if ( !iommu_supports_eim() )
+    {
+        if ( !x2apic_enabled )
         {
-            if ( x2apic_preenabled )
-                panic("x2APIC: already enabled by BIOS, but "
-                      "iommu_supports_eim failed!\n");
-            printk("Not enabling x2APIC: depends oniommu_supports_eim\n");
+            printk("Not enabling x2APIC: depends on iommu_supports_eim.\n");
             return;
         }
-    }
-
-    ioapic_entries = alloc_ioapic_entries();
-    if ( !ioapic_entries )
+        panic("x2APIC: already enabled by BIOS, but "
+              "iommu_supports_eim failed!\n");
+    }
+
+    if ( (ioapic_entries = alloc_ioapic_entries()) == NULL )
     {
         printk("Allocate ioapic_entries failed\n");
         goto out;
@@ -1040,13 +1028,13 @@ static void enable_bsp_x2apic(void)
         goto restore_out;
     }
 
-    x2apic_enabled = 1;
+    genapic = apic_x2apic_probe();
     printk("Switched to APIC driver %s.\n", genapic->name);
 
-    if ( !x2apic_preenabled )
-    {
+    if ( !x2apic_enabled )
+    {
+        x2apic_enabled = 1;
         __enable_x2apic();
-        printk("x2APIC mode enabled.\n");
     }
 
 restore_out:
@@ -1056,24 +1044,6 @@ out:
 out:
     if ( ioapic_entries )
         free_ioapic_entries(ioapic_entries);
-}
-
-static void enable_ap_x2apic(void)
-{
-    ASSERT(smp_processor_id() != 0);
-
-    /* APs only enable x2apic when BSP did so. */
-    BUG_ON(!x2apic_enabled);
-
-    __enable_x2apic();
-}
-
-void enable_x2apic(void)
-{
-    if ( smp_processor_id() == 0 )
-        enable_bsp_x2apic();
-    else
-        enable_ap_x2apic();
 }
 
 void __init init_apic_mappings(void)
diff -r 49d2aa5cee4e -r d9fc83a64a82 xen/arch/x86/cpu/common.c
--- a/xen/arch/x86/cpu/common.c Thu Dec 09 16:17:33 2010 +0000
+++ b/xen/arch/x86/cpu/common.c Thu Dec 09 19:19:34 2010 +0000
@@ -252,8 +252,8 @@ static void __init early_cpu_detect(void
 
        c->x86 = 4;
        if (c->cpuid_level >= 0x00000001) {
-               u32 junk, tfms, cap0, misc;
-               cpuid(0x00000001, &tfms, &misc, &junk, &cap0);
+               u32 cap4, tfms, cap0, misc;
+               cpuid(0x00000001, &tfms, &misc, &cap4, &cap0);
                c->x86 = (tfms >> 8) & 15;
                c->x86_model = (tfms >> 4) & 15;
                if (c->x86 == 0xf)
@@ -262,9 +262,12 @@ static void __init early_cpu_detect(void
                        c->x86_model += ((tfms >> 16) & 0xF) << 4;
                c->x86_mask = tfms & 15;
                cap0 &= ~cleared_caps[0];
+               cap4 &= ~cleared_caps[4];
                if (cap0 & (1<<19))
                        c->x86_cache_alignment = ((misc >> 8) & 0xff) * 8;
-               c->x86_capability[0] = cap0; /* Added for Xen bootstrap */
+               /* Leaf 0x1 capabilities filled in early for Xen. */
+               c->x86_capability[0] = cap0;
+               c->x86_capability[4] = cap4;
        }
 }
 
diff -r 49d2aa5cee4e -r d9fc83a64a82 xen/arch/x86/genapic/x2apic.c
--- a/xen/arch/x86/genapic/x2apic.c     Thu Dec 09 16:17:33 2010 +0000
+++ b/xen/arch/x86/genapic/x2apic.c     Thu Dec 09 19:19:34 2010 +0000
@@ -27,84 +27,39 @@
 #include <xen/smp.h>
 #include <asm/mach-default/mach_mpparse.h>
 
-static int x2apic = 1;
-boolean_param("x2apic", x2apic);
-
-static int  x2apic_phys; /* By default we use logical cluster mode. */
+static int x2apic_phys; /* By default we use logical cluster mode. */
 boolean_param("x2apic_phys", x2apic_phys);
 
-int x2apic_cmdline_disable(void)
+static void init_apic_ldr_x2apic_phys(void)
 {
-    return (x2apic == 0);
 }
 
-static int probe_x2apic_phys(void)
-{
-    return x2apic && x2apic_phys && x2apic_is_available() &&
-        iommu_supports_eim();
-}
-
-static int probe_x2apic_cluster(void)
-{
-    return x2apic && !x2apic_phys && x2apic_is_available() &&
-        iommu_supports_eim();
-}
-
-const struct genapic apic_x2apic_phys = {
-    APIC_INIT("x2apic_phys", probe_x2apic_phys),
-    GENAPIC_X2APIC_PHYS
-};
-
-const struct genapic apic_x2apic_cluster = {
-    APIC_INIT("x2apic_cluster", probe_x2apic_cluster),
-    GENAPIC_X2APIC_CLUSTER
-};
-
-const struct genapic *apic_x2apic_probe(void)
-{
-    if ( !x2apic || !x2apic_is_available() )
-        return NULL;
-
-    if ( !iommu_supports_eim() )
-        return NULL;
-
-    if ( x2apic_phys )
-        return &apic_x2apic_phys;
-    else
-        return &apic_x2apic_cluster;
-}
-
-void init_apic_ldr_x2apic_phys(void)
-{
-    return;
-}
-
-void init_apic_ldr_x2apic_cluster(void)
+static void init_apic_ldr_x2apic_cluster(void)
 {
     int cpu = smp_processor_id();
     cpu_2_logical_apicid[cpu] = apic_read(APIC_LDR);
 }
-void clustered_apic_check_x2apic(void)
+
+static void clustered_apic_check_x2apic(void)
 {
-    return;
 }
 
-const cpumask_t *target_cpus_x2apic(void)
+static const cpumask_t *target_cpus_x2apic(void)
 {
     return &cpu_online_map;
 }
 
-const cpumask_t *vector_allocation_cpumask_x2apic(int cpu)
+static const cpumask_t *vector_allocation_cpumask_x2apic(int cpu)
 {
     return cpumask_of(cpu);
 }
 
-unsigned int cpu_mask_to_apicid_x2apic_phys(const cpumask_t *cpumask)
+static unsigned int cpu_mask_to_apicid_x2apic_phys(const cpumask_t *cpumask)
 {
     return cpu_physical_id(cpumask_first(cpumask));
 }
 
-unsigned int cpu_mask_to_apicid_x2apic_cluster(const cpumask_t *cpumask)
+static unsigned int cpu_mask_to_apicid_x2apic_cluster(const cpumask_t *cpumask)
 {
     return cpu_2_logical_apicid[cpumask_first(cpumask)];
 }
@@ -143,12 +98,43 @@ static void __send_IPI_mask_x2apic(
     local_irq_restore(flags);
 }
 
-void send_IPI_mask_x2apic_phys(const cpumask_t *cpumask, int vector)
+static void send_IPI_mask_x2apic_phys(const cpumask_t *cpumask, int vector)
 {
     __send_IPI_mask_x2apic(cpumask, vector, APIC_DEST_PHYSICAL);
 }
 
-void send_IPI_mask_x2apic_cluster(const cpumask_t *cpumask, int vector)
+static void send_IPI_mask_x2apic_cluster(const cpumask_t *cpumask, int vector)
 {
     __send_IPI_mask_x2apic(cpumask, vector, APIC_DEST_LOGICAL);
 }
+
+static const struct genapic apic_x2apic_phys = {
+    APIC_INIT("x2apic_phys", NULL),
+    .int_delivery_mode = dest_Fixed,
+    .int_dest_mode = 0 /* physical delivery */,
+    .init_apic_ldr = init_apic_ldr_x2apic_phys,
+    .clustered_apic_check = clustered_apic_check_x2apic,
+    .target_cpus = target_cpus_x2apic,
+    .vector_allocation_cpumask = vector_allocation_cpumask_x2apic,
+    .cpu_mask_to_apicid = cpu_mask_to_apicid_x2apic_phys,
+    .send_IPI_mask = send_IPI_mask_x2apic_phys,
+    .send_IPI_self = send_IPI_self_x2apic
+};
+
+static const struct genapic apic_x2apic_cluster = {
+    APIC_INIT("x2apic_cluster", NULL),
+    .int_delivery_mode = dest_LowestPrio,
+    .int_dest_mode = 1 /* logical delivery */,
+    .init_apic_ldr = init_apic_ldr_x2apic_cluster,
+    .clustered_apic_check = clustered_apic_check_x2apic,
+    .target_cpus = target_cpus_x2apic,
+    .vector_allocation_cpumask = vector_allocation_cpumask_x2apic,
+    .cpu_mask_to_apicid = cpu_mask_to_apicid_x2apic_cluster,
+    .send_IPI_mask = send_IPI_mask_x2apic_cluster,
+    .send_IPI_self = send_IPI_self_x2apic
+};
+
+const struct genapic *apic_x2apic_probe(void)
+{
+    return x2apic_phys ? &apic_x2apic_phys : &apic_x2apic_cluster;
+}
diff -r 49d2aa5cee4e -r d9fc83a64a82 xen/arch/x86/setup.c
--- a/xen/arch/x86/setup.c      Thu Dec 09 16:17:33 2010 +0000
+++ b/xen/arch/x86/setup.c      Thu Dec 09 19:19:34 2010 +0000
@@ -1158,9 +1158,6 @@ void __init __start_xen(unsigned long mb
 
     tboot_probe();
 
-    /* Check if x2APIC is already enabled in BIOS */
-    check_x2apic_preenabled();
-
     /* Unmap the first page of CPU0's stack. */
     memguard_guard_stack(cpu0_stack);
 
@@ -1193,8 +1190,7 @@ void __init __start_xen(unsigned long mb
 
     init_cpu_to_node();
 
-    if ( x2apic_is_available() )
-        enable_x2apic();
+    x2apic_setup();
 
     init_IRQ();
 
diff -r 49d2aa5cee4e -r d9fc83a64a82 xen/arch/x86/smpboot.c
--- a/xen/arch/x86/smpboot.c    Thu Dec 09 16:17:33 2010 +0000
+++ b/xen/arch/x86/smpboot.c    Thu Dec 09 19:19:34 2010 +0000
@@ -194,8 +194,7 @@ void smp_callin(void)
      * update until we finish. We are free to set up this CPU: first the APIC.
      */
     Dprintk("CALLIN, before setup_local_APIC().\n");
-    if ( x2apic_enabled )
-        enable_x2apic();
+    x2apic_setup();
     setup_local_APIC();
     map_cpu_to_logical_apicid();
 
diff -r 49d2aa5cee4e -r d9fc83a64a82 xen/drivers/passthrough/vtd/intremap.c
--- a/xen/drivers/passthrough/vtd/intremap.c    Thu Dec 09 16:17:33 2010 +0000
+++ b/xen/drivers/passthrough/vtd/intremap.c    Thu Dec 09 19:19:34 2010 +0000
@@ -131,14 +131,9 @@ int iommu_supports_eim(void)
     struct acpi_drhd_unit *drhd;
     int apic;
 
-    if ( !iommu_enabled || !iommu_qinval || !iommu_intremap )
+    if ( !iommu_enabled || !iommu_qinval || !iommu_intremap ||
+         list_empty(&acpi_drhd_units) )
         return 0;
-
-    if ( list_empty(&acpi_drhd_units) )
-    {
-        dprintk(XENLOG_WARNING VTDPREFIX, "VT-d is not supported\n");
-        return 0;
-    }
 
     /* We MUST have a DRHD unit for each IOAPIC. */
     for ( apic = 0; apic < nr_ioapics; apic++ )
diff -r 49d2aa5cee4e -r d9fc83a64a82 xen/include/asm-x86/apic.h
--- a/xen/include/asm-x86/apic.h        Thu Dec 09 16:17:33 2010 +0000
+++ b/xen/include/asm-x86/apic.h        Thu Dec 09 19:19:34 2010 +0000
@@ -25,21 +25,8 @@ extern int x2apic_enabled;
 extern int x2apic_enabled;
 extern int directed_eoi_enabled;
 
-extern void check_x2apic_preenabled(void);
-extern int x2apic_cmdline_disable(void);
-extern void enable_x2apic(void);
-
-static __inline int x2apic_is_available(void)
-{
-    unsigned int op = 1, eax, ecx;
-
-    asm ( "cpuid"
-          : "=a" (eax), "=c" (ecx)
-          : "0" (op)
-          : "bx", "dx" );
-
-    return (ecx & (1U << 21));
-}
+void x2apic_setup(void);
+const struct genapic *apic_x2apic_probe(void);
 
 /*
  * Define the default level of output to be very little
diff -r 49d2aa5cee4e -r d9fc83a64a82 xen/include/asm-x86/genapic.h
--- a/xen/include/asm-x86/genapic.h     Thu Dec 09 16:17:33 2010 +0000
+++ b/xen/include/asm-x86/genapic.h     Thu Dec 09 19:19:34 2010 +0000
@@ -49,8 +49,6 @@ struct genapic {
        APICFUNC(acpi_madt_oem_check)
 
 extern const struct genapic *genapic;
-extern const struct genapic apic_x2apic_phys;
-extern const struct genapic apic_x2apic_cluster;
 
 void init_apic_ldr_flat(void);
 void clustered_apic_check_flat(void);
@@ -70,39 +68,6 @@ const cpumask_t *vector_allocation_cpuma
        .send_IPI_mask = send_IPI_mask_flat, \
        .send_IPI_self = send_IPI_self_flat
 
-const struct genapic *apic_x2apic_probe(void);
-void init_apic_ldr_x2apic_phys(void);
-void init_apic_ldr_x2apic_cluster(void);
-void clustered_apic_check_x2apic(void);
-const cpumask_t *target_cpus_x2apic(void);
-unsigned int cpu_mask_to_apicid_x2apic_phys(const cpumask_t *cpumask);
-unsigned int cpu_mask_to_apicid_x2apic_cluster(const cpumask_t *cpumask);
-void send_IPI_mask_x2apic_phys(const cpumask_t *mask, int vector);
-void send_IPI_mask_x2apic_cluster(const cpumask_t *mask, int vector);
-void send_IPI_self_x2apic(int vector);
-const cpumask_t *vector_allocation_cpumask_x2apic(int cpu);
-#define GENAPIC_X2APIC_PHYS \
-       .int_delivery_mode = dest_Fixed, \
-       .int_dest_mode = 0 /* physical delivery */, \
-       .init_apic_ldr = init_apic_ldr_x2apic_phys, \
-       .clustered_apic_check = clustered_apic_check_x2apic, \
-       .target_cpus = target_cpus_x2apic, \
-       .vector_allocation_cpumask = vector_allocation_cpumask_x2apic, \
-       .cpu_mask_to_apicid = cpu_mask_to_apicid_x2apic_phys, \
-       .send_IPI_mask = send_IPI_mask_x2apic_phys,       \
-       .send_IPI_self = send_IPI_self_x2apic
-
-#define GENAPIC_X2APIC_CLUSTER \
-    .int_delivery_mode = dest_LowestPrio, \
-    .int_dest_mode = 1 /* logical delivery */, \
-    .init_apic_ldr = init_apic_ldr_x2apic_cluster, \
-    .clustered_apic_check = clustered_apic_check_x2apic, \
-    .target_cpus = target_cpus_x2apic, \
-    .vector_allocation_cpumask = vector_allocation_cpumask_x2apic, \
-    .cpu_mask_to_apicid = cpu_mask_to_apicid_x2apic_cluster, \
-    .send_IPI_mask = send_IPI_mask_x2apic_cluster,       \
-    .send_IPI_self = send_IPI_self_x2apic
-
 void init_apic_ldr_phys(void);
 void clustered_apic_check_phys(void);
 const cpumask_t *target_cpus_phys(void);
@@ -121,4 +86,6 @@ const cpumask_t *vector_allocation_cpuma
        .send_IPI_mask = send_IPI_mask_phys, \
        .send_IPI_self = send_IPI_self_phys
 
+void send_IPI_self_x2apic(int vector);
+
 #endif

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.