From patchwork Thu Jun 8 13:34:45 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoffer Dall X-Patchwork-Id: 9775465 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 42D9660350 for ; Thu, 8 Jun 2017 14:06:08 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 32D1028543 for ; Thu, 8 Jun 2017 14:06:08 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 27ACD28558; Thu, 8 Jun 2017 14:06:08 +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=-1.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID 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 90D1F28543 for ; Thu, 8 Jun 2017 14:06:07 +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=13avNX+VQyZdQw6BqdqbUX00ogJgAoJCmSm/0V8bkSk=; b=nzxlr+VnH8KLqdHElyXgWswRDR uOEpNhCF7TYTAHMSYqhT7Qg/lEPWXSwcR58A97aLy+aX/+hJrlN8Xa2/E5y5o81IY0ZoB7ZTmK87r FVR+DKTfG06o2nt49M9yeArfbDXi9ud0lPGGemttJ/C0uZs2IVDgdNJvBk4C4kwo9Mqp7woEISqob ZCOpc0112uX7PrJsYGouIRn8gpm+h4+QccxEqmHdVibu37WFwgteAkvGbEcu+RibBlb3AIc7BeWnJ cstoDt8qFIet8aT9+uRt9y7oool7Hhzz9+73JWE52dYt9+yXaw/YINRTm6DcdkU0Mu3S5ZGK8xi0Z pXB+3iqQ==; 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 1dIy4c-0006bc-Ew; Thu, 08 Jun 2017 14:06:06 +0000 Received: from merlin.infradead.org ([205.233.59.134]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1dIy4A-0005xk-6T for linux-arm-kernel@bombadil.infradead.org; Thu, 08 Jun 2017 14:05:38 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=merlin.20170209; h=References:In-Reply-To:Message-Id:Date: Subject:Cc:To:From:Sender:Reply-To:MIME-Version:Content-Type: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id: List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=62DmrSoG2ZPESq6a72qZaSq4w5mRO3se7IjFy3Oz4FE=; b=0LxhL+IL9K4iA8ORvf/iAc0sc 0yDgNFIc5u2ct8u+PtEfkEA+eU2CNYZEp466Z3fQBqh0Ot43gEFabfuggLaab3D2O8ZGs601T2B7i 7gtgPBjd65xBzGW+xskrGGslP8ltiKQ9CywBne+jJ+MzVojG02pKiCvyEUd+f+U+a6o2BKWIC8W4O I5pElq5ml0g+2x17zaedIKQ+ZaqzwyU9lg2LAb3Y5gt74X0x5id3TEboo4Qz5xm8w+RXWBXBliCIt 05p5hsceu1VALTSDWNfz6muKUjf+oIUyVJkRGu1HqFwi4oKKQyqONjjqEorWdf+cMktAFaEARcM1F 4j6KCiJKA==; Received: from mail-wm0-f45.google.com ([74.125.82.45]) by merlin.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1dIxbo-0006oC-6k for linux-arm-kernel@lists.infradead.org; Thu, 08 Jun 2017 13:36:21 +0000 Received: by mail-wm0-f45.google.com with SMTP id d64so14190783wmf.1 for ; Thu, 08 Jun 2017 06:36:00 -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=62DmrSoG2ZPESq6a72qZaSq4w5mRO3se7IjFy3Oz4FE=; b=c2B+nnBblMolvY5zhcPENz6eH3WzyDalcwyzaBDtsLCaDgqpDSCIFyClfAcz7FTcfD 7z1xY4xQ2UXT+/PFAch0D3l8CHbyoqLV3RmEnRYDZYKInKyUs7EDuIgLauSv2w8UDXm+ 2iPvODlPmi7KqOiLk2N+za4LS44Kyse1kU5aI= 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=62DmrSoG2ZPESq6a72qZaSq4w5mRO3se7IjFy3Oz4FE=; b=LDmCcGi5WUBh2YbrkHEY2iC2DehjozmCTREhKv2a64/ByRo5mYVnL+ZPNhu/X2JAba ctc9eV/P2MWhv8ahQYPzKjoa9SFxDD6UN1TV7AfQzosLN9aKqP8QVOnixt7BeMUZjrfF Iji2aGngF6xa5T6mD+13go0XeXPNR5m8aOXKtTr9BSN4a1fEUrUCliKwzFhzYlH1jBGJ 7gBOxIfvpIheREdbGSWkkbHLGLaNmTAaoPRyUNSvuM4tfh6N0aa7DyXnt1YMwwhMruWo TzrloEpN1JAQaJQbrxcVVOUd0qlE5BtBhwSj0QpGytu9C3Xt+8+5Jj57YuRY1Caf4siN +9Vw== X-Gm-Message-State: AODbwcABebhAABo5IaG1I/ddiak37GtjjRYfMoZirpWGugZE91FoXL0l sD/Oc3f+LBEmH//2 X-Received: by 10.80.160.231 with SMTP id 94mr27921841edo.173.1496928898162; Thu, 08 Jun 2017 06:34:58 -0700 (PDT) Received: from localhost.localdomain (xd93ddc2d.cust.hiper.dk. [217.61.220.45]) by smtp.gmail.com with ESMTPSA id i38sm3981285eda.18.2017.06.08.06.34.57 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 08 Jun 2017 06:34:57 -0700 (PDT) From: Christoffer Dall To: kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org Subject: [PATCH v3 8/9] KVM: arm/arm64: Disallow userspace control of in-kernel IRQ lines Date: Thu, 8 Jun 2017 15:34:45 +0200 Message-Id: <20170608133446.3875-9-cdall@linaro.org> X-Mailer: git-send-email 2.9.0 In-Reply-To: <20170608133446.3875-1-cdall@linaro.org> References: <20170608133446.3875-1-cdall@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170608_093620_363845_DAE20EBF X-CRM114-Status: GOOD ( 17.16 ) 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: Marc Zyngier , Peter Maydell , kvm@vger.kernel.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 When injecting an IRQ to the VGIC, you now have to present an owner token for that IRQ line to show that you are the owner of that line. IRQ lines driven from userspace or via an irqfd do not have an owner and will simply pass a NULL pointer. Also get rid of the unused kvm_vgic_inject_mapped_irq prototype. Signed-off-by: Christoffer Dall Acked-by: Marc Zyngier --- include/kvm/arm_vgic.h | 4 +--- virt/kvm/arm/arch_timer.c | 3 ++- virt/kvm/arm/arm.c | 4 ++-- virt/kvm/arm/pmu.c | 3 ++- virt/kvm/arm/vgic/vgic-irqfd.c | 2 +- virt/kvm/arm/vgic/vgic.c | 15 +++++++++++---- 6 files changed, 19 insertions(+), 12 deletions(-) diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h index 5d5b345..131668f 100644 --- a/include/kvm/arm_vgic.h +++ b/include/kvm/arm_vgic.h @@ -300,9 +300,7 @@ int kvm_vgic_hyp_init(void); void kvm_vgic_init_cpu_hardware(void); int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int intid, - bool level); -int kvm_vgic_inject_mapped_irq(struct kvm *kvm, int cpuid, unsigned int intid, - bool level); + bool level, void *owner); int kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu, u32 virt_irq, u32 phys_irq); int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, unsigned int virt_irq); bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, unsigned int virt_irq); diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c index 07f6f9b..8e89d63 100644 --- a/virt/kvm/arm/arch_timer.c +++ b/virt/kvm/arm/arch_timer.c @@ -226,7 +226,8 @@ static void kvm_timer_update_irq(struct kvm_vcpu *vcpu, bool new_level, if (likely(irqchip_in_kernel(vcpu->kvm))) { ret = kvm_vgic_inject_irq(vcpu->kvm, vcpu->vcpu_id, timer_ctx->irq.irq, - timer_ctx->irq.level); + timer_ctx->irq.level, + timer_ctx); WARN_ON(ret); } } diff --git a/virt/kvm/arm/arm.c b/virt/kvm/arm/arm.c index 72816d3..a265acc 100644 --- a/virt/kvm/arm/arm.c +++ b/virt/kvm/arm/arm.c @@ -832,7 +832,7 @@ int kvm_vm_ioctl_irq_line(struct kvm *kvm, struct kvm_irq_level *irq_level, if (irq_num < VGIC_NR_SGIS || irq_num >= VGIC_NR_PRIVATE_IRQS) return -EINVAL; - return kvm_vgic_inject_irq(kvm, vcpu->vcpu_id, irq_num, level); + return kvm_vgic_inject_irq(kvm, vcpu->vcpu_id, irq_num, level, NULL); case KVM_ARM_IRQ_TYPE_SPI: if (!irqchip_in_kernel(kvm)) return -ENXIO; @@ -840,7 +840,7 @@ int kvm_vm_ioctl_irq_line(struct kvm *kvm, struct kvm_irq_level *irq_level, if (irq_num < VGIC_NR_PRIVATE_IRQS) return -EINVAL; - return kvm_vgic_inject_irq(kvm, 0, irq_num, level); + return kvm_vgic_inject_irq(kvm, 0, irq_num, level, NULL); } return -EINVAL; diff --git a/virt/kvm/arm/pmu.c b/virt/kvm/arm/pmu.c index 3f08669..26a42a9 100644 --- a/virt/kvm/arm/pmu.c +++ b/virt/kvm/arm/pmu.c @@ -215,7 +215,8 @@ static void kvm_pmu_check_overflow(struct kvm_vcpu *vcpu) if (likely(irqchip_in_kernel(vcpu->kvm))) { int ret = kvm_vgic_inject_irq(vcpu->kvm, vcpu->vcpu_id, - pmu->irq_num, overflow); + pmu->irq_num, overflow, + vcpu->arch.pmu); WARN_ON(ret); } } diff --git a/virt/kvm/arm/vgic/vgic-irqfd.c b/virt/kvm/arm/vgic/vgic-irqfd.c index f138ed2..b7baf58 100644 --- a/virt/kvm/arm/vgic/vgic-irqfd.c +++ b/virt/kvm/arm/vgic/vgic-irqfd.c @@ -34,7 +34,7 @@ static int vgic_irqfd_set_irq(struct kvm_kernel_irq_routing_entry *e, if (!vgic_valid_spi(kvm, spi_id)) return -EINVAL; - return kvm_vgic_inject_irq(kvm, 0, spi_id, level); + return kvm_vgic_inject_irq(kvm, 0, spi_id, level, NULL); } /** diff --git a/virt/kvm/arm/vgic/vgic.c b/virt/kvm/arm/vgic/vgic.c index 9628945..fed717e 100644 --- a/virt/kvm/arm/vgic/vgic.c +++ b/virt/kvm/arm/vgic/vgic.c @@ -235,10 +235,14 @@ static void vgic_sort_ap_list(struct kvm_vcpu *vcpu) /* * Only valid injection if changing level for level-triggered IRQs or for a - * rising edge. + * rising edge, and in-kernel connected IRQ lines can only be controlled by + * their owner. */ -static bool vgic_validate_injection(struct vgic_irq *irq, bool level) +static bool vgic_validate_injection(struct vgic_irq *irq, bool level, void *owner) { + if (irq->owner != owner) + return false; + switch (irq->config) { case VGIC_CONFIG_LEVEL: return irq->line_level != level; @@ -350,13 +354,16 @@ bool vgic_queue_irq_unlock(struct kvm *kvm, struct vgic_irq *irq) * false: to ignore the call * Level-sensitive true: raise the input signal * false: lower the input signal + * @owner: The opaque pointer to the owner of the IRQ being raised to verify + * that the caller is allowed to inject this IRQ. Userspace + * injections will have owner == NULL. * * The VGIC is not concerned with devices being active-LOW or active-HIGH for * level-sensitive interrupts. You can think of the level parameter as 1 * being HIGH and 0 being LOW and all devices being active-HIGH. */ int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int intid, - bool level) + bool level, void *owner) { struct kvm_vcpu *vcpu; struct vgic_irq *irq; @@ -378,7 +385,7 @@ int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int intid, spin_lock(&irq->irq_lock); - if (!vgic_validate_injection(irq, level)) { + if (!vgic_validate_injection(irq, level, owner)) { /* Nothing to see here, move along... */ spin_unlock(&irq->irq_lock); vgic_put_irq(kvm, irq);