On 10/25/2018 02:37 PM, Michael Mueller wrote: > The GIB (Guest Information Block) links the GISA of all guests > that have adapter interrupts pending. These interrupts cannot be > deliverd because no vcpu of these guests is currently running in > SIE context. Instead, a GIB alert is issued on the host to schedule > these guests to run. > > This mechanism allows to process adapter interrupts for currently > not running guests. > > The GIB is created during host initialization and associated with > the Adapter Interruption Facility in case an Adapter Interruption > Virtualization Facility is available. > > Signed-off-by: Michael Mueller <mimu@xxxxxxxxxxxxx> Some small nits below. Other than that Reviewed-by: Christian Borntraeger <borntraeger@xxxxxxxxxx> > --- > arch/s390/include/asm/kvm_host.h | 10 ++++++++ > arch/s390/kvm/interrupt.c | 43 ++++++++++++++++++++++++++++++++ > arch/s390/kvm/kvm-s390.c | 1 + > arch/s390/kvm/kvm-s390.h | 2 ++ > 4 files changed, 56 insertions(+) > > diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h > index 29c940bf8506..01be3b666b11 100644 > --- a/arch/s390/include/asm/kvm_host.h > +++ b/arch/s390/include/asm/kvm_host.h > @@ -776,6 +776,15 @@ struct kvm_s390_gisa { > }; > }; > > +struct kvm_s390_gib { > + atomic_t alert_list_origin; The only place that touches this is patch 5 (setting it to 0). All other activities are done by HW and that is why we need an atomic update. atomic_t does work as of today but you never know if we add some debugging code in the future that makes atomic_t bigger. Can we maybe just use an u32 here and then use cmpxchg in patch5? > + u32 reserved01; > + u8:5; > + u8 nisc:3; > + u8 reserved03[3]; > + u32 reserved04[5]; > +}; > + > /* > * sie_page2 has to be allocated as DMA because fac_list, crycb and > * gisa need 31bit addresses in the sie control block. > @@ -829,6 +838,7 @@ struct kvm_arch{ > /* subset of available cpu features enabled by user space */ > DECLARE_BITMAP(cpu_feat, KVM_S390_VM_CPU_FEAT_NR_BITS); > struct kvm_s390_gisa *gisa; > + int gib_in_use; > }; i> > #define KVM_HVA_ERR_BAD (-1UL) > diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c > index fcb55b02990e..3789a9ad8dee 100644 > --- a/arch/s390/kvm/interrupt.c > +++ b/arch/s390/kvm/interrupt.c > @@ -31,6 +31,8 @@ > #define PFAULT_DONE 0x0680 > #define VIRTIO_PARAM 0x0d00 > > +static struct kvm_s390_gib *gib; > + > /* handle external calls via sigp interpretation facility */ > static int sca_ext_call_pending(struct kvm_vcpu *vcpu, int *src_id) > { > @@ -2899,6 +2901,7 @@ void kvm_s390_gisa_init(struct kvm *kvm) > kvm->arch.gisa = &kvm->arch.sie_page2->gisa; > VM_EVENT(kvm, 3, "gisa 0x%pK initialized", kvm->arch.gisa); > kvm_s390_gisa_clear(kvm); > + kvm->arch.gib_in_use = !!gib; > } > } > > @@ -2908,3 +2911,43 @@ void kvm_s390_gisa_destroy(struct kvm *kvm) > return; > kvm->arch.gisa = NULL; > } > + > +void kvm_s390_gib_destroy(void) > +{ > + if (!gib) > + return; > + chsc_sgib(0); > + free_page((unsigned long)gib); > + gib = NULL; > +} > + > +void kvm_s390_gib_init(u8 nisc) > +{ > + int rc; > + > + if (gib) > + return; > + > + if (!css_general_characteristics.aiv) { > + KVM_EVENT(3, "%s", "gib not initialized, no AIV facility"); > + return; > + } > + > + gib = (struct kvm_s390_gib *)get_zeroed_page(GFP_KERNEL | GFP_DMA); > + if (!gib) { > + KVM_EVENT(3, "%s", "gib memory allocation failed"); > + return; > + } > + > + gib->nisc = nisc; > + rc = chsc_sgib((u32)(u64)gib); > + if (rc) { You could get rid of rc by doing if (chsc_sgib((u32)(u64)gib)) > + KVM_EVENT(3, "gib 0x%pK AIV association failed rc: %d", > + gib, rc); > + free_page((unsigned long)gib); > + gib = NULL; > + return; > + } > + > + KVM_EVENT(3, "gib 0x%pK (nisc=%d) initialized", gib, gib->nisc); > +} [...]