Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp3507653imu; Mon, 7 Jan 2019 04:47:19 -0800 (PST) X-Google-Smtp-Source: AFSGD/UoAJO9t00wtr9TA5Nq8WBIenJNJlQJRoD+pERFKdM2qG6FAMV1RSSuHipaFEO/c8DyYvsY X-Received: by 2002:a62:444b:: with SMTP id r72mr63910601pfa.184.1546865239555; Mon, 07 Jan 2019 04:47:19 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1546865239; cv=none; d=google.com; s=arc-20160816; b=wzCTc36iZFP+N810Bw0DgcaihpylQ7IGyYDA3nLxzPeYSPkNE41//tXqd2oIib1ioh bEFQj2+FuFslEm+7s/dk/uHoSupdjJTfgP/2tcRXD0zsmvTUmB5tru4nAjLG28EA8SFI yDSLL6FYr4cbfmfo4i/+/kFowsxXmEjl+GjIRmdTryS1M58MoysGKJPy1lUiP364EPQr DzE2HmqD8jHku3sobrtrHn++s01yKheZ3tltYN7A4MVORB5BhDSa9IqXB9l68Zkb/8z7 rmtsyPcokrrSqzqDFGeIjUyaBIhXLFfPd9kcbGjQjsSDjAvPvKGb3SmQh+mM/2vvdbrL uJ9w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=SmyG39r8sYNF5gyxWMIURQFh2by70WtEs9hb4oo4LGg=; b=09Y+wXD9NUUkEOhsSKLRIP/G1sGl5roKudliMMvRAlIkuvb8+wQdo1UXbWBfR8KcAE KlySo2d02h4wz15Bi4gimF7BHJF2cCwRK3C6W1sXZSE8I4Tvon1JSsE2PXWXvHYpQ+yE i/aGFRebMtSjOnWQAYPUbL6fBCdMNamB1kEoc63Q8zHKaO3ESwbtLgqP5yRZoOQcn1n/ xTfLTIo3P3qyDXcMr4zZnce3CqvgefidE0qXl80w04XtrCWRW9TB5+jq1cLR9KXB2t4W 3XWMTkHQ8PjfxUXN452KXd9AaYCMEF6BVLOPEFCEq2nEoe3WVKSNa1FA5cGGGD0VThdV rSsA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=RUbjzIq4; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id i64si17363009pge.361.2019.01.07.04.47.04; Mon, 07 Jan 2019 04:47:19 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=RUbjzIq4; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728822AbfAGMpM (ORCPT + 99 others); Mon, 7 Jan 2019 07:45:12 -0500 Received: from mail.kernel.org ([198.145.29.99]:34178 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728817AbfAGMpI (ORCPT ); Mon, 7 Jan 2019 07:45:08 -0500 Received: from localhost (5356596B.cm-6-7b.dynamic.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 971B5218A1; Mon, 7 Jan 2019 12:45:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1546865108; bh=bDVUMK7x89sS0+jIr4/iClA/CFfGHb1EfOjtwGAH9x0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=RUbjzIq4GFU7VcGeJMj7pqvtqGLL9ZR9f4MdyiXIZezGS8X13sx0e4k+zOloAjjqx Y3rZjiBCWvbhfaR0IQ2OC28aLc+Afal1cB0y/FEDXB+OJXOdzdM25tlGEcn6TD/blv zmvDpi11Vwr79XNpKZlQWmvgrkLCCPlI3kO54T/A= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Julien Thierry , Christoffer Dall , Marc Zyngier Subject: [PATCH 4.20 138/145] KVM: arm/arm64: Fix VMID alloc race by reverting to lock-less Date: Mon, 7 Jan 2019 13:32:55 +0100 Message-Id: <20190107104455.269088229@linuxfoundation.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190107104437.308206189@linuxfoundation.org> References: <20190107104437.308206189@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review X-Patchwork-Hint: ignore MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.20-stable review patch. If anyone has any objections, please let me know. ------------------ From: Christoffer Dall commit fb544d1ca65a89f7a3895f7531221ceeed74ada7 upstream. We recently addressed a VMID generation race by introducing a read/write lock around accesses and updates to the vmid generation values. However, kvm_arch_vcpu_ioctl_run() also calls need_new_vmid_gen() but does so without taking the read lock. As far as I can tell, this can lead to the same kind of race: VM 0, VCPU 0 VM 0, VCPU 1 ------------ ------------ update_vttbr (vmid 254) update_vttbr (vmid 1) // roll over read_lock(kvm_vmid_lock); force_vm_exit() local_irq_disable need_new_vmid_gen == false //because vmid gen matches enter_guest (vmid 254) kvm_arch.vttbr = : read_unlock(kvm_vmid_lock); enter_guest (vmid 1) Which results in running two VCPUs in the same VM with different VMIDs and (even worse) other VCPUs from other VMs could now allocate clashing VMID 254 from the new generation as long as VCPU 0 is not exiting. Attempt to solve this by making sure vttbr is updated before another CPU can observe the updated VMID generation. Cc: stable@vger.kernel.org Fixes: f0cf47d939d0 "KVM: arm/arm64: Close VMID generation race" Reviewed-by: Julien Thierry Signed-off-by: Christoffer Dall Signed-off-by: Marc Zyngier Signed-off-by: Greg Kroah-Hartman --- virt/kvm/arm/arm.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) --- a/virt/kvm/arm/arm.c +++ b/virt/kvm/arm/arm.c @@ -66,7 +66,7 @@ static DEFINE_PER_CPU(struct kvm_vcpu *, static atomic64_t kvm_vmid_gen = ATOMIC64_INIT(1); static u32 kvm_next_vmid; static unsigned int kvm_vmid_bits __read_mostly; -static DEFINE_RWLOCK(kvm_vmid_lock); +static DEFINE_SPINLOCK(kvm_vmid_lock); static bool vgic_present; @@ -484,7 +484,9 @@ void force_vm_exit(const cpumask_t *mask */ static bool need_new_vmid_gen(struct kvm *kvm) { - return unlikely(kvm->arch.vmid_gen != atomic64_read(&kvm_vmid_gen)); + u64 current_vmid_gen = atomic64_read(&kvm_vmid_gen); + smp_rmb(); /* Orders read of kvm_vmid_gen and kvm->arch.vmid */ + return unlikely(READ_ONCE(kvm->arch.vmid_gen) != current_vmid_gen); } /** @@ -499,16 +501,11 @@ static void update_vttbr(struct kvm *kvm { phys_addr_t pgd_phys; u64 vmid, cnp = kvm_cpu_has_cnp() ? VTTBR_CNP_BIT : 0; - bool new_gen; - read_lock(&kvm_vmid_lock); - new_gen = need_new_vmid_gen(kvm); - read_unlock(&kvm_vmid_lock); - - if (!new_gen) + if (!need_new_vmid_gen(kvm)) return; - write_lock(&kvm_vmid_lock); + spin_lock(&kvm_vmid_lock); /* * We need to re-check the vmid_gen here to ensure that if another vcpu @@ -516,7 +513,7 @@ static void update_vttbr(struct kvm *kvm * use the same vmid. */ if (!need_new_vmid_gen(kvm)) { - write_unlock(&kvm_vmid_lock); + spin_unlock(&kvm_vmid_lock); return; } @@ -539,7 +536,6 @@ static void update_vttbr(struct kvm *kvm kvm_call_hyp(__kvm_flush_vm_context); } - kvm->arch.vmid_gen = atomic64_read(&kvm_vmid_gen); kvm->arch.vmid = kvm_next_vmid; kvm_next_vmid++; kvm_next_vmid &= (1 << kvm_vmid_bits) - 1; @@ -550,7 +546,10 @@ static void update_vttbr(struct kvm *kvm vmid = ((u64)(kvm->arch.vmid) << VTTBR_VMID_SHIFT) & VTTBR_VMID_MASK(kvm_vmid_bits); kvm->arch.vttbr = kvm_phys_to_vttbr(pgd_phys) | vmid | cnp; - write_unlock(&kvm_vmid_lock); + smp_wmb(); + WRITE_ONCE(kvm->arch.vmid_gen, atomic64_read(&kvm_vmid_gen)); + + spin_unlock(&kvm_vmid_lock); } static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu)