svn commit: r308382 - in stable/11/sys: arm/arm arm64/arm64 kern mips/mips

Oleksandr Tymoshenko gonzo at FreeBSD.org
Sun Nov 6 18:40:14 UTC 2016


Author: gonzo
Date: Sun Nov  6 18:40:12 2016
New Revision: 308382
URL: https://svnweb.freebsd.org/changeset/base/308382

Log:
  MFC r306899, r307059, r307151
  
  r306899:
  Fix release MSI method for ARM GIC
  
  r307059:
  INTRNG - fix MSI/MSIX release path
  
  Use isrc in attached MSI data structure instead of using map's
  isrc directly. map's isrc is set to NULL on IRQ deactivation
  which happens prior to pci_release_msi so MSI_RELEASE_MSI
  receives array of NULLs
  
  Reviewed by:	mmel
  Differential Revision:	https://reviews.freebsd.org/D8206
  
  r307151:
  INTRNG: Propagate IRQ activation error to API consumer
  
  Keep resource state consistent with INTRNG state - if intr_activate_irq
  fails - deactivate resource and propagate error to calling function
  
  Reviewed by:	mmel

Modified:
  stable/11/sys/arm/arm/gic.c
  stable/11/sys/arm/arm/nexus.c
  stable/11/sys/arm64/arm64/nexus.c
  stable/11/sys/kern/subr_intr.c
  stable/11/sys/mips/mips/nexus.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/arm/arm/gic.c
==============================================================================
--- stable/11/sys/arm/arm/gic.c	Sun Nov  6 18:11:19 2016	(r308381)
+++ stable/11/sys/arm/arm/gic.c	Sun Nov  6 18:40:12 2016	(r308382)
@@ -1700,15 +1700,15 @@ arm_gicv2m_release_msi(device_t dev, dev
 
 	mtx_lock(&sc->sc_mutex);
 	for (i = 0; i < count; i++) {
-		gi = (struct gic_irqsrc *)isrc;
+		gi = (struct gic_irqsrc *)isrc[i];
 
 		KASSERT((gi->gi_flags & GI_FLAG_MSI_USED) == GI_FLAG_MSI_USED,
 		    ("%s: Trying to release an unused MSI-X interrupt",
 		    __func__));
 
 		gi->gi_flags &= ~GI_FLAG_MSI_USED;
-		mtx_unlock(&sc->sc_mutex);
 	}
+	mtx_unlock(&sc->sc_mutex);
 
 	return (0);
 }

Modified: stable/11/sys/arm/arm/nexus.c
==============================================================================
--- stable/11/sys/arm/arm/nexus.c	Sun Nov  6 18:11:19 2016	(r308381)
+++ stable/11/sys/arm/arm/nexus.c	Sun Nov  6 18:40:12 2016	(r308382)
@@ -383,7 +383,11 @@ nexus_activate_resource(device_t bus, de
 		return (0);
 	} else if (type == SYS_RES_IRQ) {
 #ifdef INTRNG
-		intr_activate_irq(child, r);
+		err = intr_activate_irq(child, r);
+		if (err != 0) {
+			rman_deactivate_resource(r);
+			return (err);
+		}
 #endif
 	}
 	return (0);

Modified: stable/11/sys/arm64/arm64/nexus.c
==============================================================================
--- stable/11/sys/arm64/arm64/nexus.c	Sun Nov  6 18:11:19 2016	(r308381)
+++ stable/11/sys/arm64/arm64/nexus.c	Sun Nov  6 18:40:12 2016	(r308382)
@@ -346,7 +346,11 @@ nexus_activate_resource(device_t bus, de
 		rman_set_virtual(r, (void *)vaddr);
 		rman_set_bushandle(r, vaddr);
 	} else if (type == SYS_RES_IRQ) {
-		intr_activate_irq(child, r);
+		err = intr_activate_irq(child, r);
+		if (err != 0) {
+			rman_deactivate_resource(r);
+			return (err);
+		}
 	}
 	return (0);
 }

Modified: stable/11/sys/kern/subr_intr.c
==============================================================================
--- stable/11/sys/kern/subr_intr.c	Sun Nov  6 18:11:19 2016	(r308381)
+++ stable/11/sys/kern/subr_intr.c	Sun Nov  6 18:40:12 2016	(r308382)
@@ -145,6 +145,7 @@ static u_int intrcnt_index;
 
 static struct intr_irqsrc *intr_map_get_isrc(u_int res_id);
 static void intr_map_set_isrc(u_int res_id, struct intr_irqsrc *isrc);
+static struct intr_map_data * intr_map_get_map_data(u_int res_id);
 static void intr_map_copy_map_data(u_int res_id, device_t *dev, intptr_t *xref,
     struct intr_map_data **data);
 
@@ -1309,6 +1310,7 @@ intr_release_msi(device_t pci, device_t 
 {
 	struct intr_irqsrc **isrc;
 	struct intr_pic *pic;
+	struct intr_map_data_msi *msi;
 	int i, err;
 
 	pic = pic_lookup(NULL, xref);
@@ -1321,8 +1323,14 @@ intr_release_msi(device_t pci, device_t 
 
 	isrc = malloc(sizeof(*isrc) * count, M_INTRNG, M_WAITOK);
 
-	for (i = 0; i < count; i++)
-		isrc[i] = intr_map_get_isrc(irqs[i]);
+	for (i = 0; i < count; i++) {
+		msi = (struct intr_map_data_msi *)
+		    intr_map_get_map_data(irqs[i]);
+		KASSERT(msi->hdr.type == INTR_MAP_DATA_MSI,
+		    ("%s: irq %d map data is not MSI", __func__,
+		    irqs[i]));
+		isrc[i] = msi->isrc;
+	}
 
 	err = MSI_RELEASE_MSI(pic->pic_dev, child, count, isrc);
 
@@ -1369,6 +1377,7 @@ intr_release_msix(device_t pci, device_t
 {
 	struct intr_irqsrc *isrc;
 	struct intr_pic *pic;
+	struct intr_map_data_msi *msi;
 	int err;
 
 	pic = pic_lookup(NULL, xref);
@@ -1379,7 +1388,12 @@ intr_release_msix(device_t pci, device_t
 	    ("%s: Found a non-MSI controller: %s", __func__,
 	     device_get_name(pic->pic_dev)));
 
-	isrc = intr_map_get_isrc(irq);
+	msi = (struct intr_map_data_msi *)
+	    intr_map_get_map_data(irq);
+	KASSERT(msi->hdr.type == INTR_MAP_DATA_MSI,
+	    ("%s: irq %d map data is not MSI", __func__,
+	    irq));
+	isrc = msi->isrc;
 	if (isrc == NULL) {
 		intr_unmap_irq(irq);
 		return (EINVAL);
@@ -1516,6 +1530,24 @@ intr_map_set_isrc(u_int res_id, struct i
 /*
  * Get a copy of intr_map_entry data
  */
+static struct intr_map_data *
+intr_map_get_map_data(u_int res_id)
+{
+	struct intr_map_data *data;
+
+	data = NULL;
+	mtx_lock(&irq_map_lock);
+	if (res_id >= irq_map_count || irq_map[res_id] == NULL)
+		panic("Attempt to copy invalid resource id: %u\n", res_id);
+	data = irq_map[res_id]->map_data;
+	mtx_unlock(&irq_map_lock);
+
+	return (data);
+}
+
+/*
+ * Get a copy of intr_map_entry data
+ */
 static void
 intr_map_copy_map_data(u_int res_id, device_t *map_dev, intptr_t *map_xref,
     struct intr_map_data **data)

Modified: stable/11/sys/mips/mips/nexus.c
==============================================================================
--- stable/11/sys/mips/mips/nexus.c	Sun Nov  6 18:11:19 2016	(r308381)
+++ stable/11/sys/mips/mips/nexus.c	Sun Nov  6 18:40:12 2016	(r308382)
@@ -433,7 +433,11 @@ nexus_activate_resource(device_t bus, de
 	} else if (type == SYS_RES_IRQ) {
 #ifdef INTRNG
 #ifdef FDT
-		intr_activate_irq(child, r);
+		err = intr_activate_irq(child, r);
+		if (err != 0) {
+			rman_deactivate_resource(r);
+			return (err);
+		}
 #else
 		/*
 		 * INTRNG without FDT needs to have the interrupt properly


More information about the svn-src-all mailing list