From patchwork Mon Sep 4 10:24:54 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoffer Dall X-Patchwork-Id: 9936969 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 26B0860237 for ; Mon, 4 Sep 2017 10:26:43 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 168F3287B8 for ; Mon, 4 Sep 2017 10:26:43 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0B847287BA; Mon, 4 Sep 2017 10:26:43 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 90F36287B8 for ; Mon, 4 Sep 2017 10:26:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=OCPm4u1Wk2/+5gkCoURTyOpBMHTvvfVVpLKNc0LKh2s=; b=BAarV/zynr/h20gkmL8rs8StYR DghPd2yp6vErg+OfrIEhWmFT1To6V1xGAtkmM3/cHb4T2ueXiOlaLyorDP3VxWIu1/pggdid/Q7l2 HVPfhxG6i54POCQ+FRDRP+gsHXIDa6Mcs5diXRV4ieBtwXQajF5jZxKjHD58Gl+OT+kLfrSqZvd5b 9PVt9sTxFCOR5D4T4AMnr7dE+Zjw3Qda0oKmaenJYdSWFCNH8/ZrJqbRMx7UlgLRGLBkFs+KsVeQV +13g8+VWyu1KlrdUK75bSHggA26kYycFz+iA+u085cLMd+E8fp4RlLmEqho3bPoGTcoedODhPZ5pq GOLEGudQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1dooaT-0003C8-3h; Mon, 04 Sep 2017 10:26:37 +0000 Received: from mail-wm0-x22e.google.com ([2a00:1450:400c:c09::22e]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1dooZR-00020C-1X for linux-arm-kernel@lists.infradead.org; Mon, 04 Sep 2017 10:25:36 +0000 Received: by mail-wm0-x22e.google.com with SMTP id f145so3541453wme.0 for ; Mon, 04 Sep 2017 03:25:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=55QHxM+1d6e67S06E9XThoct/Iwyh8lFFbmrma6x0Wk=; b=hjF1StZ2h2L2N46eK3/pAWDzDEnuP723VJ3lWdGaebELFOALj2iS8+UJMz8l+Cx/hs sXiJiuijkf/5t2MewhsLFv+vzSDOMbwuRMOrV3WFOsV32SJQgG3F3en+j1+RW8RC0N2C v4gh8jedWjhGd7k3kpbpoNwv2d4b2skfHckbE= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=55QHxM+1d6e67S06E9XThoct/Iwyh8lFFbmrma6x0Wk=; b=nK//rfJtuGjo2B1fadAYNbYP+rJKQ5bb6ynG5g04o19ShB1HOFpEsnq/WoXZQHPLc7 WPTPvaAsMHUIrlNE2rSZn8sFZVpNIeBjiKm5mQ0/SGvJUei/SsUY+7noLJTfLwEIgGIE NXd3jmAtrnakN+tNTLGvm+tzQOoMsZTV5m1p329I0OYm0L2T2KNhVQWyMueAN/k2v7ai 2UHuC+rKXtZAzyecAPbs+PtFyiOp05H5MWUBTiwNr2UAdOp+0VkhcR/91BD/2XoXWxqA GcIZzJ3wv7VPhHcl47Yom2l63wZkhWWBcaN9QtxTFnaMWRcqJLjzNsVGze3tBDK7PyLK SD+Q== X-Gm-Message-State: AHPjjUicI/P4foZvncH/KO9xzeXewowr1eE0ASq3LxC/qjQ6rrv8P1Ak IFpkFznA5p7E7HA5 X-Google-Smtp-Source: ADKCNb7D3giACI+Q97GeaWSHI+pL5C+PEfmbfmiLhAuYO3BaUVXtTAxQTnkvhp/OHY1sHCgAuc8BQQ== X-Received: by 10.80.190.13 with SMTP id a13mr154318edi.2.1504520709683; Mon, 04 Sep 2017 03:25:09 -0700 (PDT) Received: from localhost.localdomain (xd93ddc2d.cust.hiper.dk. [217.61.220.45]) by smtp.gmail.com with ESMTPSA id h64sm3406924edc.67.2017.09.04.03.25.08 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 04 Sep 2017 03:25:09 -0700 (PDT) From: Christoffer Dall To: kvmarm@lists.cs.columbia.edu, Eric Auger , Marc Zyngier Subject: [PATCH v2 4/6] KVM: arm/arm64: Support VGIC dist pend/active changes for mapped IRQs Date: Mon, 4 Sep 2017 12:24:54 +0200 Message-Id: <20170904102456.9025-5-cdall@linaro.org> X-Mailer: git-send-email 2.9.0 In-Reply-To: <20170904102456.9025-1-cdall@linaro.org> References: <20170904102456.9025-1-cdall@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170904_032533_342307_279D0A8C X-CRM114-Status: GOOD ( 16.86 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Andre Przywara , kvm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Christoffer Dall MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP For mapped IRQs (with the HW bit set in the LR) we have to follow some rules of the architecture. One of these rules is that VM must not be allowed to deactivate a virtual interrupt with the HW bit set unless the physical interrupt is also active. This works fine when injecting mapped interrupts, because we leave it up to the injector to either set EOImode==1 or manually set the active state of the physical interrupt. However, the guest can set virtual interrupt to be pending or active by writing to the virtual distributor, which could lead to deactivating a virtual interrupt with the HW bit set without the physical interrupt being active. We could set the physical interrupt to active whenever we are about to eneter the VM with a HW interrupt either pending or active, but that would be really slow, especially on GICv2. So we take the long way around and do the hard work when needed, which is expected to be extremely rare. When the VM sets the pending state for a HW interrupt on the virtual distributor we set the active state on the physical distributor, because the virtual interrupt can become active and then the guest can deactivate it. When the VM clears the pending state we also clear it on the physical side, because the injector might otherwise raise the interrupt. Signed-off-by: Christoffer Dall --- virt/kvm/arm/vgic/vgic-mmio.c | 27 +++++++++++++++++++++++++++ virt/kvm/arm/vgic/vgic.c | 7 +++++++ virt/kvm/arm/vgic/vgic.h | 1 + 3 files changed, 35 insertions(+) diff --git a/virt/kvm/arm/vgic/vgic-mmio.c b/virt/kvm/arm/vgic/vgic-mmio.c index c1e4bdd..c825d7c 100644 --- a/virt/kvm/arm/vgic/vgic-mmio.c +++ b/virt/kvm/arm/vgic/vgic-mmio.c @@ -131,6 +131,12 @@ void vgic_mmio_write_spending(struct kvm_vcpu *vcpu, struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i); spin_lock(&irq->irq_lock); + if (irq->hw) { + vgic_irq_set_phys_active(irq, true); + spin_unlock(&irq->irq_lock); + continue; + } + irq->pending_latch = true; vgic_queue_irq_unlock(vcpu->kvm, irq); @@ -149,6 +155,11 @@ void vgic_mmio_write_cpending(struct kvm_vcpu *vcpu, struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i); spin_lock(&irq->irq_lock); + if (irq->hw) { + vgic_irq_set_phys_pending(irq, false); + spin_unlock(&irq->irq_lock); + continue; + } irq->pending_latch = false; @@ -214,6 +225,22 @@ static void vgic_mmio_change_active(struct kvm_vcpu *vcpu, struct vgic_irq *irq, irq->vcpu->cpu != -1) /* VCPU thread is running */ cond_resched_lock(&irq->irq_lock); + if (irq->hw) { + /* + * We cannot support setting the physical active state for + * private interrupts from another CPU than the one running + * the VCPU which identifies which private interrupt it is + * trying to modify. + */ + if (irq->intid < VGIC_NR_PRIVATE_IRQS && + irq->target_vcpu != requester_vcpu) { + spin_unlock(&irq->irq_lock); + return; + } + + vgic_irq_set_phys_active(irq, new_active_state); + } + irq->active = new_active_state; if (new_active_state) vgic_queue_irq_unlock(vcpu->kvm, irq); diff --git a/virt/kvm/arm/vgic/vgic.c b/virt/kvm/arm/vgic/vgic.c index 8072969..7aec730 100644 --- a/virt/kvm/arm/vgic/vgic.c +++ b/virt/kvm/arm/vgic/vgic.c @@ -140,6 +140,13 @@ void vgic_put_irq(struct kvm *kvm, struct vgic_irq *irq) kfree(irq); } +void vgic_irq_set_phys_pending(struct vgic_irq *irq, bool pending) +{ + WARN_ON(irq_set_irqchip_state(irq->host_irq, + IRQCHIP_STATE_PENDING, + pending)); +} + /* Get the input level of a mapped IRQ directly from the physical GIC */ bool vgic_get_phys_line_level(struct vgic_irq *irq) { diff --git a/virt/kvm/arm/vgic/vgic.h b/virt/kvm/arm/vgic/vgic.h index 7bdcda2..498ee05 100644 --- a/virt/kvm/arm/vgic/vgic.h +++ b/virt/kvm/arm/vgic/vgic.h @@ -146,6 +146,7 @@ struct vgic_irq *vgic_get_irq(struct kvm *kvm, struct kvm_vcpu *vcpu, u32 intid); void vgic_put_irq(struct kvm *kvm, struct vgic_irq *irq); bool vgic_get_phys_line_level(struct vgic_irq *irq); +void vgic_irq_set_phys_pending(struct vgic_irq *irq, bool pending); void vgic_irq_set_phys_active(struct vgic_irq *irq, bool active); bool vgic_queue_irq_unlock(struct kvm *kvm, struct vgic_irq *irq); void vgic_kick_vcpus(struct kvm *kvm);