The branch main has been updated by alc:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=c251563470831c34cf53242936425a0d4d995edf

commit c251563470831c34cf53242936425a0d4d995edf
Author:     Alan Cox <a...@freebsd.org>
AuthorDate: 2022-07-26 04:53:15 +0000
Commit:     Alan Cox <a...@freebsd.org>
CommitDate: 2022-07-26 06:07:21 +0000

    x86/iommu: Correct a recent change to iommu_domain_unload_entry()
    
    Correct 8bc367384745.  When iommu_domain_unload_entry() performs a
    synchronous IOTLB invalidation, it must call dmar_domain_free_entry()
    to remove the entry from the domain's RB_TREE.
    
    Push down the acquisition and release of the DMAR lock into the
    recently introduced function dmar_qi_invalidate_sync_locked() and
    remove the _locked suffix.
    
    MFC with:       8bc367384745
---
 sys/x86/iommu/intel_ctx.c  | 7 ++++---
 sys/x86/iommu/intel_dmar.h | 4 ++--
 sys/x86/iommu/intel_qi.c   | 9 ++++++---
 3 files changed, 12 insertions(+), 8 deletions(-)

diff --git a/sys/x86/iommu/intel_ctx.c b/sys/x86/iommu/intel_ctx.c
index 5e13f020264b..936cf8bb7632 100644
--- a/sys/x86/iommu/intel_ctx.c
+++ b/sys/x86/iommu/intel_ctx.c
@@ -883,17 +883,18 @@ iommu_domain_unload_entry(struct iommu_map_entry *entry, 
bool free,
         * dmar_qi_task() is finished processing it.
         */
        if (unit->qi_enabled) {
-               DMAR_LOCK(unit);
                if (free) {
+                       DMAR_LOCK(unit);
                        dmar_qi_invalidate_locked(domain, entry->start,
                            entry->end - entry->start, &entry->gseq, true);
                        TAILQ_INSERT_TAIL(&unit->tlb_flush_entries, entry,
                            dmamap_link);
+                       DMAR_UNLOCK(unit);
                } else {
-                       dmar_qi_invalidate_sync_locked(domain, entry->start,
+                       dmar_qi_invalidate_sync(domain, entry->start,
                            entry->end - entry->start, cansleep);
+                       dmar_domain_free_entry(entry, false);
                }
-               DMAR_UNLOCK(unit);
        } else {
                domain_flush_iotlb_sync(domain, entry->start, entry->end -
                    entry->start);
diff --git a/sys/x86/iommu/intel_dmar.h b/sys/x86/iommu/intel_dmar.h
index 0f811d760bb7..06cecdf704ff 100644
--- a/sys/x86/iommu/intel_dmar.h
+++ b/sys/x86/iommu/intel_dmar.h
@@ -251,8 +251,8 @@ int dmar_init_qi(struct dmar_unit *unit);
 void dmar_fini_qi(struct dmar_unit *unit);
 void dmar_qi_invalidate_locked(struct dmar_domain *domain, iommu_gaddr_t start,
     iommu_gaddr_t size, struct iommu_qi_genseq *psec, bool emit_wait);
-void dmar_qi_invalidate_sync_locked(struct dmar_domain *domain,
-    iommu_gaddr_t start, iommu_gaddr_t size, bool cansleep);
+void dmar_qi_invalidate_sync(struct dmar_domain *domain, iommu_gaddr_t start,
+    iommu_gaddr_t size, bool cansleep);
 void dmar_qi_invalidate_ctx_glob_locked(struct dmar_unit *unit);
 void dmar_qi_invalidate_iotlb_glob_locked(struct dmar_unit *unit);
 void dmar_qi_invalidate_iec_glob(struct dmar_unit *unit);
diff --git a/sys/x86/iommu/intel_qi.c b/sys/x86/iommu/intel_qi.c
index 174cf9ea19a8..32f01a2787b0 100644
--- a/sys/x86/iommu/intel_qi.c
+++ b/sys/x86/iommu/intel_qi.c
@@ -243,14 +243,17 @@ dmar_qi_invalidate_locked(struct dmar_domain *domain, 
iommu_gaddr_t base,
 }
 
 void
-dmar_qi_invalidate_sync_locked(struct dmar_domain *domain, iommu_gaddr_t base,
+dmar_qi_invalidate_sync(struct dmar_domain *domain, iommu_gaddr_t base,
     iommu_gaddr_t size, bool cansleep)
 {
+       struct dmar_unit *unit;
        struct iommu_qi_genseq gseq;
 
-       DMAR_ASSERT_LOCKED(domain->dmar);
+       unit = domain->dmar;
+       DMAR_LOCK(unit);
        dmar_qi_invalidate_locked(domain, base, size, &gseq, true);
-       dmar_qi_wait_for_seq(domain->dmar, &gseq, !cansleep);
+       dmar_qi_wait_for_seq(unit, &gseq, !cansleep);
+       DMAR_UNLOCK(unit);
 }
 
 void

Reply via email to