return -EFAULT;
 }
+
+bool intel_cap_smts_sanity(void)
+{
+       return ecap_smts(intel_iommu_ecap_sanity);
+}
+
+bool intel_cap_pasid_sanity(void)
+{
+       return ecap_pasid(intel_iommu_ecap_sanity);
+}
+
+bool intel_cap_nest_sanity(void)
+{
+       return ecap_nest(intel_iommu_ecap_sanity);
+}
+
+bool intel_cap_flts_sanity(void)
+{
+       return ecap_flts(intel_iommu_ecap_sanity);
+}
 
        CAP_AUDIT_HOTPLUG_IRQR,
 };
 
+bool intel_cap_smts_sanity(void);
+bool intel_cap_pasid_sanity(void);
+bool intel_cap_nest_sanity(void);
+bool intel_cap_flts_sanity(void);
+
+static inline bool scalable_mode_support(void)
+{
+       return (intel_iommu_sm && intel_cap_smts_sanity());
+}
+
+static inline bool pasid_mode_support(void)
+{
+       return scalable_mode_support() && intel_cap_pasid_sanity();
+}
+
+static inline bool nested_mode_support(void)
+{
+       return scalable_mode_support() && intel_cap_nest_sanity();
+}
+
 int intel_cap_audit(enum cap_audit_type type, struct intel_iommu *iommu);
 
  */
 static bool first_level_by_default(void)
 {
-       struct dmar_drhd_unit *drhd;
-       struct intel_iommu *iommu;
-       static int first_level_support = -1;
-
-       if (likely(first_level_support != -1))
-               return first_level_support;
-
-       first_level_support = 1;
-
-       rcu_read_lock();
-       for_each_active_iommu(iommu, drhd) {
-               if (!sm_supported(iommu) || !ecap_flts(iommu->ecap)) {
-                       first_level_support = 0;
-                       break;
-               }
-       }
-       rcu_read_unlock();
-
-       return first_level_support;
+       return scalable_mode_support() && intel_cap_flts_sanity();
 }
 
 static struct dmar_domain *alloc_domain(int flags)
        return phys;
 }
 
-static inline bool scalable_mode_support(void)
-{
-       struct dmar_drhd_unit *drhd;
-       struct intel_iommu *iommu;
-       bool ret = true;
-
-       rcu_read_lock();
-       for_each_active_iommu(iommu, drhd) {
-               if (!sm_supported(iommu)) {
-                       ret = false;
-                       break;
-               }
-       }
-       rcu_read_unlock();
-
-       return ret;
-}
-
-static inline bool iommu_pasid_support(void)
-{
-       struct dmar_drhd_unit *drhd;
-       struct intel_iommu *iommu;
-       bool ret = true;
-
-       rcu_read_lock();
-       for_each_active_iommu(iommu, drhd) {
-               if (!pasid_supported(iommu)) {
-                       ret = false;
-                       break;
-               }
-       }
-       rcu_read_unlock();
-
-       return ret;
-}
-
-static inline bool nested_mode_support(void)
-{
-       struct dmar_drhd_unit *drhd;
-       struct intel_iommu *iommu;
-       bool ret = true;
-
-       rcu_read_lock();
-       for_each_active_iommu(iommu, drhd) {
-               if (!sm_supported(iommu) || !ecap_nest(iommu->ecap)) {
-                       ret = false;
-                       break;
-               }
-       }
-       rcu_read_unlock();
-
-       return ret;
-}
-
 static bool intel_iommu_capable(enum iommu_cap cap)
 {
        if (cap == IOMMU_CAP_CACHE_COHERENCY)
                int ret;
 
                if (!dev_is_pci(dev) || dmar_disabled ||
-                   !scalable_mode_support() || !iommu_pasid_support())
+                   !scalable_mode_support() || !pasid_mode_support())
                        return false;
 
                ret = pci_pasid_features(to_pci_dev(dev));