Update the FDT generation for the per-CPU PPI timers to be GICv5-compatible. In order to keep the code working for both older GICs and GICv5, we introduce an offset to the PPI IDs. The timer IRQs are redefined to be the absolute 0-based ID, i.e. the CNTP interrupt is changed from 14 to 30 (+16). For GICv5, these redefined IRQs are directly used. For other GICs, an offset of -16 is applied to revert these to the exected range for those systems. Signed-off-by: Sascha Bischoff --- arm64/timer.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/arm64/timer.c b/arm64/timer.c index 2ac6144f..9708f4f8 100644 --- a/arm64/timer.c +++ b/arm64/timer.c @@ -9,16 +9,30 @@ 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}; + int irqs[5] = {29, 30, 27, 26, 28}; int nr = ARRAY_SIZE(irqs); u32 irq_prop[nr * 3]; + u32 type, 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_FDT_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