summary refs log tree commit diff stats
path: root/hw/arm/pic_cpu.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/arm/pic_cpu.c')
-rw-r--r--hw/arm/pic_cpu.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/hw/arm/pic_cpu.c b/hw/arm/pic_cpu.c
index a7ad893cc2..82236006d2 100644
--- a/hw/arm/pic_cpu.c
+++ b/hw/arm/pic_cpu.c
@@ -9,6 +9,7 @@
 
 #include "hw/hw.h"
 #include "hw/arm-misc.h"
+#include "sysemu/kvm.h"
 
 /* Input 0 is IRQ and input 1 is FIQ.  */
 static void arm_pic_cpu_handler(void *opaque, int irq, int level)
@@ -34,7 +35,32 @@ static void arm_pic_cpu_handler(void *opaque, int irq, int level)
     }
 }
 
+static void kvm_arm_pic_cpu_handler(void *opaque, int irq, int level)
+{
+#ifdef CONFIG_KVM
+    ARMCPU *cpu = opaque;
+    CPUState *cs = CPU(cpu);
+    int kvm_irq = KVM_ARM_IRQ_TYPE_CPU << KVM_ARM_IRQ_TYPE_SHIFT;
+
+    switch (irq) {
+    case ARM_PIC_CPU_IRQ:
+        kvm_irq |= KVM_ARM_IRQ_CPU_IRQ;
+        break;
+    case ARM_PIC_CPU_FIQ:
+        kvm_irq |= KVM_ARM_IRQ_CPU_FIQ;
+        break;
+    default:
+        hw_error("kvm_arm_pic_cpu_handler: Bad interrupt line %d\n", irq);
+    }
+    kvm_irq |= cs->cpu_index << KVM_ARM_IRQ_VCPU_SHIFT;
+    kvm_set_irq(kvm_state, kvm_irq, level ? 1 : 0);
+#endif
+}
+
 qemu_irq *arm_pic_init_cpu(ARMCPU *cpu)
 {
+    if (kvm_enabled()) {
+        return qemu_allocate_irqs(kvm_arm_pic_cpu_handler, cpu, 2);
+    }
     return qemu_allocate_irqs(arm_pic_cpu_handler, cpu, 2);
 }