return NULL;
 }
 
+static struct kvm_s390_interrupt_info *get_top_io_int(struct kvm *kvm,
+                                                     u64 isc_mask, u32 schid)
+{
+       struct kvm_s390_interrupt_info *inti = NULL;
+       int isc;
+
+       for (isc = 0; isc <= MAX_ISC && !inti; isc++) {
+               if (isc_mask & isc_to_isc_bits(isc))
+                       inti = get_io_int(kvm, isc, schid);
+       }
+       return inti;
+}
+
+static int get_top_gisa_isc(struct kvm *kvm, u64 isc_mask, u32 schid)
+{
+       unsigned long active_mask;
+       int isc;
+
+       if (schid)
+               goto out;
+       if (!kvm->arch.gisa)
+               goto out;
+
+       active_mask = (isc_mask & kvm_s390_gisa_get_ipm(kvm->arch.gisa) << 24) << 32;
+       while (active_mask) {
+               isc = __fls(active_mask) ^ (BITS_PER_LONG - 1);
+               if (kvm_s390_gisa_tac_ipm_gisc(kvm->arch.gisa, isc))
+                       return isc;
+               clear_bit_inv(isc, &active_mask);
+       }
+out:
+       return -EINVAL;
+}
+
 /*
  * Dequeue and return an I/O interrupt matching any of the interruption
  * subclasses as designated by the isc mask in cr6 and the schid (if != 0).
+ * Take into account the interrupts pending in the interrupt list and in GISA.
+ *
+ * Note that for a guest that does not enable I/O interrupts
+ * but relies on TPI, a flood of classic interrupts may starve
+ * out adapter interrupts on the same isc. Linux does not do
+ * that, and it is possible to work around the issue by configuring
+ * different iscs for classic and adapter interrupts in the guest,
+ * but we may want to revisit this in the future.
  */
 struct kvm_s390_interrupt_info *kvm_s390_get_io_int(struct kvm *kvm,
                                                    u64 isc_mask, u32 schid)
 {
-       struct kvm_s390_interrupt_info *inti = NULL;
+       struct kvm_s390_interrupt_info *inti, *tmp_inti;
        int isc;
 
-       for (isc = 0; isc <= MAX_ISC && !inti; isc++) {
-               if (isc_mask & isc_to_isc_bits(isc))
-                       inti = get_io_int(kvm, isc, schid);
+       inti = get_top_io_int(kvm, isc_mask, schid);
+
+       isc = get_top_gisa_isc(kvm, isc_mask, schid);
+       if (isc < 0)
+               /* no AI in GISA */
+               goto out;
+
+       if (!inti)
+               /* AI in GISA but no classical IO int */
+               goto gisa_out;
+
+       /* both types of interrupts present */
+       if (int_word_to_isc(inti->io.io_int_word) <= isc) {
+               /* classical IO int with higher priority */
+               kvm_s390_gisa_set_ipm_gisc(kvm->arch.gisa, isc);
+               goto out;
        }
+gisa_out:
+       tmp_inti = kzalloc(sizeof(*inti), GFP_KERNEL);
+       if (tmp_inti) {
+               tmp_inti->type = KVM_S390_INT_IO(1, 0, 0, 0);
+               tmp_inti->io.io_int_word = isc_to_int_word(isc);
+               if (inti)
+                       kvm_s390_reinject_io_int(kvm, inti);
+               inti = tmp_inti;
+       } else
+               kvm_s390_gisa_set_ipm_gisc(kvm->arch.gisa, isc);
+out:
        return inti;
 }