git: d50403a6919a - main - iommu: add per-unit sysctls reporting the state of DMA and interrupt remapping

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Fri, 27 Sep 2024 17:34:45 UTC
The branch main has been updated by kib:

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

commit d50403a6919a641abfb0da4d60eb58ce42302de5
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2024-09-27 01:17:57 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2024-09-27 17:34:23 +0000

    iommu: add per-unit sysctls reporting the state of DMA and interrupt remapping
    
    Sponsored by:   Advanced Micro Devices (AMD)
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
---
 sys/arm64/iommu/iommu.c       | 2 ++
 sys/dev/iommu/busdma_iommu.c  | 4 ++++
 sys/dev/iommu/iommu.h         | 1 +
 sys/x86/iommu/intel_drv.c     | 2 ++
 sys/x86/iommu/intel_intrmap.c | 5 ++++-
 5 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/sys/arm64/iommu/iommu.c b/sys/arm64/iommu/iommu.c
index af0edfee70d8..e7b5b2298e26 100644
--- a/sys/arm64/iommu/iommu.c
+++ b/sys/arm64/iommu/iommu.c
@@ -454,6 +454,7 @@ iommu_register(struct iommu_unit *iommu)
 	LIST_INSERT_HEAD(&iommu_list, entry, next);
 	IOMMU_LIST_UNLOCK();
 
+	sysctl_ctx_init(&iommu->sysctl_ctx);
 	iommu_init_busdma(iommu);
 
 	return (0);
@@ -474,6 +475,7 @@ iommu_unregister(struct iommu_unit *iommu)
 	IOMMU_LIST_UNLOCK();
 
 	iommu_fini_busdma(iommu);
+	sysctl_ctx_free(&iommu->sysctl_ctx);
 
 	mtx_destroy(&iommu->lock);
 
diff --git a/sys/dev/iommu/busdma_iommu.c b/sys/dev/iommu/busdma_iommu.c
index bddb466547d1..7a0ca39172f3 100644
--- a/sys/dev/iommu/busdma_iommu.c
+++ b/sys/dev/iommu/busdma_iommu.c
@@ -963,6 +963,10 @@ iommu_init_busdma(struct iommu_unit *unit)
 	error = TUNABLE_INT_FETCH("hw.iommu.dma", &unit->dma_enabled);
 	if (error == 0) /* compatibility */
 		TUNABLE_INT_FETCH("hw.dmar.dma", &unit->dma_enabled);
+	SYSCTL_ADD_INT(&unit->sysctl_ctx,
+	    SYSCTL_CHILDREN(device_get_sysctl_tree(unit->dev)),
+	    OID_AUTO, "dma", CTLFLAG_RD, &unit->dma_enabled, 0,
+	    "DMA ops enabled");
 	TAILQ_INIT(&unit->delayed_maps);
 	TASK_INIT(&unit->dmamap_load_task, 0, iommu_bus_task_dmamap, unit);
 	unit->delayed_taskqueue = taskqueue_create("iommu", M_WAITOK,
diff --git a/sys/dev/iommu/iommu.h b/sys/dev/iommu/iommu.h
index 9845b09e8732..957d4e14e8e2 100644
--- a/sys/dev/iommu/iommu.h
+++ b/sys/dev/iommu/iommu.h
@@ -67,6 +67,7 @@ struct iommu_unit {
 	struct mtx lock;
 	device_t dev;
 	int unit;
+	struct sysctl_ctx_list sysctl_ctx;
 
 	int dma_enabled;
 
diff --git a/sys/x86/iommu/intel_drv.c b/sys/x86/iommu/intel_drv.c
index 05fb49538add..cc16759ebe34 100644
--- a/sys/x86/iommu/intel_drv.c
+++ b/sys/x86/iommu/intel_drv.c
@@ -256,6 +256,7 @@ dmar_release_resources(device_t dev, struct dmar_unit *unit)
 		vm_object_deallocate(unit->ctx_obj);
 		unit->ctx_obj = NULL;
 	}
+	sysctl_ctx_free(&unit->iommu.sysctl_ctx);
 }
 
 #ifdef DEV_APIC
@@ -337,6 +338,7 @@ dmar_attach(device_t dev)
 	unit = device_get_softc(dev);
 	unit->iommu.unit = device_get_unit(dev);
 	unit->iommu.dev = dev;
+	sysctl_ctx_init(&unit->iommu.sysctl_ctx);
 	dmaru = dmar_find_by_index(unit->iommu.unit);
 	if (dmaru == NULL)
 		return (EINVAL);
diff --git a/sys/x86/iommu/intel_intrmap.c b/sys/x86/iommu/intel_intrmap.c
index ec3cd35e4f4e..87bb7c791dd0 100644
--- a/sys/x86/iommu/intel_intrmap.c
+++ b/sys/x86/iommu/intel_intrmap.c
@@ -318,7 +318,10 @@ dmar_ir_free_irte(struct dmar_unit *unit, u_int cookie)
 int
 dmar_init_irt(struct dmar_unit *unit)
 {
-
+	SYSCTL_ADD_INT(&unit->iommu.sysctl_ctx,
+	    SYSCTL_CHILDREN(device_get_sysctl_tree(unit->iommu.dev)),
+	    OID_AUTO, "ir", CTLFLAG_RD, &unit->ir_enabled, 0,
+	    "Interrupt remapping ops enabled");
 	if ((unit->hw_ecap & DMAR_ECAP_IR) == 0)
 		return (0);
 	unit->ir_enabled = 1;