Message ID | 20240208082307.15759-9-yi.l.liu@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Add missing cache flush and dirty tracking set for nested parent domain | expand |
> From: Liu, Yi L <yi.l.liu@intel.com> > Sent: Thursday, February 8, 2024 4:23 PM > > @@ -4760,6 +4790,12 @@ static int intel_iommu_set_dirty_tracking(struct > iommu_domain *domain, > if (ret) > goto err_unwind; > > + if (dmar_domain->nested_parent) { > + ret = parent_domain_set_dirty_tracking(dmar_domain, > enable); > + if (ret) > + goto err_unwind; > + } > + there also lack of setting dirty tracking when a device is attached to the nested domain while the parent already has dirty-tracking enabled. but looks even w/o nesting this is missed in the attach path. could be fixed separately. so for this one: Reviewed-by: Kevin Tian <kevin.tian@intel.com>
On 2024/2/8 16:53, Tian, Kevin wrote: >> From: Liu, Yi L <yi.l.liu@intel.com> >> Sent: Thursday, February 8, 2024 4:23 PM >> >> @@ -4760,6 +4790,12 @@ static int intel_iommu_set_dirty_tracking(struct >> iommu_domain *domain, >> if (ret) >> goto err_unwind; >> >> + if (dmar_domain->nested_parent) { >> + ret = parent_domain_set_dirty_tracking(dmar_domain, >> enable); >> + if (ret) >> + goto err_unwind; >> + } >> + > > there also lack of setting dirty tracking when a device is attached to the > nested domain while the parent already has dirty-tracking enabled. > > but looks even w/o nesting this is missed in the attach path. > > could be fixed separately. so for this one: it's fixed here. https://lore.kernel.org/linux-iommu/20240208091414.28133-1-yi.l.liu@intel.com/ > Reviewed-by: Kevin Tian <kevin.tian@intel.com>
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index 7636d3f03905..b4101712a0c3 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -4746,6 +4746,36 @@ device_set_dirty_tracking(struct list_head *devices, bool enable) return ret; } +static int +parent_domain_set_dirty_tracking(struct dmar_domain *domain, + bool enable) +{ + struct dmar_domain *s1_domain; + unsigned long flags; + int ret; + + spin_lock(&domain->s1_lock); + list_for_each_entry(s1_domain, &domain->s1_domains, s2_link) { + spin_lock_irqsave(&s1_domain->lock, flags); + ret = device_set_dirty_tracking(&s1_domain->devices, enable); + spin_unlock_irqrestore(&s1_domain->lock, flags); + if (ret) + goto err_unwind; + } + spin_unlock(&domain->s1_lock); + return 0; + +err_unwind: + list_for_each_entry(s1_domain, &domain->s1_domains, s2_link) { + spin_lock_irqsave(&s1_domain->lock, flags); + device_set_dirty_tracking(&s1_domain->devices, + domain->dirty_tracking); + spin_unlock_irqrestore(&s1_domain->lock, flags); + } + spin_unlock(&domain->s1_lock); + return ret; +} + static int intel_iommu_set_dirty_tracking(struct iommu_domain *domain, bool enable) { @@ -4760,6 +4790,12 @@ static int intel_iommu_set_dirty_tracking(struct iommu_domain *domain, if (ret) goto err_unwind; + if (dmar_domain->nested_parent) { + ret = parent_domain_set_dirty_tracking(dmar_domain, enable); + if (ret) + goto err_unwind; + } + dmar_domain->dirty_tracking = enable; out_unlock: spin_unlock(&dmar_domain->lock);