9a05aa7fc4
22707-x2apic-preenabled-check.patch - bnc#641419 - L3: Xen: qemu-dm reports "xc_map_foreign_batch: mmap failed: Cannot allocate memory" 7434-qemu-rlimit-as.patch - Additional or upstream patches from Jan 22693-fam10-mmio-conf-base-protect.patch 22694-x86_64-no-weak.patch 22708-xenctx-misc.patch 21432-4.0-cpu-boot-failure.patch 22645-amd-flush-filter.patch qemu-fix-7433.patch - Maintain compatibility with the extid flag even though it is deprecated for both legacy and sxp config files. hv_extid_compatibility.patch - bnc#649209-improve suspend eventchn lock suspend_evtchn_lock.patch - Removed the hyper-v shim patches in favor of using the upstream version. - bnc#641419 - L3: Xen: qemu-dm reports "xc_map_foreign_batch: mmap failed: Cannot allocate memory" qemu-rlimit-as.patch - Upstream c/s 7433 to replace qemu_altgr_more.patch 7433-qemu-altgr.patch OBS-URL: https://build.opensuse.org/package/show/Virtualization/xen?expand=0&rev=90
481 lines
14 KiB
Diff
481 lines
14 KiB
Diff
# HG changeset patch
|
|
# User Keir Fraser <keir@xen.org>
|
|
# Date 1291922374 0
|
|
# Node ID d9fc83a64a82624e24876250dd88b2cd9528d266
|
|
# Parent 49d2aa5cee4ecc2411d8d638e4ee32c10e9b2761
|
|
x86: x2apic: Large cleanup
|
|
References: bnc#656369, bnc#658704
|
|
|
|
Signed-off-by: Keir Fraser <keir@xen.org>
|
|
|
|
--- a/xen/arch/x86/apic.c
|
|
+++ b/xen/arch/x86/apic.c
|
|
@@ -67,12 +67,12 @@ 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
|
|
* is no hardware IRQ pin equivalent for them, they are triggered
|
|
@@ -944,30 +944,24 @@ no_apic:
|
|
return -1;
|
|
}
|
|
|
|
-void check_x2apic_preenabled(void)
|
|
+void x2apic_setup(void)
|
|
{
|
|
+ struct IO_APIC_route_entry **ioapic_entries = NULL;
|
|
u32 lo, hi;
|
|
|
|
- if ( !x2apic_is_available() )
|
|
- return;
|
|
-
|
|
- rdmsr(MSR_IA32_APICBASE, lo, hi);
|
|
- if ( lo & 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. */
|
|
+ rdmsr(MSR_IA32_APICBASE, lo, hi);
|
|
+ if ( lo & MSR_IA32_APICBASE_EXTD )
|
|
{
|
|
/*
|
|
* Interrupt remapping should be also enabled by BIOS when
|
|
@@ -977,39 +971,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;
|
|
- }
|
|
+ printk("Not enabling x2APIC: disabled by cmdline.\n");
|
|
+ return;
|
|
}
|
|
- else
|
|
+ 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;
|
|
@@ -1031,13 +1019,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:
|
|
@@ -1049,24 +1037,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;
|
|
--- a/xen/arch/x86/cpu/common.c
|
|
+++ b/xen/arch/x86/cpu/common.c
|
|
@@ -250,8 +250,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)
|
|
@@ -260,9 +260,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;
|
|
}
|
|
}
|
|
|
|
--- a/xen/arch/x86/genapic/x2apic.c
|
|
+++ b/xen/arch/x86/genapic/x2apic.c
|
|
@@ -23,89 +23,44 @@
|
|
#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)
|
|
-{
|
|
- 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;
|
|
}
|
|
|
|
-cpumask_t target_cpus_x2apic(void)
|
|
+static cpumask_t target_cpus_x2apic(void)
|
|
{
|
|
return cpu_online_map;
|
|
}
|
|
|
|
-cpumask_t vector_allocation_domain_x2apic(int cpu)
|
|
+static cpumask_t vector_allocation_domain_x2apic(int cpu)
|
|
{
|
|
return cpumask_of_cpu(cpu);
|
|
}
|
|
|
|
-unsigned int cpu_mask_to_apicid_x2apic_phys(cpumask_t cpumask)
|
|
+static unsigned int cpu_mask_to_apicid_x2apic_phys(cpumask_t cpumask)
|
|
{
|
|
return cpu_physical_id(first_cpu(cpumask));
|
|
}
|
|
|
|
-unsigned int cpu_mask_to_apicid_x2apic_cluster(cpumask_t cpumask)
|
|
+static unsigned int cpu_mask_to_apicid_x2apic_cluster(cpumask_t cpumask)
|
|
{
|
|
return cpu_2_logical_apicid[first_cpu(cpumask)];
|
|
}
|
|
|
|
-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)
|
|
{
|
|
unsigned int cpu, cfg;
|
|
unsigned long flags;
|
|
@@ -132,7 +87,7 @@ void send_IPI_mask_x2apic_phys(const cpu
|
|
local_irq_restore(flags);
|
|
}
|
|
|
|
-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)
|
|
{
|
|
unsigned int cpu, cfg;
|
|
unsigned long flags;
|
|
@@ -148,3 +103,34 @@ void send_IPI_mask_x2apic_cluster(const
|
|
|
|
local_irq_restore(flags);
|
|
}
|
|
+
|
|
+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_domain = vector_allocation_domain_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_domain = vector_allocation_domain_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;
|
|
+}
|
|
--- a/xen/arch/x86/setup.c
|
|
+++ b/xen/arch/x86/setup.c
|
|
@@ -1006,9 +1006,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);
|
|
|
|
@@ -1039,8 +1036,7 @@ void __init __start_xen(unsigned long mb
|
|
|
|
init_apic_mappings();
|
|
|
|
- if ( x2apic_is_available() )
|
|
- enable_x2apic();
|
|
+ x2apic_setup();
|
|
|
|
percpu_free_unused_areas();
|
|
|
|
--- a/xen/arch/x86/smpboot.c
|
|
+++ b/xen/arch/x86/smpboot.c
|
|
@@ -325,8 +325,7 @@ void __devinit smp_callin(void)
|
|
*/
|
|
wait_for_init_deassert(&init_deasserted);
|
|
|
|
- if ( x2apic_enabled )
|
|
- enable_x2apic();
|
|
+ x2apic_setup();
|
|
|
|
/*
|
|
* (This works even if the APIC is not enabled.)
|
|
--- a/xen/drivers/passthrough/vtd/intremap.c
|
|
+++ b/xen/drivers/passthrough/vtd/intremap.c
|
|
@@ -129,15 +129,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)) )
|
|
--- 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
|
|
--- 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 @@ cpumask_t vector_allocation_domain_flat(
|
|
.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);
|
|
-cpumask_t target_cpus_x2apic(void);
|
|
-unsigned int cpu_mask_to_apicid_x2apic_phys(cpumask_t cpumask);
|
|
-unsigned int cpu_mask_to_apicid_x2apic_cluster(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);
|
|
-cpumask_t vector_allocation_domain_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_domain = vector_allocation_domain_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_domain = vector_allocation_domain_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);
|
|
cpumask_t target_cpus_phys(void);
|
|
@@ -121,4 +86,6 @@ cpumask_t vector_allocation_domain_phys(
|
|
.send_IPI_mask = send_IPI_mask_phys, \
|
|
.send_IPI_self = send_IPI_self_phys
|
|
|
|
+void send_IPI_self_x2apic(int vector);
|
|
+
|
|
#endif
|