]> rtime.felk.cvut.cz Git - lisovros/qemu_apohw.git/commitdiff
s390x/kvm: inject via flic
authorCornelia Huck <cornelia.huck@de.ibm.com>
Wed, 12 Mar 2014 11:40:31 +0000 (12:40 +0100)
committerCornelia Huck <cornelia.huck@de.ibm.com>
Tue, 10 Jun 2014 07:50:27 +0000 (09:50 +0200)
Try to inject floating interrupts via the flic if it is available.
This allows us to inject the full range of floating interrupts.

Reviewed-by: Jens Freimann <jfrei@linux.vnet.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
hw/intc/s390_flic_kvm.c
target-s390x/cpu.h
target-s390x/kvm.c

index a734094292c07d44e301f2b5c06de74c659e9f54..b471e7a41e46c86148db9f44e810542da500b430 100644 (file)
@@ -117,6 +117,16 @@ static int flic_enqueue_irqs(void *buf, uint64_t len,
     return rc ? -errno : 0;
 }
 
+int kvm_s390_inject_flic(struct kvm_s390_irq *irq)
+{
+    static KVMS390FLICState *flic;
+
+    if (unlikely(!flic)) {
+        flic = KVM_S390_FLIC(s390_get_flic());
+    }
+    return flic_enqueue_irqs(irq, sizeof(*irq), flic);
+}
+
 /**
  * __get_all_irqs - store all pending irqs in buffer
  * @flic: pointer to flic device state
index 9982c35fc21cebce7d6e49c5aefd33acfffb6213..b13761d9250405caa26bd2575363ff0639f12f72 100644 (file)
@@ -365,6 +365,7 @@ void kvm_s390_virtio_irq(int config_change, uint64_t token);
 void kvm_s390_service_interrupt(uint32_t parm);
 void kvm_s390_vcpu_interrupt(S390CPU *cpu, struct kvm_s390_irq *irq);
 void kvm_s390_floating_interrupt(struct kvm_s390_irq *irq);
+int kvm_s390_inject_flic(struct kvm_s390_irq *irq);
 #else
 static inline void kvm_s390_reset_vcpu(S390CPU *cpu)
 {
index a2133ff1cef259ba652f238cfe5f30b813f68fe2..a1a4cc2cab8c0ae7e7ab4a50781c472dec3c9ca5 100644 (file)
@@ -623,7 +623,7 @@ void kvm_s390_vcpu_interrupt(S390CPU *cpu, struct kvm_s390_irq *irq)
     }
 }
 
-void kvm_s390_floating_interrupt(struct kvm_s390_irq *irq)
+static void __kvm_s390_floating_interrupt(struct kvm_s390_irq *irq)
 {
     struct kvm_s390_interrupt kvmint = {};
     int r;
@@ -641,6 +641,23 @@ void kvm_s390_floating_interrupt(struct kvm_s390_irq *irq)
     }
 }
 
+void kvm_s390_floating_interrupt(struct kvm_s390_irq *irq)
+{
+    static bool use_flic = true;
+    int r;
+
+    if (use_flic) {
+        r = kvm_s390_inject_flic(irq);
+        if (r == -ENOSYS) {
+            use_flic = false;
+        }
+        if (!r) {
+            return;
+        }
+    }
+    __kvm_s390_floating_interrupt(irq);
+}
+
 void kvm_s390_virtio_irq(int config_change, uint64_t token)
 {
     struct kvm_s390_irq irq = {