Received: by 2002:a05:6a10:f347:0:0:0:0 with SMTP id d7csp2876239pxu; Sat, 19 Dec 2020 05:03:46 -0800 (PST) X-Google-Smtp-Source: ABdhPJwy9Xl3sM3Z5lIUPF8Dv2wpxD8sU1jhtFGuvb2kz/nNWAlRopDPpfc79kwO+1IdCgQZQGlh X-Received: by 2002:a17:906:b306:: with SMTP id n6mr8229576ejz.473.1608383026091; Sat, 19 Dec 2020 05:03:46 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1608383026; cv=none; d=google.com; s=arc-20160816; b=pneOvBbXA6aUjUOC3a3U4UKX7CWDhAlrabhhLj2XKePYt3cuIu1dHPLuBipby7jbS8 PUXFYoEB6h+cwFczgM/8qv8n9r+p4BkooK039KaNdn5dmPkMQLl5rMDm8xAcEcMyCrjY fZenvxg6LT1d1yrgtsv10OrSkd1YG75l8webjOcfq5aHwveXjSLQ1uoQcXEqdQaOBDR/ MiCb4WgTcWNpMUyj4Ybyad7+lVhAbv/MPikJ3PRPCNHP7CIIV+VeXHXz5VTj4KEZJLhx JLUhfVSb7tispokSsVymo91PBfFksbEK1O8FF++Qjd4IfqmLADQyJ769Urx43KM/TrfE gQHQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from; bh=3TN7766wJ5x7ffzpQUvimcgXXbqa3nS0L3GIX3dxID8=; b=EoTqHBVAQqrm6m8xsbBQFXRaf4OJg8P6vqkeSuVGYZVHXxHl4YpPLJZdY5TcX4vdzK bL7ptcRSjMIiYplyRjnpNEkfC5gNys8ni0ByL26W+bl407NTzjoF/+IDujJKiKsorrEz hf7UaGFAVoCLFA1jEuL7gcVMFSqIeAJNqbjqTiJgFAHPRbq942TN/YP0SQhi742X79s2 n4dky/O0ARZc188pSrcFrqjsV95/7wv9/N+/RAIMY609rSqSmpYWYCSBdSgLRb4qg3Hy n3X3g0YyMBoj4/815hElIxNI+4qtA9f/+MWjYiKh6Ilkq0NGotg0hOHy4huzxTKGhLw3 uliA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id j16si5576361ejc.358.2020.12.19.05.03.23; Sat, 19 Dec 2020 05:03:46 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727284AbgLSNCB (ORCPT + 99 others); Sat, 19 Dec 2020 08:02:01 -0500 Received: from mail.kernel.org ([198.145.29.99]:45836 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728038AbgLSM7P (ORCPT ); Sat, 19 Dec 2020 07:59:15 -0500 From: Greg Kroah-Hartman Authentication-Results: mail.kernel.org; dkim=permerror (bad message/signature format) To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, "Maciej S. Szmigiero" , Paolo Bonzini Subject: [PATCH 5.9 46/49] KVM: mmu: Fix SPTE encoding of MMIO generation upper half Date: Sat, 19 Dec 2020 13:58:50 +0100 Message-Id: <20201219125346.920614354@linuxfoundation.org> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20201219125344.671832095@linuxfoundation.org> References: <20201219125344.671832095@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Maciej S. Szmigiero commit 34c0f6f2695a2db81e09a3ab7bdb2853f45d4d3d upstream. Commit cae7ed3c2cb0 ("KVM: x86: Refactor the MMIO SPTE generation handling") cleaned up the computation of MMIO generation SPTE masks, however it introduced a bug how the upper part was encoded: SPTE bits 52-61 were supposed to contain bits 10-19 of the current generation number, however a missing shift encoded bits 1-10 there instead (mostly duplicating the lower part of the encoded generation number that then consisted of bits 1-9). In the meantime, the upper part was shrunk by one bit and moved by subsequent commits to become an upper half of the encoded generation number (bits 9-17 of bits 0-17 encoded in a SPTE). In addition to the above, commit 56871d444bc4 ("KVM: x86: fix overlap between SPTE_MMIO_MASK and generation") has changed the SPTE bit range assigned to encode the generation number and the total number of bits encoded but did not update them in the comment attached to their defines, nor in the KVM MMU doc. Let's do it here, too, since it is too trivial thing to warrant a separate commit. Fixes: cae7ed3c2cb0 ("KVM: x86: Refactor the MMIO SPTE generation handling") Signed-off-by: Maciej S. Szmigiero Message-Id: <156700708db2a5296c5ed7a8b9ac71f1e9765c85.1607129096.git.maciej.szmigiero@oracle.com> Cc: stable@vger.kernel.org [Reorganize macros so that everything is computed from the bit ranges. - Paolo] Signed-off-by: Paolo Bonzini Signed-off-by: Greg Kroah-Hartman --- Documentation/virt/kvm/mmu.rst | 2 +- arch/x86/kvm/mmu/mmu.c | 29 ++++++++++++++++++++--------- 2 files changed, 21 insertions(+), 10 deletions(-) --- a/Documentation/virt/kvm/mmu.rst +++ b/Documentation/virt/kvm/mmu.rst @@ -455,7 +455,7 @@ If the generation number of the spte doe number, it will ignore the cached MMIO information and handle the page fault through the slow path. -Since only 19 bits are used to store generation-number on mmio spte, all +Since only 18 bits are used to store generation-number on mmio spte, all pages are zapped when there is an overflow. Unfortunately, a single memory access might access kvm_memslots(kvm) multiple --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -402,11 +402,11 @@ static inline bool is_access_track_spte( } /* - * Due to limited space in PTEs, the MMIO generation is a 19 bit subset of + * Due to limited space in PTEs, the MMIO generation is a 18 bit subset of * the memslots generation and is derived as follows: * * Bits 0-8 of the MMIO generation are propagated to spte bits 3-11 - * Bits 9-18 of the MMIO generation are propagated to spte bits 52-61 + * Bits 9-17 of the MMIO generation are propagated to spte bits 54-62 * * The KVM_MEMSLOT_GEN_UPDATE_IN_PROGRESS flag is intentionally not included in * the MMIO generation number, as doing so would require stealing a bit from @@ -415,18 +415,29 @@ static inline bool is_access_track_spte( * requires a full MMU zap). The flag is instead explicitly queried when * checking for MMIO spte cache hits. */ -#define MMIO_SPTE_GEN_MASK GENMASK_ULL(17, 0) #define MMIO_SPTE_GEN_LOW_START 3 #define MMIO_SPTE_GEN_LOW_END 11 -#define MMIO_SPTE_GEN_LOW_MASK GENMASK_ULL(MMIO_SPTE_GEN_LOW_END, \ - MMIO_SPTE_GEN_LOW_START) #define MMIO_SPTE_GEN_HIGH_START PT64_SECOND_AVAIL_BITS_SHIFT #define MMIO_SPTE_GEN_HIGH_END 62 + +#define MMIO_SPTE_GEN_LOW_MASK GENMASK_ULL(MMIO_SPTE_GEN_LOW_END, \ + MMIO_SPTE_GEN_LOW_START) #define MMIO_SPTE_GEN_HIGH_MASK GENMASK_ULL(MMIO_SPTE_GEN_HIGH_END, \ MMIO_SPTE_GEN_HIGH_START) +#define MMIO_SPTE_GEN_LOW_BITS (MMIO_SPTE_GEN_LOW_END - MMIO_SPTE_GEN_LOW_START + 1) +#define MMIO_SPTE_GEN_HIGH_BITS (MMIO_SPTE_GEN_HIGH_END - MMIO_SPTE_GEN_HIGH_START + 1) + +/* remember to adjust the comment above as well if you change these */ +static_assert(MMIO_SPTE_GEN_LOW_BITS == 9 && MMIO_SPTE_GEN_HIGH_BITS == 9); + +#define MMIO_SPTE_GEN_LOW_SHIFT (MMIO_SPTE_GEN_LOW_START - 0) +#define MMIO_SPTE_GEN_HIGH_SHIFT (MMIO_SPTE_GEN_HIGH_START - MMIO_SPTE_GEN_LOW_BITS) + +#define MMIO_SPTE_GEN_MASK GENMASK_ULL(MMIO_SPTE_GEN_LOW_BITS + MMIO_SPTE_GEN_HIGH_BITS - 1, 0) + static u64 generation_mmio_spte_mask(u64 gen) { u64 mask; @@ -434,8 +445,8 @@ static u64 generation_mmio_spte_mask(u64 WARN_ON(gen & ~MMIO_SPTE_GEN_MASK); BUILD_BUG_ON((MMIO_SPTE_GEN_HIGH_MASK | MMIO_SPTE_GEN_LOW_MASK) & SPTE_SPECIAL_MASK); - mask = (gen << MMIO_SPTE_GEN_LOW_START) & MMIO_SPTE_GEN_LOW_MASK; - mask |= (gen << MMIO_SPTE_GEN_HIGH_START) & MMIO_SPTE_GEN_HIGH_MASK; + mask = (gen << MMIO_SPTE_GEN_LOW_SHIFT) & MMIO_SPTE_GEN_LOW_MASK; + mask |= (gen << MMIO_SPTE_GEN_HIGH_SHIFT) & MMIO_SPTE_GEN_HIGH_MASK; return mask; } @@ -443,8 +454,8 @@ static u64 get_mmio_spte_generation(u64 { u64 gen; - gen = (spte & MMIO_SPTE_GEN_LOW_MASK) >> MMIO_SPTE_GEN_LOW_START; - gen |= (spte & MMIO_SPTE_GEN_HIGH_MASK) >> MMIO_SPTE_GEN_HIGH_START; + gen = (spte & MMIO_SPTE_GEN_LOW_MASK) >> MMIO_SPTE_GEN_LOW_SHIFT; + gen |= (spte & MMIO_SPTE_GEN_HIGH_MASK) >> MMIO_SPTE_GEN_HIGH_SHIFT; return gen; }