> From: Lu Baolu <baolu...@linux.intel.com> > Sent: Sunday, September 26, 2021 7:46 PM > > The IOMMU VT-d implementation uses the first level for GPA->HPA > translation > by default. Although both the first level and the second level could handle > the DMA translation, they're different in some way. For example, the second > level translation has separate controls for the Access/Dirty page tracking. > With the first level translation, there's no such control. On the other > hand, the second level translation has the page-level control for forcing > snoop, but the first level only has global control with pasid granularity. > > This uses the second level for GPA->HPA translation so that we can provide > a consistent hardware interface for use cases like dirty page tracking for > live migration. > > Signed-off-by: Lu Baolu <baolu...@linux.intel.com> > --- > drivers/iommu/intel/iommu.c | 12 +++++++++--- > 1 file changed, 9 insertions(+), 3 deletions(-) > > diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c > index dc2030d014e0..426630261614 100644 > --- a/drivers/iommu/intel/iommu.c > +++ b/drivers/iommu/intel/iommu.c > @@ -1991,9 +1991,15 @@ static void free_dmar_iommu(struct intel_iommu > *iommu) > * 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; > + /* if 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(); > + /* if both levels are available, decide it based on domain type */ > + return type != IOMMU_DOMAIN_UNMANAGED; > } with above comments added: Reviewed-by: Kevin Tian <kevin.t...@intel.com> > > static struct dmar_domain *alloc_domain(unsigned int type) > @@ -2006,7 +2012,7 @@ 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); > -- > 2.25.1 _______________________________________________ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu