If kvm_irqchip_in_kernel option is set, set property irqchip-in-kernel with ExtIOI, IPI, PCH_PCI and PCH_MSI interrupt controller, so that irqchip in kernel is supported.
Signed-off-by: Bibo Mao <maob...@loongson.cn> --- hw/loongarch/virt.c | 15 +++++++++++++++ target/loongarch/cpu.h | 1 + target/loongarch/kvm/kvm.c | 16 ++++++++++++++++ 3 files changed, 32 insertions(+) diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c index 1b504047db..a79e77e663 100644 --- a/hw/loongarch/virt.c +++ b/hw/loongarch/virt.c @@ -398,6 +398,9 @@ static void virt_irq_init(LoongArchVirtMachineState *lvms) /* Create IPI device */ ipi = qdev_new(TYPE_LOONGARCH_IPI); + if (kvm_irqchip_in_kernel()) { + qdev_prop_set_bit(ipi, "irqchip-in-kernel", true); + } lvms->ipi = ipi; sysbus_realize_and_unref(SYS_BUS_DEVICE(ipi), &error_fatal); @@ -413,6 +416,9 @@ static void virt_irq_init(LoongArchVirtMachineState *lvms) if (virt_is_veiointc_enabled(lvms)) { qdev_prop_set_bit(extioi, "has-virtualization-extension", true); } + if (kvm_irqchip_in_kernel()) { + qdev_prop_set_bit(extioi, "irqchip-in-kernel", true); + } sysbus_realize_and_unref(SYS_BUS_DEVICE(extioi), &error_fatal); memory_region_add_subregion(&lvms->system_iocsr, APIC_BASE, sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi), 0)); @@ -423,6 +429,9 @@ static void virt_irq_init(LoongArchVirtMachineState *lvms) virt_cpu_irq_init(lvms); pch_pic = qdev_new(TYPE_LOONGARCH_PIC); + if (kvm_irqchip_in_kernel()) { + qdev_prop_set_bit(pch_pic, "irqchip-in-kernel", true); + } num = VIRT_PCH_PIC_IRQ_NUM; qdev_prop_set_uint32(pch_pic, "pch_pic_irq_num", num); d = SYS_BUS_DEVICE(pch_pic); @@ -436,6 +445,9 @@ static void virt_irq_init(LoongArchVirtMachineState *lvms) } pch_msi = qdev_new(TYPE_LOONGARCH_PCH_MSI); + if (kvm_irqchip_in_kernel()) { + qdev_prop_set_bit(pch_msi, "irqchip-in-kernel", true); + } start = num; num = EXTIOI_IRQS - start; qdev_prop_set_uint32(pch_msi, "msi_irq_base", start); @@ -449,6 +461,9 @@ static void virt_irq_init(LoongArchVirtMachineState *lvms) qdev_get_gpio_in(extioi, i + start)); } + if (kvm_irqchip_in_kernel()) { + kvm_loongarch_init_irq_routing(); + } virt_devices_init(pch_pic, lvms); } diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h index 262bf87f7b..9538e8d61d 100644 --- a/target/loongarch/cpu.h +++ b/target/loongarch/cpu.h @@ -503,5 +503,6 @@ static inline void kvm_loongarch_cpu_post_init(LoongArchCPU *cpu) { } #endif +void kvm_loongarch_init_irq_routing(void); #endif /* LOONGARCH_CPU_H */ diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c index a8e5724b21..52a54f286b 100644 --- a/target/loongarch/kvm/kvm.c +++ b/target/loongarch/kvm/kvm.c @@ -1236,6 +1236,22 @@ void kvm_arch_init_irq_routing(KVMState *s) { } +void kvm_loongarch_init_irq_routing(void) +{ + int i; + + kvm_async_interrupts_allowed = true; + kvm_msi_via_irqfd_allowed = kvm_irqfds_enabled(); + if (kvm_has_gsi_routing()) { + for (i = 0; i < 64; ++i) { + kvm_irqchip_add_irq_route(kvm_state, i, 0, i); + } + + kvm_gsi_routing_allowed = true; + kvm_irqchip_commit_routes(kvm_state); + } +} + int kvm_arch_get_default_type(MachineState *ms) { return 0; -- 2.39.3