Implement the routing of PC's interrupt gpio to intc, and retrieve the gsi.
Signed-off-by: Liu Ping Fan <pingf...@linux.vnet.ibm.com> --- hw/core/qdev.c | 8 ++++++++ hw/i386/kvm/i8259.c | 8 +++++++- hw/i386/kvm/ioapic.c | 21 ++++++++++++++++++++- hw/i386/pc_q35.c | 4 ++-- include/hw/qdev-core.h | 2 ++ include/sysemu/kvm.h | 1 + 6 files changed, 40 insertions(+), 4 deletions(-) diff --git a/hw/core/qdev.c b/hw/core/qdev.c index 758de9f..63605d1 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -312,6 +312,14 @@ void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n) dev->num_gpio_in += n; } +void qdev_init_gpio_in_2(DeviceState *dev, qemu_irq_handler handler, + qemu_irq_route route, int n) +{ + dev->gpio_in = qemu_extend_irqs_2(dev->gpio_in, dev->num_gpio_in, handler, + route, dev, n); + dev->num_gpio_in += n; +} + void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n) { assert(dev->num_gpio_out == 0); diff --git a/hw/i386/kvm/i8259.c b/hw/i386/kvm/i8259.c index 53e3ca8..1193b54 100644 --- a/hw/i386/kvm/i8259.c +++ b/hw/i386/kvm/i8259.c @@ -106,6 +106,11 @@ static void kvm_pic_reset(DeviceState *dev) kvm_pic_put(s); } +static int kvm_pic_route_gsi(void *opaque, int irq) +{ + return irq; +} + static void kvm_pic_set_irq(void *opaque, int irq, int level) { int delivered; @@ -130,7 +135,8 @@ qemu_irq *kvm_i8259_init(ISABus *bus) i8259_init_chip(TYPE_KVM_I8259, bus, true); i8259_init_chip(TYPE_KVM_I8259, bus, false); - return qemu_allocate_irqs(kvm_pic_set_irq, NULL, ISA_NUM_IRQS); + return qemu_extend_irqs_2(NULL, 0, kvm_pic_set_irq, kvm_pic_route_gsi, + NULL, ISA_NUM_IRQS); } static void kvm_i8259_class_init(ObjectClass *klass, void *data) diff --git a/hw/i386/kvm/ioapic.c b/hw/i386/kvm/ioapic.c index f11a540..1e6ff0b 100644 --- a/hw/i386/kvm/ioapic.c +++ b/hw/i386/kvm/ioapic.c @@ -44,6 +44,19 @@ void kvm_pc_setup_irq_routing(bool pci_enabled) } } +int kvm_pc_route_gsi(void *opaque, int n) +{ + GSIState *s = opaque; + int gsi; + + if (n < ISA_NUM_IRQS) { + gsi = qemu_irq_route_gsi(s->i8259_irq[n]); + } else { + gsi = qemu_irq_route_gsi(s->ioapic_irq[n]); + } + return gsi; +} + void kvm_pc_gsi_handler(void *opaque, int n, int level) { GSIState *s = opaque; @@ -127,11 +140,17 @@ static void kvm_ioapic_set_irq(void *opaque, int irq, int level) apic_report_irq_delivered(delivered); } +static int kvm_ioapic_route_irq(void *opaque, int irq) +{ + return irq; +} + static void kvm_ioapic_init(IOAPICCommonState *s, int instance_no) { memory_region_init_reservation(&s->io_memory, NULL, "kvm-ioapic", 0x1000); - qdev_init_gpio_in(DEVICE(s), kvm_ioapic_set_irq, IOAPIC_NUM_PINS); + qdev_init_gpio_in_2(DEVICE(s), kvm_ioapic_set_irq, kvm_ioapic_route_irq, + IOAPIC_NUM_PINS); } static Property kvm_ioapic_properties[] = { diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index 198c785..df1deb3 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -120,8 +120,8 @@ static void pc_q35_init(QEMUMachineInitArgs *args) gsi_state = g_malloc0(sizeof(*gsi_state)); if (kvm_irqchip_in_kernel()) { kvm_pc_setup_irq_routing(pci_enabled); - gsi = qemu_allocate_irqs(kvm_pc_gsi_handler, gsi_state, - GSI_NUM_PINS); + gsi = qemu_extend_irqs_2(NULL, 0, kvm_pc_gsi_handler, + kvm_pc_route_gsi, gsi_state, GSI_NUM_PINS); } else { gsi = qemu_allocate_irqs(gsi_handler, gsi_state, GSI_NUM_PINS); } diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index 46972f4..4b8eb35 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -252,6 +252,8 @@ BusState *qdev_get_child_bus(DeviceState *dev, const char *name); /* Register device properties. */ /* GPIO inputs also double as IRQ sinks. */ void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n); +void qdev_init_gpio_in_2(DeviceState *dev, qemu_irq_handler handler, + qemu_irq_route route, int n); void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n); BusState *qdev_get_parent_bus(DeviceState *dev); diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h index 8e76685..47cc012 100644 --- a/include/sysemu/kvm.h +++ b/include/sysemu/kvm.h @@ -312,6 +312,7 @@ void kvm_irqchip_release_virq(KVMState *s, int virq); int kvm_irqchip_add_irqfd_notifier(KVMState *s, EventNotifier *n, EventNotifier *rn, int virq); int kvm_irqchip_remove_irqfd_notifier(KVMState *s, EventNotifier *n, int virq); +int kvm_pc_route_gsi(void *opaque, int n); void kvm_pc_gsi_handler(void *opaque, int n, int level); void kvm_pc_setup_irq_routing(bool pci_enabled); void kvm_init_irq_routing(KVMState *s); -- 1.8.1.4