git: bfb3b0e7065f - stable/14 - gicv3: Only set the redistributor base if we're not prealloced

From: Warner Losh <imp_at_FreeBSD.org>
Date: Tue, 16 Apr 2024 21:42:48 UTC
The branch stable/14 has been updated by imp:

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

commit bfb3b0e7065f0cee980037bd9ef7afc78f68d7b2
Author:     Warner Losh <imp@FreeBSD.org>
AuthorDate: 2024-02-28 14:08:39 +0000
Commit:     Warner Losh <imp@FreeBSD.org>
CommitDate: 2024-04-16 21:28:40 +0000

    gicv3: Only set the redistributor base if we're not prealloced
    
    Only set the redistributor base if we're not reallocated.  If we are
    preallocated, leave it all alone.
    
    Sponsored by:           Netflix
    Reviewed by:            andrew
    Differential Revision:  https://reviews.freebsd.org/D44035
    
    (cherry picked from commit ae84491a3594c542f2aedc9340581cbb30386c1e)
---
 sys/arm64/arm64/gicv3_its.c | 134 +++++++++++++++++++++++---------------------
 1 file changed, 71 insertions(+), 63 deletions(-)

diff --git a/sys/arm64/arm64/gicv3_its.c b/sys/arm64/arm64/gicv3_its.c
index de65d130ce91..51e7251b9ffd 100644
--- a/sys/arm64/arm64/gicv3_its.c
+++ b/sys/arm64/arm64/gicv3_its.c
@@ -746,81 +746,89 @@ static void
 its_init_cpu_lpi(device_t dev, struct gicv3_its_softc *sc)
 {
 	device_t gicv3;
-	uint64_t xbaser, tmp;
+	uint64_t xbaser, tmp, size;
 	uint32_t ctlr;
 	u_int cpuid;
 
 	gicv3 = device_get_parent(dev);
 	cpuid = PCPU_GET(cpuid);
 
-	/* Disable LPIs */
-	ctlr = gic_r_read_4(gicv3, GICR_CTLR);
-	ctlr &= ~GICR_CTLR_LPI_ENABLE;
-	gic_r_write_4(gicv3, GICR_CTLR, ctlr);
-
-	/* Make sure changes are observable my the GIC */
-	dsb(sy);
-
 	/*
-	 * Set the redistributor base
+	 * Set the redistributor base. If we're reusing what we found on boot
+	 * since the gic was already running, then don't touch it here. We also
+	 * don't need to disable / enable LPI if we're not changing PROPBASER,
+	 * so only do that if we're not prealloced.
 	 */
-	xbaser = vtophys(sc->sc_conf_base) |
-	    (GICR_PROPBASER_SHARE_IS << GICR_PROPBASER_SHARE_SHIFT) |
-	    (GICR_PROPBASER_CACHE_NIWAWB << GICR_PROPBASER_CACHE_SHIFT) |
-	    (flsl(LPI_CONFTAB_SIZE | GIC_FIRST_LPI) - 1);
-	gic_r_write_8(gicv3, GICR_PROPBASER, xbaser);
-
-	/* Check the cache attributes we set */
-	tmp = gic_r_read_8(gicv3, GICR_PROPBASER);
-
-	if ((tmp & GICR_PROPBASER_SHARE_MASK) !=
-	    (xbaser & GICR_PROPBASER_SHARE_MASK)) {
-		if ((tmp & GICR_PROPBASER_SHARE_MASK) ==
-		    (GICR_PROPBASER_SHARE_NS << GICR_PROPBASER_SHARE_SHIFT)) {
-			/* We need to mark as non-cacheable */
-			xbaser &= ~(GICR_PROPBASER_SHARE_MASK |
-			    GICR_PROPBASER_CACHE_MASK);
-			/* Non-cacheable */
-			xbaser |= GICR_PROPBASER_CACHE_NIN <<
-			    GICR_PROPBASER_CACHE_SHIFT;
-			/* Non-shareable */
-			xbaser |= GICR_PROPBASER_SHARE_NS <<
-			    GICR_PROPBASER_SHARE_SHIFT;
-			gic_r_write_8(gicv3, GICR_PROPBASER, xbaser);
+	if ((sc->sc_its_flags & ITS_FLAGS_LPI_PREALLOC) == 0) {
+		/* Disable LPIs */
+		ctlr = gic_r_read_4(gicv3, GICR_CTLR);
+		ctlr &= ~GICR_CTLR_LPI_ENABLE;
+		gic_r_write_4(gicv3, GICR_CTLR, ctlr);
+
+		/* Make sure changes are observable my the GIC */
+		dsb(sy);
+
+		size = (flsl(LPI_CONFTAB_SIZE | GIC_FIRST_LPI) - 1);
+
+		xbaser = vtophys(sc->sc_conf_base) |
+		    (GICR_PROPBASER_SHARE_IS << GICR_PROPBASER_SHARE_SHIFT) |
+		    (GICR_PROPBASER_CACHE_NIWAWB << GICR_PROPBASER_CACHE_SHIFT) |
+		    size;
+
+		gic_r_write_8(gicv3, GICR_PROPBASER, xbaser);
+
+		/* Check the cache attributes we set */
+		tmp = gic_r_read_8(gicv3, GICR_PROPBASER);
+
+		if ((tmp & GICR_PROPBASER_SHARE_MASK) !=
+		    (xbaser & GICR_PROPBASER_SHARE_MASK)) {
+			if ((tmp & GICR_PROPBASER_SHARE_MASK) ==
+			    (GICR_PROPBASER_SHARE_NS << GICR_PROPBASER_SHARE_SHIFT)) {
+				/* We need to mark as non-cacheable */
+				xbaser &= ~(GICR_PROPBASER_SHARE_MASK |
+				    GICR_PROPBASER_CACHE_MASK);
+				/* Non-cacheable */
+				xbaser |= GICR_PROPBASER_CACHE_NIN <<
+				    GICR_PROPBASER_CACHE_SHIFT;
+				/* Non-shareable */
+				xbaser |= GICR_PROPBASER_SHARE_NS <<
+				    GICR_PROPBASER_SHARE_SHIFT;
+				gic_r_write_8(gicv3, GICR_PROPBASER, xbaser);
+			}
+			sc->sc_its_flags |= ITS_FLAGS_LPI_CONF_FLUSH;
 		}
-		sc->sc_its_flags |= ITS_FLAGS_LPI_CONF_FLUSH;
-	}
 
-	/*
-	 * Set the LPI pending table base
-	 */
-	xbaser = vtophys(sc->sc_pend_base[cpuid]) |
-	    (GICR_PENDBASER_CACHE_NIWAWB << GICR_PENDBASER_CACHE_SHIFT) |
-	    (GICR_PENDBASER_SHARE_IS << GICR_PENDBASER_SHARE_SHIFT);
-
-	gic_r_write_8(gicv3, GICR_PENDBASER, xbaser);
-
-	tmp = gic_r_read_8(gicv3, GICR_PENDBASER);
-
-	if ((tmp & GICR_PENDBASER_SHARE_MASK) ==
-	    (GICR_PENDBASER_SHARE_NS << GICR_PENDBASER_SHARE_SHIFT)) {
-		/* Clear the cahce and shareability bits */
-		xbaser &= ~(GICR_PENDBASER_CACHE_MASK |
-		    GICR_PENDBASER_SHARE_MASK);
-		/* Mark as non-shareable */
-		xbaser |= GICR_PENDBASER_SHARE_NS << GICR_PENDBASER_SHARE_SHIFT;
-		/* And non-cacheable */
-		xbaser |= GICR_PENDBASER_CACHE_NIN <<
-		    GICR_PENDBASER_CACHE_SHIFT;
-	}
+		/*
+		 * Set the LPI pending table base
+		 */
+		xbaser = vtophys(sc->sc_pend_base[cpuid]) |
+		    (GICR_PENDBASER_CACHE_NIWAWB << GICR_PENDBASER_CACHE_SHIFT) |
+		    (GICR_PENDBASER_SHARE_IS << GICR_PENDBASER_SHARE_SHIFT);
+
+		gic_r_write_8(gicv3, GICR_PENDBASER, xbaser);
+
+		tmp = gic_r_read_8(gicv3, GICR_PENDBASER);
+
+		if ((tmp & GICR_PENDBASER_SHARE_MASK) ==
+		    (GICR_PENDBASER_SHARE_NS << GICR_PENDBASER_SHARE_SHIFT)) {
+			/* Clear the cahce and shareability bits */
+			xbaser &= ~(GICR_PENDBASER_CACHE_MASK |
+			    GICR_PENDBASER_SHARE_MASK);
+			/* Mark as non-shareable */
+			xbaser |= GICR_PENDBASER_SHARE_NS << GICR_PENDBASER_SHARE_SHIFT;
+			/* And non-cacheable */
+			xbaser |= GICR_PENDBASER_CACHE_NIN <<
+			    GICR_PENDBASER_CACHE_SHIFT;
+		}
 
-	/* Enable LPIs */
-	ctlr = gic_r_read_4(gicv3, GICR_CTLR);
-	ctlr |= GICR_CTLR_LPI_ENABLE;
-	gic_r_write_4(gicv3, GICR_CTLR, ctlr);
+		/* Enable LPIs */
+		ctlr = gic_r_read_4(gicv3, GICR_CTLR);
+		ctlr |= GICR_CTLR_LPI_ENABLE;
+		gic_r_write_4(gicv3, GICR_CTLR, ctlr);
 
-	/* Make sure the GIC has seen everything */
-	dsb(sy);
+		/* Make sure the GIC has seen everything */
+		dsb(sy);
+	}
 }
 
 static int