From patchwork Mon Dec 4 20:35:23 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoffer Dall X-Patchwork-Id: 10091499 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 89B9460327 for ; Mon, 4 Dec 2017 20:37:19 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7B4C12925F for ; Mon, 4 Dec 2017 20:37:19 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6F52C293F9; Mon, 4 Dec 2017 20:37:19 +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 F03FE2925F for ; Mon, 4 Dec 2017 20:37:18 +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=PbweMX6SZWWi0o8+es30VrrtXVLKv1QeveUglzimAWY=; b=WUg4EFm8d6FkEmU4UnipILv8Jd yJXqTuhZtbIv+S1kikOgiWuQZereQWpXLWxeDd6Uxg10hractKVEf9lxD7RBHHzCJp3k43s1HyHar +2W3cRh7aKCqj7jr+KrSoUUjkhowTwqtD87km+2bgnkXVNUX1ImrLKDkHPbHFHlG2q0yx+ivkRHe4 OFvmMJMvGu36bxdaCWJ0JOG3qO1gweKbNKrDeWy1sGNKDCtLQQV5U2CICHtFq0lxlBydyGpRM662j A/tLaCcRmcxz3TOyMbApdwRW38rvsZIBM8fc88KuQrvsYJey4po4pBX7Y1CwnsZOKTH33W5whwhPj HhqsZGpA==; 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 1eLxUM-0007LJ-8J; Mon, 04 Dec 2017 20:37:18 +0000 Received: from mail-wm0-x242.google.com ([2a00:1450:400c:c09::242]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1eLxTI-0006BX-2P for linux-arm-kernel@lists.infradead.org; Mon, 04 Dec 2017 20:36:15 +0000 Received: by mail-wm0-x242.google.com with SMTP id 64so16584545wme.3 for ; Mon, 04 Dec 2017 12:35:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=christofferdall-dk.20150623.gappssmtp.com; s=20150623; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=x+zvnQ9tb3neoXAB4uPVa3PmQf0KA1azQazQX4ATnNU=; b=b92Q6VWHAkAAfsJCyj5Nrl2l+xx98SKkwMj0OCTR9jxLnGGvB6eZ79c07FLhqdhsg7 pkCgRQzg3Ot+6jFP1g75WSSBQfw3b4zEnkK92xN+WV4Xkc7A4uhz5Rj8juKtdqDKyYBq z/HZW+1EJidBpXxthwf2QGfu2SpoXJ/hFPbi+qyhZxOJbBy0SDE+15yRWwjhMBaVsZbE LTDAqGXxARY75SDdTHM/HPXURHIpWEWUEOuOTK1KfDhFyFh+/ldWG1sXKBII4ACHppJL YT5fkrhBEzyKaJ1m6OsHg1El55xOVwzeIezokf/7bsBwa37H38XhXOGxbj/CAlLn4jlQ J8WQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=x+zvnQ9tb3neoXAB4uPVa3PmQf0KA1azQazQX4ATnNU=; b=BZE3J6AGWHXSsdsFdFgr6tNyfzaGsSz3LM/EruBAKWqRxhq9eBWnBy+1/wMJjMqaIT iSN0Skl+dpG4P4RqEEmTsn5ilnLbrOQOwNict7vrmroJOdh/t5/AQz6wo7Z1kN/eSUd5 1/IlUcK+Ku/8ifqVu6wbDYMA4CGU7MQTdnw/hB7BLMalksGWJqCje0yxnCBQ+vfUrFJB tUo1YZ9O2tqdhJiFt2a8ZM+2azED7/BS/jSc8tUdG7WsL9Z5oFBcWjiQ7Svl4gtfFZSU S0mJ5AB63ycTZPXuJREc9Tt0GwuRHLljm/1dmR9iuA1d60rpyHNUCbNQlkUWS1WG8AO/ Z75Q== X-Gm-Message-State: AJaThX6v/K0AmCTgMb9VN6EczXetRUNheO+ljUYrB1zyN/wXM6gdMMKO gnevkGqeFLOg7/gdqaNxa0PGiQ== X-Google-Smtp-Source: AGs4zMYBfw6fIgifowW945uvz7aanJTFR0eAl5gbdfR/iN0GcXcp72jAe8sX8YANT7ZlHwQS0fXSWg== X-Received: by 10.80.136.228 with SMTP id d91mr31911412edd.296.1512419749892; Mon, 04 Dec 2017 12:35:49 -0800 (PST) Received: from localhost.localdomain (x50d2404e.cust.hiper.dk. [80.210.64.78]) by smtp.gmail.com with ESMTPSA id k42sm8434943edb.94.2017.12.04.12.35.48 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 04 Dec 2017 12:35:49 -0800 (PST) From: Christoffer Dall To: kvm@vger.kernel.org Subject: [PATCH v3 01/16] KVM: Take vcpu->mutex outside vcpu_load Date: Mon, 4 Dec 2017 21:35:23 +0100 Message-Id: <20171204203538.8370-2-cdall@kernel.org> X-Mailer: git-send-email 2.14.2 In-Reply-To: <20171204203538.8370-1-cdall@kernel.org> References: <20171204203538.8370-1-cdall@kernel.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20171204_123612_264724_EC5A4B3B X-CRM114-Status: GOOD ( 16.09 ) 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: linux-mips@linux-mips.org, Andrew Jones , =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= , Marc Zyngier , James Hogan , Cornelia Huck , kvm-ppc@vger.kernel.org, Paul Mackerras , Christian Borntraeger , linux-arm-kernel@lists.infradead.org, Paolo Bonzini , linux-s390@vger.kernel.org, kvmarm@lists.cs.columbia.edu, 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 From: Christoffer Dall As we're about to call vcpu_load() from architecture-specific implementations of the KVM vcpu ioctls, but yet we access data structures protected by the vcpu->mutex in the generic code, factor this logic out from vcpu_load(). x86 is the only architecture which calls vcpu_load() outside of the main vcpu ioctl function, and these calls will no longer take the vcpu mutex following this patch. However, with the exception of kvm_arch_vcpu_postcreate (see below), the callers are either in the creation or destruction path of the VCPU, which means there cannot be any concurrent access to the data structure, because the file descriptor is not yet accessible, or is already gone. kvm_arch_vcpu_postcreate makes the newly created vcpu potentially accessible by other in-kernel threads through the kvm->vcpus array, and we therefore take the vcpu mutex in this case directly. Signed-off-by: Christoffer Dall Reviewed-by: Cornelia Huck --- arch/x86/kvm/vmx.c | 4 +--- arch/x86/kvm/x86.c | 20 +++++++------------- include/linux/kvm_host.h | 2 +- virt/kvm/kvm_main.c | 17 ++++++----------- 4 files changed, 15 insertions(+), 28 deletions(-) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 714a0673ec3c..e7c46d20e186 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -9559,10 +9559,8 @@ static void vmx_switch_vmcs(struct kvm_vcpu *vcpu, struct loaded_vmcs *vmcs) static void vmx_free_vcpu_nested(struct kvm_vcpu *vcpu) { struct vcpu_vmx *vmx = to_vmx(vcpu); - int r; - r = vcpu_load(vcpu); - BUG_ON(r); + vcpu_load(vcpu); vmx_switch_vmcs(vcpu, &vmx->vmcs01); free_nested(vmx); vcpu_put(vcpu); diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 34c85aa2e2d1..9b8f864243c9 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -7747,16 +7747,12 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) { - int r; - kvm_vcpu_mtrr_init(vcpu); - r = vcpu_load(vcpu); - if (r) - return r; + vcpu_load(vcpu); kvm_vcpu_reset(vcpu, false); kvm_mmu_setup(vcpu); vcpu_put(vcpu); - return r; + return 0; } void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu) @@ -7766,13 +7762,15 @@ void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu) kvm_hv_vcpu_postcreate(vcpu); - if (vcpu_load(vcpu)) + if (mutex_lock_killable(&vcpu->mutex)) return; + vcpu_load(vcpu); msr.data = 0x0; msr.index = MSR_IA32_TSC; msr.host_initiated = true; kvm_write_tsc(vcpu, &msr); vcpu_put(vcpu); + mutex_unlock(&vcpu->mutex); if (!kvmclock_periodic_sync) return; @@ -7783,11 +7781,9 @@ void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu) void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu) { - int r; vcpu->arch.apf.msr_val = 0; - r = vcpu_load(vcpu); - BUG_ON(r); + vcpu_load(vcpu); kvm_mmu_unload(vcpu); vcpu_put(vcpu); @@ -8155,9 +8151,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) static void kvm_unload_vcpu_mmu(struct kvm_vcpu *vcpu) { - int r; - r = vcpu_load(vcpu); - BUG_ON(r); + vcpu_load(vcpu); kvm_mmu_unload(vcpu); vcpu_put(vcpu); } diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 2e754b7c282c..a000dd8b75f0 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -533,7 +533,7 @@ static inline int kvm_vcpu_get_idx(struct kvm_vcpu *vcpu) int kvm_vcpu_init(struct kvm_vcpu *vcpu, struct kvm *kvm, unsigned id); void kvm_vcpu_uninit(struct kvm_vcpu *vcpu); -int __must_check vcpu_load(struct kvm_vcpu *vcpu); +void vcpu_load(struct kvm_vcpu *vcpu); void vcpu_put(struct kvm_vcpu *vcpu); #ifdef __KVM_HAVE_IOAPIC diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index f169ecc4f2e8..39961fb8aef7 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -146,17 +146,12 @@ bool kvm_is_reserved_pfn(kvm_pfn_t pfn) /* * Switches to specified vcpu, until a matching vcpu_put() */ -int vcpu_load(struct kvm_vcpu *vcpu) +void vcpu_load(struct kvm_vcpu *vcpu) { - int cpu; - - if (mutex_lock_killable(&vcpu->mutex)) - return -EINTR; - cpu = get_cpu(); + int cpu = get_cpu(); preempt_notifier_register(&vcpu->preempt_notifier); kvm_arch_vcpu_load(vcpu, cpu); put_cpu(); - return 0; } EXPORT_SYMBOL_GPL(vcpu_load); @@ -166,7 +161,6 @@ void vcpu_put(struct kvm_vcpu *vcpu) kvm_arch_vcpu_put(vcpu); preempt_notifier_unregister(&vcpu->preempt_notifier); preempt_enable(); - mutex_unlock(&vcpu->mutex); } EXPORT_SYMBOL_GPL(vcpu_put); @@ -2529,9 +2523,9 @@ static long kvm_vcpu_ioctl(struct file *filp, #endif - r = vcpu_load(vcpu); - if (r) - return r; + if (mutex_lock_killable(&vcpu->mutex)) + return -EINTR; + vcpu_load(vcpu); switch (ioctl) { case KVM_RUN: { struct pid *oldpid; @@ -2704,6 +2698,7 @@ static long kvm_vcpu_ioctl(struct file *filp, } out: vcpu_put(vcpu); + mutex_unlock(&vcpu->mutex); kfree(fpu); kfree(kvm_sregs); return r;