[v2 2/2] arm: kvm: Update KVM interrupt injection arm

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The irq field on the irq_level struct has changed,

Meaning of the 'irq' parameter to KVM:

bits:  | 31 ... 24 | 23  ... 16 | 15    ...    0 |

irq_type[0]: out-of-kernel GIC: irq_number 0 is IRQ, irq_number 1 is FIQ
irq_type[1]: in-kernel GIC: SPI, irq_number between 32 and 1019 (incl.)
             (the vcpu_index field is ignored)
irq_type[2]: in-kernel GIC: PPI, irq_number between 16 and 31 (incl.)

This commit change both in-kernel gic and out of kernel gic support to
use the new scheme.

Signed-off-by: Christoffer Dall <c.dall@xxxxxxxxxxxxxxxxxxxxxx>
---
 hw/arm_pic.c     |    8 +++++---
 hw/kvm/arm_gic.c |   14 +++++++++-----
 2 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/hw/arm_pic.c b/hw/arm_pic.c
index 950e6c4..9609580 100644
--- a/hw/arm_pic.c
+++ b/hw/arm_pic.c
@@ -44,15 +44,17 @@ static void kvm_arm_pic_cpu_handler(void *opaque, int irq, int level)
 
     switch (irq) {
     case ARM_PIC_CPU_IRQ:
-        kvm_irq = KVM_ARM_IRQ_LINE;
+        kvm_irq = KVM_ARM_IRQ_TYPE_CPU << KVM_ARM_IRQ_TYPE_SHIFT;
+        kvm_irq += KVM_ARM_IRQ_CPU_IRQ;
         break;
     case ARM_PIC_CPU_FIQ:
-        kvm_irq = KVM_ARM_FIQ_LINE;
+        kvm_irq = KVM_ARM_IRQ_TYPE_CPU << KVM_ARM_IRQ_TYPE_SHIFT;
+        kvm_irq += KVM_ARM_IRQ_CPU_FIQ;
         break;
     default:
         hw_error("kvm_arm_pic_cpu_handler: Bad interrupt line %d\n", irq);
     }
-    kvm_irq |= (env->cpu_index << 1);
+    kvm_irq |= env->cpu_index << KVM_ARM_IRQ_VCPU_SHIFT;
     kvm_set_irq(kvm_state, kvm_irq, level ? 1 : 0);
 }
 #endif
diff --git a/hw/kvm/arm_gic.c b/hw/kvm/arm_gic.c
index 4535f90..76f52f9 100644
--- a/hw/kvm/arm_gic.c
+++ b/hw/kvm/arm_gic.c
@@ -45,22 +45,26 @@ static void kvm_arm_gic_set_irq(void *opaque, int irq, int level)
      *  ...
      */
     gic_state *s = (gic_state *)opaque;
+    int kvm_irq;
 
 
     if (irq < (s->num_irq - GIC_INTERNAL)) {
         /* External interrupt number 'irq' */
-        kvm_set_irq(kvm_state, irq + GIC_INTERNAL, !!level);
+        kvm_irq = KVM_ARM_IRQ_TYPE_SPI << KVM_ARM_IRQ_TYPE_SHIFT;
+        kvm_irq += irq + GIC_INTERNAL;
     } else {
-        struct kvm_irq_level irq_level;
         int cpu;
         irq -= (s->num_irq - GIC_INTERNAL);
         cpu = irq / GIC_INTERNAL;
         irq %= GIC_INTERNAL;
+
         /* Internal interrupt 'irq' for CPU 'cpu' */
-        irq_level.irq = irq;
-        irq_level.level = !!level;
-        kvm_vcpu_ioctl(qemu_get_cpu(cpu), KVM_IRQ_LINE, &irq_level);
+        kvm_irq = KVM_ARM_IRQ_TYPE_PPI << KVM_ARM_IRQ_TYPE_SHIFT;
+        kvm_irq |= (cpu << KVM_ARM_IRQ_VCPU_SHIFT);
+        kvm_irq += irq;
     }
+
+    kvm_set_irq(kvm_state, kvm_irq, !!level);
 }
 
 static void kvm_arm_gic_put(gic_state *s)
-- 
1.7.9.5

_______________________________________________
kvmarm mailing list
kvmarm@xxxxxxxxxxxxxxxxxxxxx
https://lists.cs.columbia.edu/cucslists/listinfo/kvmarm


[Index of Archives]     [Linux KVM]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux