From mboxrd@z Thu Jan 1 00:00:00 1970 From: Christian Borntraeger Subject: [PATCH 09/12] KVM: s390: make kvm_s390_get_io_int() aware of GISA Date: Tue, 16 Jan 2018 21:02:14 +0100 Message-ID: <20180116200217.211897-10-borntraeger@de.ibm.com> References: <20180116200217.211897-1-borntraeger@de.ibm.com> Cc: KVM , Christian Borntraeger , linux-s390 , Janosch Frank , David Hildenbrand , Michael Mueller To: Cornelia Huck Return-path: Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:57966 "EHLO mx0a-001b2d01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752041AbeAPUCd (ORCPT ); Tue, 16 Jan 2018 15:02:33 -0500 Received: from pps.filterd (m0098410.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id w0GK25Dw028437 for ; Tue, 16 Jan 2018 15:02:33 -0500 Received: from e06smtp15.uk.ibm.com (e06smtp15.uk.ibm.com [195.75.94.111]) by mx0a-001b2d01.pphosted.com with ESMTP id 2fhmepa8p6-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Tue, 16 Jan 2018 15:02:33 -0500 Received: from localhost by e06smtp15.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Tue, 16 Jan 2018 20:02:30 -0000 In-Reply-To: <20180116200217.211897-1-borntraeger@de.ibm.com> Sender: kvm-owner@vger.kernel.org List-ID: From: Michael Mueller The function returns a pending I/O interrupt with the highest priority defined by its ISC. Together with AIV activation, pending adapter interrupts are managed by the GISA IPM. Thus kvm_s390_get_io_int() needs to inspect the IPM as well when the interrupt with the highest priority has to be identified. In case classic and adapter interrupts with the same ISC are pending, the classic interrupt will be returned first. Signed-off-by: Michael Mueller Reviewed-by: Halil Pasic Reviewed-by: Christian Borntraeger Signed-off-by: Christian Borntraeger --- arch/s390/kvm/interrupt.c | 71 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 65 insertions(+), 6 deletions(-) diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c index 6c7a024c2554..2f1a5603c366 100644 --- a/arch/s390/kvm/interrupt.c +++ b/arch/s390/kvm/interrupt.c @@ -1449,12 +1449,8 @@ static struct kvm_s390_interrupt_info *get_io_int(struct kvm *kvm, return NULL; } -/* - * 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). - */ -struct kvm_s390_interrupt_info *kvm_s390_get_io_int(struct kvm *kvm, - u64 isc_mask, u32 schid) +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; @@ -1466,6 +1462,69 @@ struct kvm_s390_interrupt_info *kvm_s390_get_io_int(struct kvm *kvm, 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 = __flogr(active_mask); + 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. + */ +struct kvm_s390_interrupt_info *kvm_s390_get_io_int(struct kvm *kvm, + u64 isc_mask, u32 schid) +{ + struct kvm_s390_interrupt_info *inti, *tmp_inti; + int isc; + + 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; +} + #define SCCB_MASK 0xFFFFFFF8 #define SCCB_EVENT_PENDING 0x3 -- 2.13.4