honor ACPI v4 FADT flags
authorJan Beulich <jbeulich@suse.com>
Fri, 22 Feb 2013 10:56:54 +0000 (11:56 +0100)
committerJan Beulich <jbeulich@suse.com>
Fri, 22 Feb 2013 10:56:54 +0000 (11:56 +0100)
- force use of physical APIC mode if indicated so (as we don't support
  xAPIC cluster mode, the respective flag is taken to force physical
  mode too)
- don't use MSI if indicated so (implies no IOMMU)

Both can be overridden on the command line, for the MSI case this at
once adds a new command line option allowing to turn off PCI MSI (IOMMU
and HPET are unaffected by this).

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Keir Fraser <keir@xen.org>
docs/misc/xen-command-line.markdown
xen/arch/x86/genapic/bigsmp.c
xen/arch/x86/genapic/x2apic.c
xen/arch/x86/hpet.c
xen/arch/x86/msi.c
xen/drivers/passthrough/amd/iommu_acpi.c
xen/drivers/passthrough/vtd/iommu.c

index 81b86613dcae427a8469ab6bb2b2805022989ad2..708ffc2d5e01e68ee0dcbcb63186559c5e155556 100644 (file)
@@ -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>`
 
index 62d255eb651dfd8b1da9618c496c51afd68f9516..96b23d6a2bfdd22104e4bed73cb77ccda2b7fe52 100644 (file)
@@ -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;
 } 
index 3616011d37e0b78d5202ad5bd9013cd75398640f..d4c91495ace894a459fbb4801e60ce99fd4049d6 100644 (file)
@@ -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;
 
index fb875523f0419e94d52a5f23a13aef55a50d3a03..02926b53199c5c1bcfda7311c4f676ed4284695e 100644 (file)
@@ -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);
index 0e6e50bce916c12caea989644149dc44bfe02631..09e081f79b0603540cecde58359cf5ded6668ce1 100644 (file)
@@ -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 )
index 40550c4a1191c5ac2bed58a4d31d8ac8d726492b..679c2a4137b21726d2578da68d9397d8805cd41f 100644 (file)
@@ -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);
 }
index 284e9f0f0263d96b2216222d52203978d0f44dc4..b6ea6850c56d7e93252c2d4c1e73e468499e7a18 100644 (file)
@@ -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