From patchwork Thu Feb 7 12:20:52 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cornelia Huck X-Patchwork-Id: 2110401 Return-Path: X-Original-To: patchwork-kvm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork1.kernel.org (Postfix) with ESMTP id E02633FDF1 for ; Thu, 7 Feb 2013 12:21:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754621Ab3BGMVK (ORCPT ); Thu, 7 Feb 2013 07:21:10 -0500 Received: from e06smtp15.uk.ibm.com ([195.75.94.111]:41391 "EHLO e06smtp15.uk.ibm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752159Ab3BGMVI (ORCPT ); Thu, 7 Feb 2013 07:21:08 -0500 Received: from /spool/local by e06smtp15.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Thu, 7 Feb 2013 12:19:38 -0000 Received: from b06cxnps3075.portsmouth.uk.ibm.com (9.149.109.195) by e06smtp15.uk.ibm.com (192.168.101.145) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Thu, 7 Feb 2013 12:19:26 -0000 Received: from d06av08.portsmouth.uk.ibm.com (d06av08.portsmouth.uk.ibm.com [9.149.37.249]) by b06cxnps3075.portsmouth.uk.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id r17CKkWn32899176; Thu, 7 Feb 2013 12:20:46 GMT Received: from d06av08.portsmouth.uk.ibm.com (loopback [127.0.0.1]) by d06av08.portsmouth.uk.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id r17CKsJZ012475; Thu, 7 Feb 2013 05:20:54 -0700 Received: from tuxmaker.boeblingen.de.ibm.com (tuxmaker.boeblingen.de.ibm.com [9.152.85.9]) by d06av08.portsmouth.uk.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with ESMTP id r17CKrPd012447; Thu, 7 Feb 2013 05:20:53 -0700 From: Cornelia Huck To: Marcelo Tosatti , Gleb Natapov Cc: Christian Borntraeger , Carsten Otte , Alexander Graf , Heiko Carstens , Martin Schwidefsky , KVM , linux-s390 Subject: [PATCH] KVM: s390: Fix handling of iscs. Date: Thu, 7 Feb 2013 13:20:52 +0100 Message-Id: <1360239652-52350-2-git-send-email-cornelia.huck@de.ibm.com> X-Mailer: git-send-email 1.7.12.4 In-Reply-To: <1360239652-52350-1-git-send-email-cornelia.huck@de.ibm.com> References: <1360239652-52350-1-git-send-email-cornelia.huck@de.ibm.com> x-cbid: 13020712-0342-0000-0000-000004241E43 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org There are two ways to express an interruption subclass: - As a bitmask, as used in cr6. - As a number, as used in the I/O interruption word. Unfortunately, we have treated the I/O interruption word as if it contained the bitmask as well, which went unnoticed so far as - (not-yet-released) qemu made the same mistake, and - Linux guest kernels don't check the isc value in the I/O interruption word for subchannel interrupts. Make sure that we treat the I/O interruption word correctly. Reviewed-by: Christian Borntraeger Signed-off-by: Cornelia Huck --- arch/s390/kvm/interrupt.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c index 9a12835..2f6ccb0 100644 --- a/arch/s390/kvm/interrupt.c +++ b/arch/s390/kvm/interrupt.c @@ -55,6 +55,13 @@ static int psw_interrupts_disabled(struct kvm_vcpu *vcpu) return 1; } +static u64 int_word_to_isc_bits(u32 int_word) +{ + u8 isc = (int_word & 0x38000000) >> 27; + + return (0x80 >> isc) << 24; +} + static int __interrupt_is_deliverable(struct kvm_vcpu *vcpu, struct kvm_s390_interrupt_info *inti) { @@ -96,7 +103,8 @@ static int __interrupt_is_deliverable(struct kvm_vcpu *vcpu, case KVM_S390_INT_IO_MIN...KVM_S390_INT_IO_MAX: if (psw_ioint_disabled(vcpu)) return 0; - if (vcpu->arch.sie_block->gcr[6] & inti->io.io_int_word) + if (vcpu->arch.sie_block->gcr[6] & + int_word_to_isc_bits(inti->io.io_int_word)) return 1; return 0; default: @@ -724,7 +732,8 @@ struct kvm_s390_interrupt_info *kvm_s390_get_io_int(struct kvm *kvm, list_for_each_entry(iter, &fi->list, list) { if (!is_ioint(iter->type)) continue; - if (cr6 && ((cr6 & iter->io.io_int_word) == 0)) + if (cr6 && + ((cr6 & int_word_to_isc_bits(iter->io.io_int_word)) == 0)) continue; if (schid) { if (((schid & 0x00000000ffff0000) >> 16) != @@ -811,11 +820,14 @@ int kvm_s390_inject_vm(struct kvm *kvm, if (!is_ioint(inti->type)) list_add_tail(&inti->list, &fi->list); else { + u64 isc_bits = int_word_to_isc_bits(inti->io.io_int_word); + /* Keep I/O interrupts sorted in isc order. */ list_for_each_entry(iter, &fi->list, list) { if (!is_ioint(iter->type)) continue; - if (iter->io.io_int_word <= inti->io.io_int_word) + if (int_word_to_isc_bits(iter->io.io_int_word) + <= isc_bits) continue; break; }