--- /dev/null
+From fc57ac2c9ca8109ea97fcc594f4be436944230cc Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Wed, 14 May 2014 17:40:58 +0200
+Subject: KVM: lapic: sync highest ISR to hardware apic on EOI
+
+From: Paolo Bonzini <pbonzini@redhat.com>
+
+commit fc57ac2c9ca8109ea97fcc594f4be436944230cc upstream.
+
+When Hyper-V enlightenments are in effect, Windows prefers to issue an
+Hyper-V MSR write to issue an EOI rather than an x2apic MSR write.
+The Hyper-V MSR write is not handled by the processor, and besides
+being slower, this also causes bugs with APIC virtualization. The
+reason is that on EOI the processor will modify the highest in-service
+interrupt (SVI) field of the VMCS, as explained in section 29.1.4 of
+the SDM; every other step in EOI virtualization is already done by
+apic_send_eoi or on VM entry, but this one is missing.
+
+We need to do the same, and be careful not to muck with the isr_count
+and highest_isr_cache fields that are unused when virtual interrupt
+delivery is enabled.
+
+Reviewed-by: Yang Zhang <yang.z.zhang@intel.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/kvm/lapic.c | 62 +++++++++++++++++++++++++++++++++++----------------
+ 1 file changed, 43 insertions(+), 19 deletions(-)
+
+--- a/arch/x86/kvm/lapic.c
++++ b/arch/x86/kvm/lapic.c
+@@ -360,6 +360,8 @@ static inline void apic_clear_irr(int ve
+
+ static inline void apic_set_isr(int vec, struct kvm_lapic *apic)
+ {
++ /* Note that we never get here with APIC virtualization enabled. */
++
+ if (!__apic_test_and_set_vector(vec, apic->regs + APIC_ISR))
+ ++apic->isr_count;
+ BUG_ON(apic->isr_count > MAX_APIC_VECTOR);
+@@ -371,12 +373,48 @@ static inline void apic_set_isr(int vec,
+ apic->highest_isr_cache = vec;
+ }
+
++static inline int apic_find_highest_isr(struct kvm_lapic *apic)
++{
++ int result;
++
++ /*
++ * Note that isr_count is always 1, and highest_isr_cache
++ * is always -1, with APIC virtualization enabled.
++ */
++ if (!apic->isr_count)
++ return -1;
++ if (likely(apic->highest_isr_cache != -1))
++ return apic->highest_isr_cache;
++
++ result = find_highest_vector(apic->regs + APIC_ISR);
++ ASSERT(result == -1 || result >= 16);
++
++ return result;
++}
++
+ static inline void apic_clear_isr(int vec, struct kvm_lapic *apic)
+ {
+- if (__apic_test_and_clear_vector(vec, apic->regs + APIC_ISR))
++ struct kvm_vcpu *vcpu;
++ if (!__apic_test_and_clear_vector(vec, apic->regs + APIC_ISR))
++ return;
++
++ vcpu = apic->vcpu;
++
++ /*
++ * We do get here for APIC virtualization enabled if the guest
++ * uses the Hyper-V APIC enlightenment. In this case we may need
++ * to trigger a new interrupt delivery by writing the SVI field;
++ * on the other hand isr_count and highest_isr_cache are unused
++ * and must be left alone.
++ */
++ if (unlikely(kvm_apic_vid_enabled(vcpu->kvm)))
++ kvm_x86_ops->hwapic_isr_update(vcpu->kvm,
++ apic_find_highest_isr(apic));
++ else {
+ --apic->isr_count;
+- BUG_ON(apic->isr_count < 0);
+- apic->highest_isr_cache = -1;
++ BUG_ON(apic->isr_count < 0);
++ apic->highest_isr_cache = -1;
++ }
+ }
+
+ int kvm_lapic_find_highest_irr(struct kvm_vcpu *vcpu)
+@@ -456,22 +494,6 @@ static void pv_eoi_clr_pending(struct kv
+ __clear_bit(KVM_APIC_PV_EOI_PENDING, &vcpu->arch.apic_attention);
+ }
+
+-static inline int apic_find_highest_isr(struct kvm_lapic *apic)
+-{
+- int result;
+-
+- /* Note that isr_count is always 1 with vid enabled */
+- if (!apic->isr_count)
+- return -1;
+- if (likely(apic->highest_isr_cache != -1))
+- return apic->highest_isr_cache;
+-
+- result = find_highest_vector(apic->regs + APIC_ISR);
+- ASSERT(result == -1 || result >= 16);
+-
+- return result;
+-}
+-
+ void kvm_apic_update_tmr(struct kvm_vcpu *vcpu, u32 *tmr)
+ {
+ struct kvm_lapic *apic = vcpu->arch.apic;
+@@ -1605,6 +1627,8 @@ int kvm_get_apic_interrupt(struct kvm_vc
+ int vector = kvm_apic_has_interrupt(vcpu);
+ struct kvm_lapic *apic = vcpu->arch.apic;
+
++ /* Note that we never get here with APIC virtualization enabled. */
++
+ if (vector == -1)
+ return -1;
+
--- /dev/null
+From 67335e63c9ef59e97b45a08b4a6a93767762031d Mon Sep 17 00:00:00 2001
+From: Christian Borntraeger <borntraeger@de.ibm.com>
+Date: Tue, 25 Mar 2014 17:09:08 +0100
+Subject: KVM: s390: Drop pending interrupts on guest exit
+
+From: Christian Borntraeger <borntraeger@de.ibm.com>
+
+commit 67335e63c9ef59e97b45a08b4a6a93767762031d upstream.
+
+On hard exits (abort, sigkill) we have have some kvm_s390_interrupt_info
+structures hanging around. Delete those on exit to avoid memory leaks.
+
+Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
+Reviewed-by: Thomas Huth <thuth@linux.vnet.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/s390/kvm/interrupt.c | 4 ++--
+ arch/s390/kvm/kvm-s390.c | 2 ++
+ arch/s390/kvm/kvm-s390.h | 1 +
+ 3 files changed, 5 insertions(+), 2 deletions(-)
+
+--- a/arch/s390/kvm/interrupt.c
++++ b/arch/s390/kvm/interrupt.c
+@@ -900,7 +900,7 @@ int kvm_s390_inject_vcpu(struct kvm_vcpu
+ return 0;
+ }
+
+-static void clear_floating_interrupts(struct kvm *kvm)
++void kvm_s390_clear_float_irqs(struct kvm *kvm)
+ {
+ struct kvm_s390_float_interrupt *fi;
+ struct kvm_s390_interrupt_info *n, *inti = NULL;
+@@ -1246,7 +1246,7 @@ static int flic_set_attr(struct kvm_devi
+ break;
+ case KVM_DEV_FLIC_CLEAR_IRQS:
+ r = 0;
+- clear_floating_interrupts(dev->kvm);
++ kvm_s390_clear_float_irqs(dev->kvm);
+ break;
+ case KVM_DEV_FLIC_APF_ENABLE:
+ dev->kvm->arch.gmap->pfault_enabled = 1;
+--- a/arch/s390/kvm/kvm-s390.c
++++ b/arch/s390/kvm/kvm-s390.c
+@@ -322,6 +322,7 @@ void kvm_arch_vcpu_destroy(struct kvm_vc
+ {
+ VCPU_EVENT(vcpu, 3, "%s", "free cpu");
+ trace_kvm_s390_destroy_vcpu(vcpu->vcpu_id);
++ kvm_s390_clear_local_irqs(vcpu);
+ kvm_clear_async_pf_completion_queue(vcpu);
+ if (!kvm_is_ucontrol(vcpu->kvm)) {
+ clear_bit(63 - vcpu->vcpu_id,
+@@ -372,6 +373,7 @@ void kvm_arch_destroy_vm(struct kvm *kvm
+ if (!kvm_is_ucontrol(kvm))
+ gmap_free(kvm->arch.gmap);
+ kvm_s390_destroy_adapters(kvm);
++ kvm_s390_clear_float_irqs(kvm);
+ }
+
+ /* Section: vcpu related */
+--- a/arch/s390/kvm/kvm-s390.h
++++ b/arch/s390/kvm/kvm-s390.h
+@@ -130,6 +130,7 @@ void kvm_s390_tasklet(unsigned long parm
+ void kvm_s390_deliver_pending_interrupts(struct kvm_vcpu *vcpu);
+ void kvm_s390_deliver_pending_machine_checks(struct kvm_vcpu *vcpu);
+ void kvm_s390_clear_local_irqs(struct kvm_vcpu *vcpu);
++void kvm_s390_clear_float_irqs(struct kvm *kvm);
+ int __must_check kvm_s390_inject_vm(struct kvm *kvm,
+ struct kvm_s390_interrupt *s390int);
+ int __must_check kvm_s390_inject_vcpu(struct kvm_vcpu *vcpu,