git: 412c3a037049 - main - arm64/gicv5: Use ArmMpidr to find the correct CPU

From: Andrew Turner <andrew_at_FreeBSD.org>
Date: Mon, 05 Oct 2026 14:13:29 UTC
The branch main has been updated by andrew:

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

commit 412c3a0370491c6745e056266f54ce9aa67017e1
Author:     Andrew Turner <andrew@FreeBSD.org>
AuthorDate: 2026-10-05 13:31:02 +0000
Commit:     Andrew Turner <andrew@FreeBSD.org>
CommitDate: 2026-10-05 14:13:06 +0000

    arm64/gicv5: Use ArmMpidr to find the correct CPU
    
    The GICv5 ACPI code uses CpuInterfaceNumber to as the CPU ID. This a
    GICv5 CPU ID and may not be the same as the appropriate FreeBSD value.
    
    It is also possible the target CPU is disabled, e.g. when the hw.ncpu
    tunable is uses to limit CPUs. If this is the case we don't want to
    enable the CPU in the cpu set as it is offline so cannot handle
    interrupts.
    
    Switch to use ArmMpidr to find which pcpu to use when finding which
    CPUs the IRS is attached to.
    
    Fixes:  9556306213e1 ("arm64: Add ACPI support to GICv5 driver")
    Differential Revision:  https://reviews.freebsd.org/D59993
    Sponsored by:   Arm Ltd
---
 sys/arm64/arm64/gicv5_acpi.c | 17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/sys/arm64/arm64/gicv5_acpi.c b/sys/arm64/arm64/gicv5_acpi.c
index 0cece1eae0e5..aebea1dcd466 100644
--- a/sys/arm64/arm64/gicv5_acpi.c
+++ b/sys/arm64/arm64/gicv5_acpi.c
@@ -28,11 +28,12 @@
 #include <sys/types.h>
 #include <sys/systm.h>
 #include <sys/bus.h>
+#include <sys/cpuset.h>
 #include <sys/kernel.h>
 #include <sys/malloc.h>
 #include <sys/module.h>
 #include <sys/rman.h>
-#include <sys/cpuset.h>
+#include <sys/smp.h>
 
 #include <machine/intr.h>
 #include <machine/resource.h>
@@ -254,14 +255,24 @@ madt_process_gicc(ACPI_SUBTABLE_HEADER *entry, void *arg)
 {
 	struct process_gicc_args *gicc_args;
 	ACPI_MADT_GENERIC_INTERRUPT *gicc;
+	struct pcpu *pcpu;
+	int cpu;
 
 	gicc_args = (struct process_gicc_args *)arg;
 
 	if (entry->Type == ACPI_MADT_TYPE_GENERIC_INTERRUPT) {
 		gicc = (ACPI_MADT_GENERIC_INTERRUPT *)entry;
 
-		if (gicc->IrsId == gicc_args->irs_id)
-			CPU_SET(gicc->CpuInterfaceNumber, &gicc_args->cpuset);
+		if (gicc->IrsId == gicc_args->irs_id) {
+			/* Find CPU ID from gicc->ArmMpidr */
+			CPU_FOREACH(cpu) {
+				pcpu = pcpu_find(cpu);
+				if (pcpu->pc_mpidr != gicc->ArmMpidr)
+					continue;
+				CPU_SET(pcpu->pc_cpuid, &gicc_args->cpuset);
+				break;
+			}
+		}
 	}
 }