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


Reply via email to