The function its_init_cpu_lpi() will configure the LPIs for a given CPU. One part is to configure the GICR_PROPBASER which contains, among other fields, the size of the property table. This is computed as followed: ``` 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; ``` Per the GIC specification (12.11.31 in ARM IHI 069G), the ID bits is: ``` The number of bits of LPI INTID supported, minus one, by the LPI Configuration table starting at Physical_Address. ``` As the function flsl returns the last bit set starting from 1 (e.g. if the value 1 is passed, then the return is 1), I think the size should be computed using flsl(...) - 2. The size is also used by the pending table which can't be touched by the OS once the LPIs has been enabled: ``` During normal operation, the LPI Pending table is maintained solely by the Redistributor. Behavior is UNPREDICTABLE if software writes to the LPI Pending tables while GICR_CTLR.EnableLPIs == 1. When GICR_CTLR.EnableLPIs is cleared to 0, behavior is UNPREDICTABLE if the LPI Pending table is written before GICR_CTLR.RWP reads 0. ``` As we don't know the content past the region, this could lead to strange behavior. Although, I am not aware of any issue right now. This will also become a problem in confidential compute, because FreeBSD may end up to declassify more memory than we should. I am not posting a formal patch because I don't have a setup to build FreeBSD yet.
I opened a review: https://reviews.freebsd.org/D49542
A commit in branch main references this bug: URL: https://cgit.FreeBSD.org/src/commit/?id=a1759dca96748648a6da5f9ebd14e46836eed45e commit a1759dca96748648a6da5f9ebd14e46836eed45e Author: Colin Percival <cperciva@FreeBSD.org> AuthorDate: 2025-03-27 20:23:32 +0000 Commit: Colin Percival <cperciva@FreeBSD.org> CommitDate: 2025-03-28 17:58:19 +0000 arm64: Fix off-by-one in its_init_cpu_lpi The low bits of GICR_PROPBASER are defined as The number of bits of LPI INTID supported, minus one, by the LPI Configuration table starting at Physical_Address. but flsl(1 << n) returns n + 1; use ilog2_long instead. PR: 285677 Reported by: Julien Grall Reviewed by: andrew Sponsored by: Amazon Differential Revision: https://reviews.freebsd.org/D49542 sys/arm64/arm64/gicv3_its.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)