git: c25156347083 - main - x86/iommu: Correct a recent change to iommu_domain_unload_entry()
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 26 Jul 2022 06:08:09 UTC
The branch main has been updated by alc:
URL: https://cgit.FreeBSD.org/src/commit/?id=c251563470831c34cf53242936425a0d4d995edf
commit c251563470831c34cf53242936425a0d4d995edf
Author: Alan Cox <alc@FreeBSD.org>
AuthorDate: 2022-07-26 04:53:15 +0000
Commit: Alan Cox <alc@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