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); + } +} + void kvm_s390_gisa_clear(struct kvm *kvm) { if (kvm->arch.gisa) { -- 2.13.4