Message ID | 20181119172536.52649-10-mimu@linux.ibm.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | KVM: s390: make use of the GIB | expand |
On Mon, 19 Nov 2018 18:25:33 +0100 Michael Mueller <mimu@linux.ibm.com> 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@linux.ibm.com> > --- > 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) {
On 26.11.18 16:57, Cornelia Huck wrote: > On Mon, 19 Nov 2018 18:25:33 +0100 > Michael Mueller <mimu@linux.ibm.com> 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@linux.ibm.com> >> --- >> 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; The check goes here. >> + /* 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? That's correct! > >> + } >> +} >> + >> void kvm_s390_gisa_clear(struct kvm *kvm) >> { >> if (kvm->arch.gisa) { >
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) {
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@linux.ibm.com> --- arch/s390/kvm/interrupt.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+)