git: a0e20c0ded1a - main - Limit the number of CPUs in the gicv1/2 driver
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 04 Aug 2023 17:53:27 UTC
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;