* Check and return whether first level is used by default for
* DMA translation.
*/
-static bool first_level_by_default(void)
+static bool first_level_by_default(unsigned int type)
{
- return scalable_mode_support() && intel_cap_flts_sanity();
+ /* Only SL is available in legacy mode */
+ if (!scalable_mode_support())
+ return false;
+
+ /* Only level (either FL or SL) is available, just use it */
+ if (intel_cap_flts_sanity() ^ intel_cap_slts_sanity())
+ return intel_cap_flts_sanity();
+
+ /* Both levels are available, decide it based on domain type */
+ return type != IOMMU_DOMAIN_UNMANAGED;
}
static struct dmar_domain *alloc_domain(unsigned int type)
memset(domain, 0, sizeof(*domain));
domain->nid = NUMA_NO_NODE;
- if (first_level_by_default())
+ if (first_level_by_default(type))
domain->flags |= DOMAIN_FLAG_USE_FIRST_LEVEL;
domain->has_iotlb_device = false;
INIT_LIST_HEAD(&domain->devices);