Received: by 2002:ac0:a582:0:0:0:0:0 with SMTP id m2-v6csp2341888imm; Thu, 11 Oct 2018 08:47:57 -0700 (PDT) X-Google-Smtp-Source: ACcGV62aesYHSBrMte0uFXaL+bm1yJTNUZ7d8q/SZp0/Bmhs1YWmvl/w3zi/Rgw9FGGH5PmflCuX X-Received: by 2002:a62:d286:: with SMTP id c128-v6mr2113499pfg.14.1539272877377; Thu, 11 Oct 2018 08:47:57 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1539272877; cv=none; d=google.com; s=arc-20160816; b=Jp67RfpKGE2FriP4aUceQqInCFeCr8JMgEbf7yIbdPEP0BzQXP4xQhpiA/x5dqkafn 0MxzDoEStuEgEWwZzj/w2EiP4WkLDeiPIrJ/LvB4ysDrZ6nC+HjE7fAGH388FRp0ZcGv 2e8UUxUVwuJoL4Ths7XX0VO3lTDgYebVvLjLZaGMFeCvEbHDBl5XJxWQ01dCIXKL7Wc9 DMVByhxlE9ef0E+70p+qk+tHG/5xFqPJ6ARcptv5HLQEZaIacQApF4jyvbRbCO+yD2Hq bGVb4wtYx5Gj9U3mv9kyDjVhSeOZOgPCniMBJGIqq4dPZhBbXXg0euW+/7FtwNmlIqic JLyw== 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=zTRI67BPg6cGG8dCEMtw7EyUGvYGrNzHPa7UUpiaKBg=; b=nqDfXw3ECCCt6FpFVzo7412ge4r1ogQG7C/8xq7Z/QY7cWA/UsmAK5NdYP4J/EGI39 0mN6srQbpZfOtuZAzle/S9l6nSvYGRxpcyjECKC16nY/O4HIT0X2uJBroRzI2Xj43N6L sCu671V+uER9Z2Jvnrwrgb2ZhnwYy9iyYaLiWk+nc56gRtg/C79i9bfsj0fHplxsLXU4 BGaouU67ev91196PjqGi6TcuBSR1x8E0LtJvQbwlU4gM9KKGctN6IH6bKVGJzf9BuPoL BMFwaUCheUVWInhzVWHS63VcR06KYn8BLtACWfAXNxI4VUPp0knQxrrXg10k4qu3q1jt 2bJQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=SiQRFEvv; 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 o5-v6si20395183plh.96.2018.10.11.08.47.42; Thu, 11 Oct 2018 08:47:57 -0700 (PDT) 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=SiQRFEvv; 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 S1731571AbeJKXOM (ORCPT + 99 others); Thu, 11 Oct 2018 19:14:12 -0400 Received: from mail.kernel.org ([198.145.29.99]:47094 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726700AbeJKXOM (ORCPT ); Thu, 11 Oct 2018 19:14:12 -0400 Received: from localhost (ip-213-127-77-176.ip.prioritytelecom.net [213.127.77.176]) (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 86BE7213A2; Thu, 11 Oct 2018 15:46:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1539272786; bh=l3stj+o57SubcEgGWasAKfC7PPLWZ/JDfqq8X6Cg06w=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=SiQRFEvvzGaWbrsTsIUqRJazAzCxQuqqvaJiK3XV3yc6G8zMt8zkcfaywJ0CMO587 rR1jhHaPQpItnXTfW/nzTPxl4Mnuw9f4mavIV2Tyju72YAhb/zb+RJECdX2F08zeQM B0G4zJIUWQsQkHqXWQhDgEyr+xaVfRXyrVohdFcw= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Sakari Ailus , Junaid Shahid , Jim Mattson , Sakari Ailus , Sean Christopherson , Paolo Bonzini Subject: [PATCH 4.14 05/45] KVM: x86: fix L1TFs MMIO GFN calculation Date: Thu, 11 Oct 2018 17:39:32 +0200 Message-Id: <20181011152509.092819524@linuxfoundation.org> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181011152508.885515042@linuxfoundation.org> References: <20181011152508.885515042@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review 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.14-stable review patch. If anyone has any objections, please let me know. ------------------ From: Sean Christopherson commit daa07cbc9ae3da2d61b7ce900c0b9107d134f2c1 upstream. One defense against L1TF in KVM is to always set the upper five bits of the *legal* physical address in the SPTEs for non-present and reserved SPTEs, e.g. MMIO SPTEs. In the MMIO case, the GFN of the MMIO SPTE may overlap with the upper five bits that are being usurped to defend against L1TF. To preserve the GFN, the bits of the GFN that overlap with the repurposed bits are shifted left into the reserved bits, i.e. the GFN in the SPTE will be split into high and low parts. When retrieving the GFN from the MMIO SPTE, e.g. to check for an MMIO access, get_mmio_spte_gfn() unshifts the affected bits and restores the original GFN for comparison. Unfortunately, get_mmio_spte_gfn() neglects to mask off the reserved bits in the SPTE that were used to store the upper chunk of the GFN. As a result, KVM fails to detect MMIO accesses whose GPA overlaps the repurprosed bits, which in turn causes guest panics and hangs. Fix the bug by generating a mask that covers the lower chunk of the GFN, i.e. the bits that aren't shifted by the L1TF mitigation. The alternative approach would be to explicitly zero the five reserved bits that are used to store the upper chunk of the GFN, but that requires additional run-time computation and makes an already-ugly bit of code even more inscrutable. I considered adding a WARN_ON_ONCE(low_phys_bits-1 <= PAGE_SHIFT) to warn if GENMASK_ULL() generated a nonsensical value, but that seemed silly since that would mean a system that supports VMX has less than 18 bits of physical address space... Reported-by: Sakari Ailus Fixes: d9b47449c1a1 ("kvm: x86: Set highest physical address bits in non-present/reserved SPTEs") Cc: Junaid Shahid Cc: Jim Mattson Cc: stable@vger.kernel.org Reviewed-by: Junaid Shahid Tested-by: Sakari Ailus Signed-off-by: Sean Christopherson Signed-off-by: Paolo Bonzini Signed-off-by: Greg Kroah-Hartman --- arch/x86/kvm/mmu.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -231,6 +231,17 @@ static u64 __read_mostly shadow_nonprese */ static const u64 shadow_nonpresent_or_rsvd_mask_len = 5; +/* + * In some cases, we need to preserve the GFN of a non-present or reserved + * SPTE when we usurp the upper five bits of the physical address space to + * defend against L1TF, e.g. for MMIO SPTEs. To preserve the GFN, we'll + * shift bits of the GFN that overlap with shadow_nonpresent_or_rsvd_mask + * left into the reserved bits, i.e. the GFN in the SPTE will be split into + * high and low parts. This mask covers the lower bits of the GFN. + */ +static u64 __read_mostly shadow_nonpresent_or_rsvd_lower_gfn_mask; + + static void mmu_spte_set(u64 *sptep, u64 spte); static void mmu_free_roots(struct kvm_vcpu *vcpu); @@ -338,9 +349,7 @@ static bool is_mmio_spte(u64 spte) static gfn_t get_mmio_spte_gfn(u64 spte) { - u64 mask = generation_mmio_spte_mask(MMIO_GEN_MASK) | shadow_mmio_mask | - shadow_nonpresent_or_rsvd_mask; - u64 gpa = spte & ~mask; + u64 gpa = spte & shadow_nonpresent_or_rsvd_lower_gfn_mask; gpa |= (spte >> shadow_nonpresent_or_rsvd_mask_len) & shadow_nonpresent_or_rsvd_mask; @@ -404,6 +413,8 @@ EXPORT_SYMBOL_GPL(kvm_mmu_set_mask_ptes) static void kvm_mmu_reset_all_pte_masks(void) { + u8 low_phys_bits; + shadow_user_mask = 0; shadow_accessed_mask = 0; shadow_dirty_mask = 0; @@ -418,12 +429,17 @@ static void kvm_mmu_reset_all_pte_masks( * appropriate mask to guard against L1TF attacks. Otherwise, it is * assumed that the CPU is not vulnerable to L1TF. */ + low_phys_bits = boot_cpu_data.x86_phys_bits; if (boot_cpu_data.x86_phys_bits < - 52 - shadow_nonpresent_or_rsvd_mask_len) + 52 - shadow_nonpresent_or_rsvd_mask_len) { shadow_nonpresent_or_rsvd_mask = rsvd_bits(boot_cpu_data.x86_phys_bits - shadow_nonpresent_or_rsvd_mask_len, boot_cpu_data.x86_phys_bits - 1); + low_phys_bits -= shadow_nonpresent_or_rsvd_mask_len; + } + shadow_nonpresent_or_rsvd_lower_gfn_mask = + GENMASK_ULL(low_phys_bits - 1, PAGE_SHIFT); } static int is_cpuid_PSE36(void)