xen/arm: gic: defer host LPI allocation until after ITS init

gicv3_lpi_init_host_lpis() initializes Xen-side host LPI bookkeeping,
registers the CPU notifier, and allocates the boot CPU pending table.
The pending table allocation uses gicv3_its_get_memflags().

ITS quirks are discovered by gicv3_its_init(), so allocating the boot
CPU pending table from gicv3_dist_init() can happen before the memory
restrictions required by the ITS are known. On affected systems this
can leave the pending table allocated using the default memory policy.

Move host LPI initialization after gicv3_its_init(), and only run it
when a host ITS was found. The old call ignored the return value. Now
that the call is made from gicv3_init(), check it and panic on failure
because Redistributor LPI initialization relies on that state being
available.

Although this reorders host LPI bookkeeping with respect to ITS
initialization, it does not change the hardware-visible LPI setup
sequence. gicv3_lpi_init_host_lpis() does not program the
Redistributor or submit any ITS commands. gicv3_cpu_init() still
programs GICR_PENDBASER/GICR_PROPBASER via
gicv3_lpi_init_rdist(), sets GICR_CTLR.EnableLPIs, and only then calls
gicv3_its_setup_collection(), which submits the first MAPC/SYNC
commands. Therefore, the ordering introduced by 95604873cc remains
unchanged.

This also narrows the condition for host LPI initialization from
"GICD advertises LPIs" to "a host ITS was discovered". This is
intentional: Xen currently has no supported LPI path without a host
ITS, and gicv3_lpi_init_rdist() already rejects that case with
-ENODEV. Therefore, on systems where GICD_TYPE_LPIS is set but no host
ITS is present, skipping gicv3_lpi_init_host_lpis() only avoids
allocating host LPI state that cannot be used by a supported Xen LPI
path.

Fixes: dcb6cb2636 ("ARM: GICv3 ITS: introduce host LPI array")
Fixes: 751ec850ec ("ARM: ITS: implement quirks and add support for Renesas Gen4 ITS")
Signed-off-by: Mykola Kvach <mykola_kvach@epam.com>
Reviewed-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>
Reviewed-by: Michal Orzel <michal.orzel@amd.com>
Release-Acked-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
This commit is contained in:
Mykola Kvach authored and Michal Orzel committed 2026-06-26 10:06:08 +02:00
1 parent c7b7429854
commit 9b3a73a028
1 file changed
+11 -3
+11 -3
View File
@@ -764,9 +764,6 @@ static void __init gicv3_dist_init(void)
type = readl_relaxed(GICD + GICD_TYPER);
nr_lines = 32 * ((type & GICD_TYPE_LINES) + 1);
if ( type & GICD_TYPE_LPIS )
gicv3_lpi_init_host_lpis(GICD_TYPE_ID_BITS(type));
/* Only 1020 interrupts are supported */
nr_lines = min(1020U, nr_lines);
gicv3_info.nr_lines = nr_lines;
@@ -1990,6 +1987,17 @@ static int __init gicv3_init(void)
res = gicv3_its_init();
if ( res )
panic("GICv3: ITS: initialization failed: %d\n", res);
/*
* Host LPI allocation uses ITS-derived memory attributes, so defer it
* until after gicv3_its_init() has discovered ITS workarounds.
*/
if ( gicv3_its_host_has_its() )
{
res = gicv3_lpi_init_host_lpis(intid_bits);
if ( res )
panic("GICv3: LPI initialization failed: %d\n", res);
}
}
res = gicv3_cpu_init();
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.