diff options
Diffstat (limited to 'target-s390x')
-rw-r--r-- | target-s390x/cpu.h | 1 | ||||
-rw-r--r-- | target-s390x/kvm.c | 19 |
2 files changed, 19 insertions, 1 deletions
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h index 9982c35fc2..b13761d925 100644 --- a/target-s390x/cpu.h +++ b/target-s390x/cpu.h @@ -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) { diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c index a2133ff1ce..a1a4cc2cab 100644 --- a/target-s390x/kvm.c +++ b/target-s390x/kvm.c @@ -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 = { |