From patchwork Tue May 16 18:45:55 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoffer Dall X-Patchwork-Id: 9729519 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 D755960386 for ; Tue, 16 May 2017 18:48:25 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C8D8D28780 for ; Tue, 16 May 2017 18:48:25 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id BC5362896B; Tue, 16 May 2017 18:48:25 +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 3587F28780 for ; Tue, 16 May 2017 18:48:25 +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=DMtmbr7ZNil60iDGcD3NoYvuOCUvYA25HPILPvhDWlc=; b=o51HX0ehb8zVSAMBUYMYxx1W/8 G+vmUtwoDG+sEMqnPqGmK+XZqJzK9mHHQSlCd4r1T7O8nlCh0/C9B/rE+E3LGtJ4mDmiofnUUR/iC 2L2Rgi+3QerNAUDaTErzGu7S19tZHKNlxNArYvwAvNCNO8j7YNz0ycS6ykCE5IoldJWwcj9zS9oJz wb9Xc/5moOO9has6mBpXxRNvh7nZogRn0l6rl4DYMT5YkQ+3LA9TRAoTGYxJF5ckQuwwe0laH65U9 nrt8FfFFklCmf4C7gCa+xuVie7JIkry4W9t16OaAgWGiSnQypng9/aecqboMGHQygBkPW/zulE55k 3wt5Xogg==; 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 1dAhWB-0004Ry-HE; Tue, 16 May 2017 18:48:23 +0000 Received: from mail-wm0-x231.google.com ([2a00:1450:400c:c09::231]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1dAhUZ-0002Ob-IO for linux-arm-kernel@lists.infradead.org; Tue, 16 May 2017 18:46:49 +0000 Received: by mail-wm0-x231.google.com with SMTP id u65so131015081wmu.1 for ; Tue, 16 May 2017 11:46:25 -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=eWmCQYX2R43EV0Nd92qYoROFr27zBOCsRWzYg1R/4P8=; b=VIYdGC6aTwKei8X6MUqsw6rkdR2TPyXFgI3UnIhqYExf4wYBu4+xeHHhdjT1Ala5kp n81I3JCrUOG4b1JK2IvVkRA5bmWjdGOJxp3SOXNusP1UjgHK08I5fAqjzdqesAMZCZjY 6BA9ubw0OESGcrvKpc32LRH0wTMy6g7gQNquI= 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=eWmCQYX2R43EV0Nd92qYoROFr27zBOCsRWzYg1R/4P8=; b=SqXBN3502Em4smugQKHEFONA4MNsaoHuI7IesQ7tvqdStM8DHKcDr90jHiVV0LIVAK zNTHpG8L8woDsaeK1E+jGE+dJbHFIROLK/GBmRc9NVrpCC73BJ7FS2l4c211Kh7w0HCU fsPnrIqe5yFJnXrdhKG64diHBWsZVofKEGEEoIDZbEIXeac6nubZKFjJKmVBUc2hhOUv jZKcK+Ai3qzbfZV+J2T5KECjrp7NPghHpHTdNzBT123+5RYxwpKSyYgfbLnBYqPjjn9E HWBmtRwslnX+ho8IF/skwSTvRQ3YhIV1JdlWvlI5wOSwXSvfT+X4L+xaIiLecjunP3JN F4nA== X-Gm-Message-State: AODbwcBXfwYu5+JwywiJz85+AvfzBSp3HREqiBOevA1pYEkuHNTin5LA B47Uj3vyboxpGWWpJVHwRQ== X-Received: by 10.80.158.131 with SMTP id a3mr66224edf.169.1494960383857; Tue, 16 May 2017 11:46:23 -0700 (PDT) Received: from localhost.localdomain (xd93ddc2d.cust.hiper.dk. [217.61.220.45]) by smtp.gmail.com with ESMTPSA id c2sm25102edc.34.2017.05.16.11.46.23 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 16 May 2017 11:46:23 -0700 (PDT) From: Christoffer Dall To: kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org Subject: [PATCH v2 8/9] KVM: arm/arm64: Disallow userspace control of in-kernel IRQ lines Date: Tue, 16 May 2017 20:45:55 +0200 Message-Id: <20170516184556.26785-9-cdall@linaro.org> X-Mailer: git-send-email 2.9.0 In-Reply-To: <20170516184556.26785-1-cdall@linaro.org> References: <20170516184556.26785-1-cdall@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170516_114643_954804_C0E8583C X-CRM114-Status: GOOD ( 16.37 ) 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 , Christoffer Dall , Alexander Graf , kvm@vger.kernel.org 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 --- 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 528acf0..becd8e7 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 3417e18..42cb9e8 100644 --- a/virt/kvm/arm/arm.c +++ b/virt/kvm/arm/arm.c @@ -806,7 +806,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; @@ -814,7 +814,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 c354bd5..006a033 100644 --- a/virt/kvm/arm/pmu.c +++ b/virt/kvm/arm/pmu.c @@ -238,7 +238,8 @@ static void kvm_pmu_update_state(struct kvm_vcpu *vcpu) if (likely(irqchip_in_kernel(vcpu->kvm))) { int ret; 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 e9e46f1..01dc4cd 100644 --- a/virt/kvm/arm/vgic/vgic.c +++ b/virt/kvm/arm/vgic/vgic.c @@ -234,10 +234,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; @@ -346,13 +350,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; @@ -374,7 +381,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);