Received: by 2002:a05:6a10:9e8c:0:0:0:0 with SMTP id y12csp311018pxx; Wed, 28 Oct 2020 05:38:32 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyWzw4+ARFk5Kq4/vBK13MKoFQ1xFLUkz3F5nopAkv6FvUHONlLJ5yyTaxUW148kESVnXoc X-Received: by 2002:aa7:c14a:: with SMTP id r10mr7684226edp.345.1603888712263; Wed, 28 Oct 2020 05:38:32 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1603888712; cv=none; d=google.com; s=arc-20160816; b=LEZHp/Y3NDR58HHsxXLXHmS+knXNPpYMzAh79Q+AQD297E/GiRlD47XDn6+74lOCSo LUB35MB4we7/MMSdtJUfO2PTfRXFJ1MTGSZI0S0A3C0FpLKypdTcr2x5FoENf5TwVloF 0AcPiqpQK+HbQT20rr/BUqQSKjieQO/Iy7I73hBzL2MF/SOgynYh6JCp5lzMwqyzXd9k Q4500zlEllmL5f9q67IuxoBBbfQW+INwn3ktTljd81oqu0NWyb9R65mMVe+DGZLmR8JB CD4oKGjnJItVk7x9XCw/6HHJfRlkEoYpt/2rUb9j/7EsWPigtauNnfgtHTty/QIOn+Q/ F1vA== 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:dkim-signature; bh=xNkkCrkAr5eVTVzRTybW4MVOVIAb2uXs9RZ8Dukrk1Q=; b=HWbpkKiVnTTAhv3xOHF8kV3CBlDq/2AFYFntadrpprR58LePF8gM36Qrs3CxD06E7R ZuqikYeiC1heqkrrPjqrrRoJvw+349B1H3YfN/6eZQWUlc+Kk4XxZAPGGQS+v9Sg8ddI gNaMctlKXiLmtsmhzkO/OIecX0BGypuZd8V3aOpVMsQkoIbHIGxNZnX38HyL5TfqYrbg ZJ3YEkNBSLG/FT7suDUFCXHO6tX7el9TufetKu2cugInjooauRmJ9VefnAxt7JhrYItM PPHa6FknoQusa6H2MX6tOfXVE0y5zI8zsF1b8Kvj1D+IOxKVckvyJmgYVerC1G3Z6YLq /cMw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b="u//SPXUj"; 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 w17si2969573ejk.629.2020.10.28.05.38.09; Wed, 28 Oct 2020 05:38:32 -0700 (PDT) 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; dkim=pass header.i=@kernel.org header.s=default header.b="u//SPXUj"; 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 S1797456AbgJ0PXj (ORCPT + 99 others); Tue, 27 Oct 2020 11:23:39 -0400 Received: from mail.kernel.org ([198.145.29.99]:36246 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1797103AbgJ0PVi (ORCPT ); Tue, 27 Oct 2020 11:21:38 -0400 Received: from localhost (83-86-74-64.cable.dynamic.v4.ziggo.nl [83.86.74.64]) (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 E7AAB20657; Tue, 27 Oct 2020 15:21:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1603812097; bh=6yv3Oh8wNkjZaKoanGeblrl+rJZ6HHCfqns5L9hxAtE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=u//SPXUjWsu+c7jsXyEMtRHs9tgddSD6PA4M9+/JxyiDhMSNGaVwmXvBSZGHsWlTK DYpOLspvJNeJzIjMpJUoMQps6ijM+x/GJU3ZAo4V19+VZM7mVgvjKUcigNykPsSk07 X0sRKHUaq7UQbKUH7OJ+jBkWBXHslTEVQJF15FR8= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Sean Christopherson , Paolo Bonzini Subject: [PATCH 5.9 074/757] KVM: nVMX: Reset the segment cache when stuffing guest segs Date: Tue, 27 Oct 2020 14:45:24 +0100 Message-Id: <20201027135454.019797277@linuxfoundation.org> X-Mailer: git-send-email 2.29.1 In-Reply-To: <20201027135450.497324313@linuxfoundation.org> References: <20201027135450.497324313@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: Sean Christopherson commit fc387d8daf3960c5e1bc18fa353768056f4fd394 upstream. Explicitly reset the segment cache after stuffing guest segment regs in prepare_vmcs02_rare(). Although the cache is reset when switching to vmcs02, there is nothing that prevents KVM from re-populating the cache prior to writing vmcs02 with vmcs12's values. E.g. if the vCPU is preempted after switching to vmcs02 but before prepare_vmcs02_rare(), kvm_arch_vcpu_put() will dereference GUEST_SS_AR_BYTES via .get_cpl() and cache the stale vmcs02 value. While the current code base only caches stale data in the preemption case, it's theoretically possible future code could read a segment register during the nested flow itself, i.e. this isn't technically illegal behavior in kvm_arch_vcpu_put(), although it did introduce the bug. This manifests as an unexpected nested VM-Enter failure when running with unrestricted guest disabled if the above preemption case coincides with L1 switching L2's CPL, e.g. when switching from a L2 vCPU at CPL3 to to a L2 vCPU at CPL0. stack_segment_valid() will see the new SS_SEL but the old SS_AR_BYTES and incorrectly mark the guest state as invalid due to SS.dpl != SS.rpl. Don't bother updating the cache even though prepare_vmcs02_rare() writes every segment. With unrestricted guest, guest segments are almost never read, let alone L2 guest segments. On the other hand, populating the cache requires a large number of memory writes, i.e. it's unlikely to be a net win. Updating the cache would be a win when unrestricted guest is not supported, as guest_state_valid() will immediately cache all segment registers. But, nested virtualization without unrestricted guest is dirt slow, saving some VMREADs won't change that, and every CPU manufactured in the last decade supports unrestricted guest. In other words, the extra (minor) complexity isn't worth the trouble. Note, kvm_arch_vcpu_put() may see stale data when querying guest CPL depending on when preemption occurs. This is "ok" in that the usage is imperfect by nature, i.e. it's used heuristically to improve performance but doesn't affect functionality. kvm_arch_vcpu_put() could be "fixed" by also disabling preemption while loading segments, but that's pointless and misleading as reading state from kvm_sched_{in,out}() is guaranteed to see stale data in one form or another. E.g. even if all the usage of regs_avail is fixed to call kvm_register_mark_available() after the associated state is set, the individual state might still be stale with respect to the overall vCPU state. I.e. making functional decisions in an asynchronous hook is doomed from the get go. Thankfully KVM doesn't do that. Fixes: de63ad4cf4973 ("KVM: X86: implement the logic for spinlock optimization") Cc: stable@vger.kernel.org Signed-off-by: Sean Christopherson Message-Id: <20200923184452.980-2-sean.j.christopherson@intel.com> Signed-off-by: Paolo Bonzini Signed-off-by: Greg Kroah-Hartman --- arch/x86/kvm/vmx/nested.c | 2 ++ 1 file changed, 2 insertions(+) --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -2408,6 +2408,8 @@ static void prepare_vmcs02_rare(struct v vmcs_writel(GUEST_TR_BASE, vmcs12->guest_tr_base); vmcs_writel(GUEST_GDTR_BASE, vmcs12->guest_gdtr_base); vmcs_writel(GUEST_IDTR_BASE, vmcs12->guest_idtr_base); + + vmx->segment_cache.bitmask = 0; } if (!hv_evmcs || !(hv_evmcs->hv_clean_fields &