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;