# 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
|