diff options
-rw-r--r-- | docs/misc/xen-command-line.markdown | 7 | ||||
-rw-r--r-- | xen/arch/x86/genapic/bigsmp.c | 9 | ||||
-rw-r--r-- | xen/arch/x86/genapic/x2apic.c | 9 | ||||
-rw-r--r-- | xen/arch/x86/hpet.c | 3 | ||||
-rw-r--r-- | xen/arch/x86/msi.c | 18 | ||||
-rw-r--r-- | xen/drivers/passthrough/amd/iommu_acpi.c | 3 | ||||
-rw-r--r-- | xen/drivers/passthrough/vtd/iommu.c | 6 |
7 files changed, 49 insertions, 6 deletions
diff --git a/docs/misc/xen-command-line.markdown b/docs/misc/xen-command-line.markdown index 81b86613dc..708ffc2d5e 100644 --- a/docs/misc/xen-command-line.markdown +++ b/docs/misc/xen-command-line.markdown @@ -639,6 +639,13 @@ limit is ignored by Xen. Specify if the MMConfig space should be enabled. +### msi +> `= <boolean>` + +> Default: `true` + +Force Xen to (not) use PCI-MSI, even if ACPI FADT says otherwise. + ### mwait-idle > `= <boolean>` diff --git a/xen/arch/x86/genapic/bigsmp.c b/xen/arch/x86/genapic/bigsmp.c index 62d255eb65..96b23d6a2b 100644 --- a/xen/arch/x86/genapic/bigsmp.c +++ b/xen/arch/x86/genapic/bigsmp.c @@ -40,7 +40,14 @@ static struct dmi_system_id __initdata bigsmp_dmi_table[] = { static __init int probe_bigsmp(void) { - if (!def_to_bigsmp) + /* + * We don't implement cluster mode, so force use of + * physical mode in both cases. + */ + if (acpi_gbl_FADT.flags & + (ACPI_FADT_APIC_CLUSTER | ACPI_FADT_APIC_PHYSICAL)) + def_to_bigsmp = 1; + else if (!def_to_bigsmp) dmi_check_system(bigsmp_dmi_table); return def_to_bigsmp; } diff --git a/xen/arch/x86/genapic/x2apic.c b/xen/arch/x86/genapic/x2apic.c index 3616011d37..d4c91495ac 100644 --- a/xen/arch/x86/genapic/x2apic.c +++ b/xen/arch/x86/genapic/x2apic.c @@ -30,9 +30,6 @@ #include <xen/smp.h> #include <asm/mach-default/mach_mpparse.h> -static bool_t __initdata x2apic_phys; /* By default we use logical cluster mode. */ -boolean_param("x2apic_phys", x2apic_phys); - static DEFINE_PER_CPU_READ_MOSTLY(u32, cpu_2_logical_apicid); static DEFINE_PER_CPU_READ_MOSTLY(cpumask_t *, cluster_cpus); static cpumask_t *cluster_cpus_spare; @@ -223,8 +220,14 @@ static struct notifier_block x2apic_cpu_nfb = { .notifier_call = update_clusterinfo }; +static s8 __initdata x2apic_phys = -1; /* By default we use logical cluster mode. */ +boolean_param("x2apic_phys", x2apic_phys); + const struct genapic *__init apic_x2apic_probe(void) { + if ( x2apic_phys < 0 ) + x2apic_phys = !!(acpi_gbl_FADT.flags & ACPI_FADT_APIC_PHYSICAL); + if ( x2apic_phys ) return &apic_x2apic_phys; diff --git a/xen/arch/x86/hpet.c b/xen/arch/x86/hpet.c index fb875523f0..02926b5319 100644 --- a/xen/arch/x86/hpet.c +++ b/xen/arch/x86/hpet.c @@ -381,6 +381,9 @@ static void __init hpet_fsb_cap_lookup(void) u32 id; unsigned int i, num_chs; + if ( unlikely(acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_MSI) ) + return; + id = hpet_read32(HPET_ID); num_chs = ((id & HPET_ID_NUMBER) >> HPET_ID_NUMBER_SHIFT); diff --git a/xen/arch/x86/msi.c b/xen/arch/x86/msi.c index 0e6e50bce9..09e081f79b 100644 --- a/xen/arch/x86/msi.c +++ b/xen/arch/x86/msi.c @@ -32,6 +32,9 @@ #include <xen/iommu.h> #include <xsm/xsm.h> +static s8 __read_mostly use_msi = -1; +boolean_param("msi", use_msi); + /* bitmap indicate which fixed map is free */ static DEFINE_SPINLOCK(msix_fixmap_lock); static DECLARE_BITMAP(msix_fixmap_pages, FIX_MSIX_MAX_PAGES); @@ -968,6 +971,9 @@ int pci_enable_msi(struct msi_info *msi, struct msi_desc **desc) { ASSERT(spin_is_locked(&pcidevs_lock)); + if ( !use_msi ) + return -EPERM; + return msi->table_base ? __pci_enable_msix(msi, desc) : __pci_enable_msi(msi, desc); } @@ -1013,7 +1019,10 @@ int pci_restore_msi_state(struct pci_dev *pdev) ASSERT(spin_is_locked(&pcidevs_lock)); - if (!pdev) + if ( !use_msi ) + return -EOPNOTSUPP; + + if ( !pdev ) return -EINVAL; ret = xsm_resource_setup_pci(XSM_PRIV, (pdev->seg << 16) | (pdev->bus << 8) | pdev->devfn); @@ -1072,7 +1081,7 @@ unsigned int pci_msix_get_table_len(struct pci_dev *pdev) func = PCI_FUNC(pdev->devfn); pos = pci_find_cap_offset(seg, bus, slot, func, PCI_CAP_ID_MSIX); - if ( !pos ) + if ( !pos || !use_msi ) return 0; control = pci_conf_read16(seg, bus, slot, func, msix_control_reg(pos)); @@ -1109,6 +1118,11 @@ static struct notifier_block msi_cpu_nfb = { void __init early_msi_init(void) { + if ( use_msi < 0 ) + use_msi = !(acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_MSI); + if ( !use_msi ) + return; + register_cpu_notifier(&msi_cpu_nfb); if ( msi_cpu_callback(&msi_cpu_nfb, CPU_UP_PREPARE, NULL) & NOTIFY_STOP_MASK ) diff --git a/xen/drivers/passthrough/amd/iommu_acpi.c b/xen/drivers/passthrough/amd/iommu_acpi.c index 40550c4a11..679c2a4137 100644 --- a/xen/drivers/passthrough/amd/iommu_acpi.c +++ b/xen/drivers/passthrough/amd/iommu_acpi.c @@ -1087,5 +1087,8 @@ int __init amd_iommu_get_ivrs_dev_entries(void) int __init amd_iommu_update_ivrs_mapping_acpi(void) { + if ( unlikely(acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_MSI) ) + return -EPERM; + return acpi_table_parse(ACPI_SIG_IVRS, parse_ivrs_table); } diff --git a/xen/drivers/passthrough/vtd/iommu.c b/xen/drivers/passthrough/vtd/iommu.c index 284e9f0f02..b6ea6850c5 100644 --- a/xen/drivers/passthrough/vtd/iommu.c +++ b/xen/drivers/passthrough/vtd/iommu.c @@ -2115,6 +2115,12 @@ int __init intel_vtd_setup(void) goto error; } + if ( unlikely(acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_MSI) ) + { + ret = -EPERM; + goto error; + } + platform_quirks_init(); /* We enable the following features only if they are supported by all VT-d |