From: Keir Fraser Date: Thu, 9 Dec 2010 19:19:34 +0000 (+0000) Subject: x86: x2apic: Large cleanup X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=56343b7be11ab9e3aae9a6cbfc0af7a388b3694f;p=xen.git x86: x2apic: Large cleanup Signed-off-by: Keir Fraser --- diff --git a/xen/arch/x86/apic.c b/xen/arch/x86/apic.c index 8329da1930..4b122ed45e 100644 --- a/xen/arch/x86/apic.c +++ b/xen/arch/x86/apic.c @@ -76,12 +76,12 @@ static int enable_local_apic __initdata = 0; /* -1=force-disable, +1=force-enabl */ 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 * is no hardware IRQ pin equivalent for them, they are triggered @@ -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() ) - return; - - rdmsrl(MSR_IA32_APICBASE, msr_content); - if ( msr_content & MSR_IA32_APICBASE_EXTD ) + if ( smp_processor_id() != 0 ) { - printk("x2APIC mode is already enabled by BIOS.\n"); - x2apic_preenabled = 1; - x2apic_enabled = 1; + if ( x2apic_enabled ) + __enable_x2apic(); + return; } -} -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 ( !cpu_has_x2apic ) + return; - if ( x2apic_preenabled ) + /* Check whether x2apic mode was already enabled by the BIOS. */ + rdmsrl(MSR_IA32_APICBASE, msr_content); + if ( msr_content & MSR_IA32_APICBASE_EXTD ) { /* * 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"); + + printk("x2APIC mode is already enabled by BIOS.\n"); + x2apic_enabled = 1; } - x2apic_genapic = apic_x2apic_probe(); - if ( x2apic_genapic ) - genapic = x2apic_genapic; - else + if ( !opt_x2apic ) { - if ( x2apic_cmdline_disable() ) + 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; } + panic("x2APIC: already enabled by BIOS, but " + "iommu_supports_eim failed!\n"); } - ioapic_entries = alloc_ioapic_entries(); - if ( !ioapic_entries ) + 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: @@ -1058,24 +1046,6 @@ out: 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) { unsigned long apic_phys; diff --git a/xen/arch/x86/cpu/common.c b/xen/arch/x86/cpu/common.c index f9a40991e9..5251113b4c 100644 --- a/xen/arch/x86/cpu/common.c +++ b/xen/arch/x86/cpu/common.c @@ -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 --git a/xen/arch/x86/genapic/x2apic.c b/xen/arch/x86/genapic/x2apic.c index 0d36d34948..91daaa3bf4 100644 --- a/xen/arch/x86/genapic/x2apic.c +++ b/xen/arch/x86/genapic/x2apic.c @@ -27,84 +27,39 @@ #include #include -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) -{ - return (x2apic == 0); -} - -static int probe_x2apic_phys(void) +static void init_apic_ldr_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 --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c index 42e063aa79..053b9c27ed 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -1158,9 +1158,6 @@ void __init __start_xen(unsigned long mbi_p) 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 mbi_p) init_cpu_to_node(); - if ( x2apic_is_available() ) - enable_x2apic(); + x2apic_setup(); init_IRQ(); diff --git a/xen/arch/x86/smpboot.c b/xen/arch/x86/smpboot.c index 7f5c63339c..40b60ae746 100644 --- a/xen/arch/x86/smpboot.c +++ b/xen/arch/x86/smpboot.c @@ -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 --git a/xen/drivers/passthrough/vtd/intremap.c b/xen/drivers/passthrough/vtd/intremap.c index bc41f888d3..996d9bc21b 100644 --- a/xen/drivers/passthrough/vtd/intremap.c +++ b/xen/drivers/passthrough/vtd/intremap.c @@ -131,15 +131,10 @@ 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++ ) if ( !ioapic_to_drhd(IO_APIC_ID(apic)) ) diff --git a/xen/include/asm-x86/apic.h b/xen/include/asm-x86/apic.h index e867464332..4a825a8793 100644 --- a/xen/include/asm-x86/apic.h +++ b/xen/include/asm-x86/apic.h @@ -25,21 +25,8 @@ extern int apic_verbosity; 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 --git a/xen/include/asm-x86/genapic.h b/xen/include/asm-x86/genapic.h index 2060bab48b..81c86329b2 100644 --- a/xen/include/asm-x86/genapic.h +++ b/xen/include/asm-x86/genapic.h @@ -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_cpumask_flat(int cpu); .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_cpumask_phys(int cpu); .send_IPI_mask = send_IPI_mask_phys, \ .send_IPI_self = send_IPI_self_phys +void send_IPI_self_x2apic(int vector); + #endif