
References: bsc#1135799

# Commit cd7680326a51d9e65ec8a966dfad4ca24cf5d4df
# Date 2019-04-08 13:05:12 +0200
# Author Jan Beulich <jbeulich@suse.com>
# Committer Jan Beulich <jbeulich@suse.com>
x86/IOMMU: abstract Intel-specific iommu_supports_eim()

Introduce a respective element in struct iommu_init_ops.

Take the liberty and also switch intel_iommu_supports_eim() to bool/
true/false, to fully match the hook's type.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>

--- a/xen/arch/x86/apic.c
+++ b/xen/arch/x86/apic.c
@@ -898,14 +898,14 @@ void __init x2apic_bsp_setup(void)
         printk("x2APIC: Already enabled by BIOS: Ignoring cmdline disable.\n");
     }
 
-    if ( !iommu_supports_eim() )
+    if ( !iommu_supports_x2apic() )
     {
         if ( !x2apic_enabled )
         {
-            printk("Not enabling x2APIC: depends on iommu_supports_eim.\n");
+            printk("Not enabling x2APIC: depends on IOMMU support\n");
             return;
         }
-        panic("x2APIC: already enabled by BIOS, but iommu_supports_eim failed\n");
+        panic("x2APIC: already enabled by BIOS, but no IOMMU support\n");
     }
 
     if ( (ioapic_entries = alloc_ioapic_entries()) == NULL )
--- a/xen/drivers/passthrough/vtd/extern.h
+++ b/xen/drivers/passthrough/vtd/extern.h
@@ -34,6 +34,8 @@ void print_iommu_regs(struct acpi_drhd_u
 void print_vtd_entries(struct iommu *iommu, int bus, int devfn, u64 gmfn);
 keyhandler_fn_t vtd_dump_iommu_info;
 
+bool intel_iommu_supports_eim(void);
+
 int enable_qinval(struct iommu *iommu);
 void disable_qinval(struct iommu *iommu);
 int enable_intremap(struct iommu *iommu, int eim);
--- a/xen/drivers/passthrough/vtd/intremap.c
+++ b/xen/drivers/passthrough/vtd/intremap.c
@@ -142,13 +142,13 @@ static void set_hpet_source_id(unsigned
     set_ire_sid(ire, SVT_VERIFY_SID_SQ, SQ_13_IGNORE_3, hpetid_to_bdf(id));
 }
 
-bool_t __init iommu_supports_eim(void)
+bool __init intel_iommu_supports_eim(void)
 {
     struct acpi_drhd_unit *drhd;
     unsigned int apic;
 
     if ( !iommu_qinval || !iommu_intremap || list_empty(&acpi_drhd_units) )
-        return 0;
+        return false;
 
     /* We MUST have a DRHD unit for each IOAPIC. */
     for ( apic = 0; apic < nr_ioapics; apic++ )
@@ -157,16 +157,16 @@ bool_t __init iommu_supports_eim(void)
             dprintk(XENLOG_WARNING VTDPREFIX,
                     "There is not a DRHD for IOAPIC %#x (id: %#x)!\n",
                     apic, IO_APIC_ID(apic));
-            return 0;
+            return false;
         }
 
     for_each_drhd_unit ( drhd )
         if ( !ecap_queued_inval(drhd->iommu->ecap) ||
              !ecap_intr_remap(drhd->iommu->ecap) ||
              !ecap_eim(drhd->iommu->ecap) )
-            return 0;
+            return false;
 
-    return 1;
+    return true;
 }
 
 /*
@@ -889,7 +889,7 @@ int iommu_enable_x2apic_IR(void)
 
     if ( system_state < SYS_STATE_active )
     {
-        if ( !iommu_supports_eim() )
+        if ( !intel_iommu_supports_eim() )
             return -EOPNOTSUPP;
 
         if ( !platform_supports_x2apic() )
--- a/xen/drivers/passthrough/vtd/iommu.c
+++ b/xen/drivers/passthrough/vtd/iommu.c
@@ -2789,6 +2789,7 @@ const struct iommu_ops __initconstrel in
 
 const struct iommu_init_ops __initconstrel intel_iommu_init_ops = {
     .setup = vtd_setup,
+    .supports_x2apic = intel_iommu_supports_eim,
 };
 
 /*
--- a/xen/include/asm-x86/iommu.h
+++ b/xen/include/asm-x86/iommu.h
@@ -66,6 +66,7 @@ static inline const struct iommu_ops *io
 
 struct iommu_init_ops {
     int (*setup)(void);
+    bool (*supports_x2apic)(void);
 };
 
 extern const struct iommu_init_ops *iommu_init_ops;
@@ -87,7 +88,14 @@ int iommu_setup_hpet_msi(struct msi_desc
 int adjust_vtd_irq_affinities(void);
 int __must_check iommu_pte_flush(struct domain *d, u64 gfn, u64 *pte,
                                  int order, int present);
-bool_t iommu_supports_eim(void);
+
+static inline bool iommu_supports_x2apic(void)
+{
+    return iommu_init_ops && iommu_init_ops->supports_x2apic
+           ? iommu_init_ops->supports_x2apic()
+           : false;
+}
+
 int iommu_enable_x2apic_IR(void);
 void iommu_disable_x2apic_IR(void);
 
