Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 4 Aug 2023 17:53:27 GMT
From:      Andrew Turner <andrew@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: a0e20c0ded1a - main - Limit the number of CPUs in the gicv1/2 driver
Message-ID:  <202308041753.374HrRBP076209@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by andrew:

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

commit a0e20c0ded1ae98ec25ded317c6a331fbd40e18c
Author:     Andrew Turner <andrew@FreeBSD.org>
AuthorDate: 2023-08-04 15:06:44 +0000
Commit:     Andrew Turner <andrew@FreeBSD.org>
CommitDate: 2023-08-04 17:47:47 +0000

    Limit the number of CPUs in the gicv1/2 driver
    
    The GICv2 can only send IPIs to 8 CPUs. Because of this it should only
    be in machines with no more than 8 cores.
    
    Create a new macro to hold this limit to reduce the size of the softc.
    
    Reviewed by:    emaste
    Sponsored by:   Arm Ltd
    Differential Revision:  https://reviews.freebsd.org/D41322
---
 sys/arm/arm/gic.c | 19 +++++++++++++++----
 sys/arm/arm/gic.h |  9 ++++++++-
 2 files changed, 23 insertions(+), 5 deletions(-)

diff --git a/sys/arm/arm/gic.c b/sys/arm/arm/gic.c
index a6f81254fe7d..3ff1276f7a3e 100644
--- a/sys/arm/arm/gic.c
+++ b/sys/arm/arm/gic.c
@@ -146,7 +146,7 @@ static int gic_debug_spurious = 0;
 #endif
 TUNABLE_INT("hw.gic.debug_spurious", &gic_debug_spurious);
 
-static u_int arm_gic_map[MAXCPU];
+static u_int arm_gic_map[GIC_MAXCPU];
 
 static struct arm_gic_softc *gic_sc = NULL;
 
@@ -209,6 +209,7 @@ arm_gic_init_secondary(device_t dev)
 
 	/* Set the mask so we can find this CPU to send it IPIs */
 	cpu = PCPU_GET(cpuid);
+	MPASS(cpu < GIC_MAXCPU);
 	arm_gic_map[cpu] = gic_cpu_mask(sc);
 
 	for (irq = 0; irq < sc->nirqs; irq += 4)
@@ -317,6 +318,12 @@ arm_gic_attach(device_t dev)
 	if (gic_sc)
 		return (ENXIO);
 
+	if (mp_ncpus > GIC_MAXCPU) {
+		device_printf(dev, "Too many CPUs for IPIs to work (%d > %d)\n",
+		    mp_ncpus, GIC_MAXCPU);
+		return (ENXIO);
+	}
+
 	sc = device_get_softc(dev);
 
 	if (bus_alloc_resources(dev, arm_gic_spec, sc->gic_res)) {
@@ -362,6 +369,7 @@ arm_gic_attach(device_t dev)
 	/* Find the current cpu mask */
 	mask = gic_cpu_mask(sc);
 	/* Set the mask so we can find this CPU to send it IPIs */
+	MPASS(PCPU_GET(cpuid) < GIC_MAXCPU);
 	arm_gic_map[PCPU_GET(cpuid)] = mask;
 	/* Set all four targets to this cpu */
 	mask |= mask << 8;
@@ -649,7 +657,7 @@ gic_bind(struct arm_gic_softc *sc, u_int irq, cpuset_t *cpus)
 {
 	uint32_t cpu, end, mask;
 
-	end = min(mp_ncpus, 8);
+	end = min(mp_ncpus, GIC_MAXCPU);
 	for (cpu = end; cpu < MAXCPU; cpu++)
 		if (CPU_ISSET(cpu, cpus))
 			return (EINVAL);
@@ -988,9 +996,12 @@ arm_gic_ipi_send(device_t dev, struct intr_irqsrc *isrc, cpuset_t cpus,
 	struct gic_irqsrc *gi = (struct gic_irqsrc *)isrc;
 	uint32_t val = 0, i;
 
-	for (i = 0; i < MAXCPU; i++)
-		if (CPU_ISSET(i, &cpus))
+	for (i = 0; i < MAXCPU; i++) {
+		if (CPU_ISSET(i, &cpus)) {
+			MPASS(i < GIC_MAXCPU);
 			val |= arm_gic_map[i] << GICD_SGI_TARGET_SHIFT;
+		}
+	}
 
 	gic_d_write_4(sc, GICD_SGIR, val | gi->gi_irq);
 }
diff --git a/sys/arm/arm/gic.h b/sys/arm/arm/gic.h
index 5db11a16a4e2..e0780c85fdf9 100644
--- a/sys/arm/arm/gic.h
+++ b/sys/arm/arm/gic.h
@@ -39,6 +39,13 @@
 #ifndef _ARM_GIC_H_
 #define _ARM_GIC_H_
 
+/* The GICv1/2 only supports 8 CPUs */
+#if MAXCPU > 8
+#define	GIC_MAXCPU	8
+#else
+#define	GIC_MAXCPU	MAXCPU
+#endif
+
 struct arm_gic_softc {
 	device_t		gic_dev;
 	void *			gic_intrhand;
@@ -50,7 +57,7 @@ struct arm_gic_softc {
 	struct mtx		mutex;
 	uint32_t		nirqs;
 	uint32_t		typer;
-	uint32_t		last_irq[MAXCPU];
+	uint32_t		last_irq[GIC_MAXCPU];
 
 	uint32_t		gic_iidr;
 	u_int			gic_bus;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202308041753.374HrRBP076209>