summary refs log tree commit diff stats
path: root/kvm-all.c
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2015-12-17 17:16:08 +0100
committerPaolo Bonzini <pbonzini@redhat.com>2015-12-17 17:33:47 +0100
commit15eafc2e602ff8c37c6e132eb8c63fec8fc17175 (patch)
treee37c79eac125c083389e8bde03b8d3e048c22b0a /kvm-all.c
parent32c18a2dbaf79c241eddabd19a3b410bab5bf0cc (diff)
downloadfocaccia-qemu-15eafc2e602ff8c37c6e132eb8c63fec8fc17175.tar.gz
focaccia-qemu-15eafc2e602ff8c37c6e132eb8c63fec8fc17175.zip
kvm: x86: add support for KVM_CAP_SPLIT_IRQCHIP
This patch adds support for split IRQ chip mode. When
KVM_CAP_SPLIT_IRQCHIP is enabled:

    1.) The PIC, PIT, and IOAPIC are implemented in userspace while
    the LAPIC is implemented by KVM.

    2.) The software IOAPIC delivers interrupts to the KVM LAPIC via
    kvm_set_irq. Interrupt delivery is configured via the MSI routing
    table, for which routes are reserved in target-i386/kvm.c then
    configured in hw/intc/ioapic.c

    3.) KVM delivers IOAPIC EOIs via a new exit KVM_EXIT_IOAPIC_EOI,
    which is handled in target-i386/kvm.c and relayed to the software
    IOAPIC via ioapic_eoi_broadcast.

Signed-off-by: Matt Gingell <gingell@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'kvm-all.c')
-rw-r--r--kvm-all.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/kvm-all.c b/kvm-all.c
index e78a3786d6..bd9e7641b2 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -99,6 +99,7 @@ struct KVMState
 
 KVMState *kvm_state;
 bool kvm_kernel_irqchip;
+bool kvm_split_irqchip;
 bool kvm_async_interrupts_allowed;
 bool kvm_halt_in_kernel_allowed;
 bool kvm_eventfds_allowed;
@@ -1430,9 +1431,14 @@ static void kvm_irqchip_create(MachineState *machine, KVMState *s)
 
     /* First probe and see if there's a arch-specific hook to create the
      * in-kernel irqchip for us */
-    ret = kvm_arch_irqchip_create(s);
+    ret = kvm_arch_irqchip_create(machine, s);
     if (ret == 0) {
-        ret = kvm_vm_ioctl(s, KVM_CREATE_IRQCHIP);
+        if (machine_kernel_irqchip_split(machine)) {
+            perror("Split IRQ chip mode not supported.");
+            exit(1);
+        } else {
+            ret = kvm_vm_ioctl(s, KVM_CREATE_IRQCHIP);
+        }
     }
     if (ret < 0) {
         fprintf(stderr, "Create kernel irqchip failed: %s\n", strerror(-ret));