svn commit: r367016 - in head/sys: dev/iommu kern

Ruslan Bukin br at FreeBSD.org
Sat Oct 24 20:09:28 UTC 2020


Author: br
Date: Sat Oct 24 20:09:27 2020
New Revision: 367016
URL: https://svnweb.freebsd.org/changeset/base/367016

Log:
  o Add iommu de-initialization method for MSI interface.
  o Add iommu_unmap_msi() to release the msi GAS entry.
  o Provide default implementations for iommu init/deinit methods.
  
  Reviewed by:	kib
  Sponsored by:	Innovate DSbD
  Differential Revision:	https://reviews.freebsd.org/D26906

Modified:
  head/sys/dev/iommu/iommu_gas.c
  head/sys/dev/iommu/iommu_msi.h
  head/sys/kern/msi_if.m
  head/sys/kern/subr_intr.c

Modified: head/sys/dev/iommu/iommu_gas.c
==============================================================================
--- head/sys/dev/iommu/iommu_gas.c	Sat Oct 24 17:47:43 2020	(r367015)
+++ head/sys/dev/iommu/iommu_gas.c	Sat Oct 24 20:09:27 2020	(r367016)
@@ -727,6 +727,31 @@ iommu_map(struct iommu_domain *domain,
 	return (error);
 }
 
+void
+iommu_unmap_msi(struct iommu_ctx *ctx)
+{
+	struct iommu_map_entry *entry;
+	struct iommu_domain *domain;
+
+	domain = ctx->domain;
+	entry = domain->msi_entry;
+	if (entry == NULL)
+		return;
+
+	domain->ops->unmap(domain, entry->start, entry->end -
+	    entry->start, IOMMU_PGF_WAITOK);
+
+	IOMMU_DOMAIN_LOCK(domain);
+	iommu_gas_free_space(domain, entry);
+	IOMMU_DOMAIN_UNLOCK(domain);
+
+	iommu_gas_free_entry(domain, entry);
+
+	domain->msi_entry = NULL;
+	domain->msi_base = 0;
+	domain->msi_phys = 0;
+}
+
 int
 iommu_map_msi(struct iommu_ctx *ctx, iommu_gaddr_t size, int offset,
     u_int eflags, u_int flags, vm_page_t *ma)

Modified: head/sys/dev/iommu/iommu_msi.h
==============================================================================
--- head/sys/dev/iommu/iommu_msi.h	Sat Oct 24 17:47:43 2020	(r367015)
+++ head/sys/dev/iommu/iommu_msi.h	Sat Oct 24 20:09:27 2020	(r367016)
@@ -42,5 +42,6 @@ struct iommu_ctx;
 void iommu_translate_msi(struct iommu_domain *domain, uint64_t *addr);
 int iommu_map_msi(struct iommu_ctx *ctx, iommu_gaddr_t size, int offset,
     u_int eflags, u_int flags, vm_page_t *ma);
+void iommu_unmap_msi(struct iommu_ctx *ctx);
 
 #endif /* !_DEV_IOMMU_IOMMU_MSI_H_ */

Modified: head/sys/kern/msi_if.m
==============================================================================
--- head/sys/kern/msi_if.m	Sat Oct 24 17:47:43 2020	(r367015)
+++ head/sys/kern/msi_if.m	Sat Oct 24 20:09:27 2020	(r367016)
@@ -38,6 +38,22 @@ HEADER {
 	struct intr_irqsrc;
 };
 
+#
+# Default implementations of some methods.
+#
+CODE {
+	static int
+	iommu_init(device_t dev, device_t child, struct iommu_domain **domain)
+	{
+		*domain = NULL;
+		return (0);
+	}
+	static void
+	iommu_deinit(device_t dev, device_t child)
+	{
+	}
+};
+
 METHOD int alloc_msi {
 	device_t	dev;
 	device_t	child;
@@ -79,4 +95,9 @@ METHOD int iommu_init {
 	device_t	dev;
 	device_t	child;
 	struct iommu_domain **domain;
-};
+} DEFAULT iommu_init;
+
+METHOD void iommu_deinit {
+	device_t	dev;
+	device_t	child;
+} DEFAULT iommu_deinit;

Modified: head/sys/kern/subr_intr.c
==============================================================================
--- head/sys/kern/subr_intr.c	Sat Oct 24 17:47:43 2020	(r367015)
+++ head/sys/kern/subr_intr.c	Sat Oct 24 20:09:27 2020	(r367016)
@@ -1297,9 +1297,7 @@ int
 intr_alloc_msi(device_t pci, device_t child, intptr_t xref, int count,
     int maxcount, int *irqs)
 {
-#ifdef IOMMU
 	struct iommu_domain *domain;
-#endif
 	struct intr_irqsrc **isrc;
 	struct intr_pic *pic;
 	device_t pdev;
@@ -1314,7 +1312,6 @@ intr_alloc_msi(device_t pci, device_t child, intptr_t 
 	    ("%s: Found a non-MSI controller: %s", __func__,
 	     device_get_name(pic->pic_dev)));
 
-#ifdef IOMMU
 	/*
 	 * If this is the first time we have used this context ask the
 	 * interrupt controller to map memory the msi source will need.
@@ -1322,7 +1319,6 @@ intr_alloc_msi(device_t pci, device_t child, intptr_t 
 	err = MSI_IOMMU_INIT(pic->pic_dev, child, &domain);
 	if (err != 0)
 		return (err);
-#endif
 
 	isrc = malloc(sizeof(*isrc) * count, M_INTRNG, M_WAITOK);
 	err = MSI_ALLOC_MSI(pic->pic_dev, child, count, maxcount, &pdev, isrc);
@@ -1332,9 +1328,7 @@ intr_alloc_msi(device_t pci, device_t child, intptr_t 
 	}
 
 	for (i = 0; i < count; i++) {
-#ifdef IOMMU
 		isrc[i]->isrc_iommu = domain;
-#endif
 		msi = (struct intr_map_data_msi *)intr_alloc_map_data(
 		    INTR_MAP_DATA_MSI, sizeof(*msi), M_WAITOK | M_ZERO);
 		msi-> isrc = isrc[i];
@@ -1375,6 +1369,8 @@ intr_release_msi(device_t pci, device_t child, intptr_
 		isrc[i] = msi->isrc;
 	}
 
+	MSI_IOMMU_DEINIT(pic->pic_dev, child);
+
 	err = MSI_RELEASE_MSI(pic->pic_dev, child, count, isrc);
 
 	for (i = 0; i < count; i++) {
@@ -1389,9 +1385,7 @@ intr_release_msi(device_t pci, device_t child, intptr_
 int
 intr_alloc_msix(device_t pci, device_t child, intptr_t xref, int *irq)
 {
-#ifdef IOMMU
 	struct iommu_domain *domain;
-#endif
 	struct intr_irqsrc *isrc;
 	struct intr_pic *pic;
 	device_t pdev;
@@ -1406,7 +1400,6 @@ intr_alloc_msix(device_t pci, device_t child, intptr_t
 	    ("%s: Found a non-MSI controller: %s", __func__,
 	     device_get_name(pic->pic_dev)));
 
-#ifdef IOMMU
 	/*
 	 * If this is the first time we have used this context ask the
 	 * interrupt controller to map memory the msi source will need.
@@ -1414,15 +1407,12 @@ intr_alloc_msix(device_t pci, device_t child, intptr_t
 	err = MSI_IOMMU_INIT(pic->pic_dev, child, &domain);
 	if (err != 0)
 		return (err);
-#endif
 
 	err = MSI_ALLOC_MSIX(pic->pic_dev, child, &pdev, &isrc);
 	if (err != 0)
 		return (err);
 
-#ifdef IOMMU
 	isrc->isrc_iommu = domain;
-#endif
 	msi = (struct intr_map_data_msi *)intr_alloc_map_data(
 		    INTR_MAP_DATA_MSI, sizeof(*msi), M_WAITOK | M_ZERO);
 	msi->isrc = isrc;
@@ -1456,6 +1446,8 @@ intr_release_msix(device_t pci, device_t child, intptr
 		intr_unmap_irq(irq);
 		return (EINVAL);
 	}
+
+	MSI_IOMMU_DEINIT(pic->pic_dev, child);
 
 	err = MSI_RELEASE_MSIX(pic->pic_dev, child, isrc);
 	intr_unmap_irq(irq);


More information about the svn-src-all mailing list