GICv5 DT specifiers use absolute PPI numbers due to having separate namespaces for the different interrupt types. Keep the existing GICv2/v3 specifiers by subtracting the legacy PPI base for those irqchips. Signed-off-by: Sascha Bischoff --- arm64/timer.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/arm64/timer.c b/arm64/timer.c index 2ac6144f..b791956b 100644 --- a/arm64/timer.c +++ b/arm64/timer.c @@ -9,16 +9,31 @@ void timer__generate_fdt_nodes(void *fdt, struct kvm *kvm) { const char compatible[] = "arm,armv8-timer\0arm,armv7-timer"; u32 cpu_mask = gic__get_fdt_irq_cpumask(kvm); - int irqs[5] = {13, 14, 11, 10, 12}; + const int irqs[5] = { 29, 30, 27, 26, 28 }; int nr = ARRAY_SIZE(irqs); u32 irq_prop[nr * 3]; + u32 type; + int offset; if (!kvm->cfg.arch.nested_virt) nr--; + /* + * For GICv5 guests, we can directly use the IRQs above in the FDT, but + * for older GICs one specifies the offset into the PPI range, which is + * adjusted using the offset below. + */ + if (gic__is_v5()) { + type = GICV5_IRQ_TYPE_PPI; + offset = 0; + } else { + type = GIC_FDT_IRQ_TYPE_PPI; + offset = -16; + } + for (int i = 0; i < nr; i++) { - irq_prop[i * 3 + 0] = cpu_to_fdt32(GIC_FDT_IRQ_TYPE_PPI); - irq_prop[i * 3 + 1] = cpu_to_fdt32(irqs[i]); + irq_prop[i * 3 + 0] = cpu_to_fdt32(type); + irq_prop[i * 3 + 1] = cpu_to_fdt32(irqs[i] + offset); irq_prop[i * 3 + 2] = cpu_to_fdt32(cpu_mask | IRQ_TYPE_LEVEL_LOW); } -- 2.34.1