On Mon, 19 Nov 2018 18:25:33 +0100 Michael Mueller <mimu@xxxxxxxxxxxxx> wrote: > This function processes a gib alert list. It is required to > run when either a gib alert interruption has been received or > a gisa that might be in the alert list is cleared or dropped. > > Signed-off-by: Michael Mueller <mimu@xxxxxxxxxxxxx> > --- > arch/s390/kvm/interrupt.c | 28 ++++++++++++++++++++++++++++ > 1 file changed, 28 insertions(+) > > diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c > index 8676596f6b5c..443d1804d611 100644 > --- a/arch/s390/kvm/interrupt.c > +++ b/arch/s390/kvm/interrupt.c > @@ -2910,6 +2910,34 @@ static void nullify_gisa(struct kvm_s390_gisa *gisa) > gisa->next_alert = (u32)(u64)gisa; > } > > +/* > + * Before processing, the gib alert list needs to be cut-off from > + * the gib by means of function unlink_gib_alert_list(). If non NULL, > + * the list is processed from its latest to oldest entry. > + * > + * Processing an gisa entry needs to wake-up a vcpu of the kvm this gisa > + * belongs to. Thus, the pending guest interruption will be processed > + * in SIE context. > + */ > +static void __maybe_unused process_gib_alert_list(void) > +{ > + struct kvm_s390_gisa *gisa = unlink_gib_alert_list(); > + struct kvm_s390_gisa *next_alert; > + struct kvm_vcpu *vcpu; > + struct kvm *kvm; > + > + for (; gisa; gisa = next_alert) { > + next_alert = (struct kvm_s390_gisa *)(u64)gisa->next_alert; > + /* unlink from alert list */ > + gisa->next_alert = (u32)(u64)gisa; > + /* wake-up a vcpu of the kvm this gisa belongs to */ > + kvm = container_of(gisa, struct sie_page2, gisa)->kvm; > + vcpu = __find_vcpu_for_floating_irq(kvm); > + if (vcpu) > + kvm_s390_vcpu_wakeup(vcpu); Just to check if I understood correctly: This loop is where you'll add the extra check whether the interrupt has already been delivered, right? > + } > +} > + > void kvm_s390_gisa_clear(struct kvm *kvm) > { > if (kvm->arch.gisa) {