Received: by 2002:a25:ab43:0:0:0:0:0 with SMTP id u61csp848078ybi; Wed, 19 Jun 2019 08:51:24 -0700 (PDT) X-Google-Smtp-Source: APXvYqxwEO8nn2ta4jVAAXDFYaucYLAGwjVVj/Mk+iCQbmMnuQOnDaa+8WTyvpmqRoU/s8mka6Hj X-Received: by 2002:a65:5202:: with SMTP id o2mr7722094pgp.199.1560959484178; Wed, 19 Jun 2019 08:51:24 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1560959484; cv=none; d=google.com; s=arc-20160816; b=Y7/+fiheD7tUV6Aiga+y35ubKMulhY22jE5GchJnho/1VG0IbyvmKMsLB0hk2xtSNs OUWmZmBLIvspo6xpV5/NmB4wJi5Xc7f3qgE+y4bdR7ES1pcRVNgZAFzIhyZYirLKhgBL nv1QNz9ndHrO2aDvSlBs4ytGM2zwUpw97p03A7l7G/gqbWmEcRLzFfgvtchxlRmZ2lWq hs+rrwotpr1KDW4DKIeJmmiNgxIqTOonLMLUMmlo0XiUVD8de99wg0HxYPoNoxMJGqVl cWI3b/0hmwrM0D7y/U59oJtSDoxQKx5zr/Sfajx98e2bi21mYuGxxUS7dIOZwMZT23Ap LZjQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:date:subject:cc:to:from :dkim-signature; bh=zjf81C76HrVq+IReyDc6rr3+Eybofc2ke2b3vedZ5Rg=; b=sf+Uxu1ytt7vzToRLYo4ySRk3r00Ya91puJ6CGLhfl6kPr1Q3d/QOWycyMyawBA/9L LY2lk8HMaw2ukKBG7XF2eCHlZAavcKbE9WRNPoUMqmE7b+fiOblfhXhezp0Q9boJfB6r NxOw9Z0DT6w0IA//Qes1iqfJ9ubPTmEJD/8fBHz1EEaz6yf3BhLCS915K/U8mrWMAfkt 0qivgriPcbggrJ3eM5Vks8K53nAvvSmZb6e7nKTs2FJiQ1086lKERxL5j6wQwOUOkxAD zM2PNbV6bSdnPECIANiJINqvZtt4XNwXK6mZ+qS/0cfHFq6eIFFrezcDn/vixYnvh/YU C7vQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@gmail.com header.s=20161025 header.b=ULctRkHD; 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id cn1si12489800plb.204.2019.06.19.08.51.07; Wed, 19 Jun 2019 08:51:24 -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=fail header.i=@gmail.com header.s=20161025 header.b=ULctRkHD; 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729131AbfFSPuC (ORCPT + 99 others); Wed, 19 Jun 2019 11:50:02 -0400 Received: from mail-wr1-f67.google.com ([209.85.221.67]:46023 "EHLO mail-wr1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726091AbfFSPuC (ORCPT ); Wed, 19 Jun 2019 11:50:02 -0400 Received: by mail-wr1-f67.google.com with SMTP id f9so3897778wre.12; Wed, 19 Jun 2019 08:49:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id; bh=zjf81C76HrVq+IReyDc6rr3+Eybofc2ke2b3vedZ5Rg=; b=ULctRkHDOigvuGlSvdwNv3rWYSF9l80UIsojktkG8wSVREp60zn7BBE0zSyH4N1C+c L3QO7i7auNozvzvjRDFGY92+L8FgL94ArECvsovHgh6SCv94okLREIFeVG+ncRncFQZo adh5deAk9NRmmpuRxNyk0YFZw8C2rcgt6tWYpPnidOI5d2mM1nHZ2YfaS0CYu7PHno1w 6jLtVujb2t47X+hh0PgqPsb/FZL2bayp0ebjBm8K8squkHPdR+9JImYWaPIV/CtiL1Zu 9gIh6TMh8OG2lXWeCuqJ4IPAw9MRzsrA+dSJoNx44vovu+Io3vUNkW4dyZTl1FwIaOEX EG9Q== 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; bh=zjf81C76HrVq+IReyDc6rr3+Eybofc2ke2b3vedZ5Rg=; b=ksB/GcdwDtRAduY3xrMOt0aEWwRAw8kKDrnF28PU/cfOrPlybD05XiZIAmGca1ELpQ TFOQPErPVjY/BMyURU5gCsb+INpav0I5QfkcdSNwnsD05uOrVWmznWOdWJY5O6gInq3o k66Q96KkoNBkb1zxgBpV4vGeTa2ZwKERjjU0rRDZdBTbuHiSTCtORj4N42uTflnAcaOP wpiTIPti5U8rxvsosXK22YJPDAOWv/yXKro+jtWpgEqx8h8sgsSw/xkqG5J034nGqqPr SvXXiqCnLtKOIRDA77OuKJfhXfrLgUOhQJQcj9FkS5EK5TpyWd8IeEsWVySB+mKGdKjL wn+Q== X-Gm-Message-State: APjAAAXbPim8m2f7RqyxXJgPe7yyF6xvPLB/nf/fP8Igqeo/kgBsObxp 3ni2vu3KfUGS7AJ4Er5QssPn2irl X-Received: by 2002:adf:dd03:: with SMTP id a3mr34099070wrm.87.1560959398652; Wed, 19 Jun 2019 08:49:58 -0700 (PDT) Received: from 640k.lan ([93.56.166.5]) by smtp.gmail.com with ESMTPSA id q21sm1977424wmq.13.2019.06.19.08.49.57 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 19 Jun 2019 08:49:57 -0700 (PDT) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: Aaron Lewis , Vitaly Kuznetsov Subject: [PATCH] KVM: nVMX: reorganize initial steps of vmx_set_nested_state Date: Wed, 19 Jun 2019 17:49:56 +0200 Message-Id: <1560959396-13969-1-git-send-email-pbonzini@redhat.com> X-Mailer: git-send-email 1.8.3.1 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Commit 332d079735f5 ("KVM: nVMX: KVM_SET_NESTED_STATE - Tear down old EVMCS state before setting new state", 2019-05-02) broke evmcs_test because the eVMCS setup must be performed even if there is no VMXON region defined, as long as the eVMCS bit is set in the assist page. While the simplest possible fix would be to add a check on kvm_state->flags & KVM_STATE_NESTED_EVMCS in the initial "if" that covers kvm_state->hdr.vmx.vmxon_pa == -1ull, that is quite ugly. Instead, this patch moves checks earlier in the function and conditionalizes them on kvm_state->hdr.vmx.vmxon_pa, so that vmx_set_nested_state always goes through vmx_leave_nested and nested_enable_evmcs. Fixes: 332d079735f5 Cc: Aaron Lewis Cc: Vitaly Kuznetsov Signed-off-by: Paolo Bonzini --- arch/x86/kvm/vmx/nested.c | 26 ++++++++++-------- .../kvm/x86_64/vmx_set_nested_state_test.c | 32 ++++++++++++++-------- 2 files changed, 35 insertions(+), 23 deletions(-) diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index fb6d1f7b43f3..5f9c1a200201 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -5343,9 +5343,6 @@ static int vmx_set_nested_state(struct kvm_vcpu *vcpu, if (kvm_state->format != KVM_STATE_NESTED_FORMAT_VMX) return -EINVAL; - if (!nested_vmx_allowed(vcpu)) - return kvm_state->hdr.vmx.vmxon_pa == -1ull ? 0 : -EINVAL; - if (kvm_state->hdr.vmx.vmxon_pa == -1ull) { if (kvm_state->hdr.vmx.smm.flags) return -EINVAL; @@ -5353,12 +5350,15 @@ static int vmx_set_nested_state(struct kvm_vcpu *vcpu, if (kvm_state->hdr.vmx.vmcs12_pa != -1ull) return -EINVAL; - vmx_leave_nested(vcpu); - return 0; - } + if (kvm_state->flags & ~KVM_STATE_NESTED_EVMCS) + return -EINVAL; + } else { + if (!nested_vmx_allowed(vcpu)) + return -EINVAL; - if (!page_address_valid(vcpu, kvm_state->hdr.vmx.vmxon_pa)) - return -EINVAL; + if (!page_address_valid(vcpu, kvm_state->hdr.vmx.vmxon_pa)) + return -EINVAL; + } if ((kvm_state->hdr.vmx.smm.flags & KVM_STATE_NESTED_SMM_GUEST_MODE) && (kvm_state->flags & KVM_STATE_NESTED_GUEST_MODE)) @@ -5381,11 +5381,15 @@ static int vmx_set_nested_state(struct kvm_vcpu *vcpu, return -EINVAL; vmx_leave_nested(vcpu); - if (kvm_state->hdr.vmx.vmxon_pa == -1ull) - return 0; + if (kvm_state->flags & KVM_STATE_NESTED_EVMCS) { + if (!nested_vmx_allowed(vcpu)) + return -EINVAL; - if (kvm_state->flags & KVM_STATE_NESTED_EVMCS) nested_enable_evmcs(vcpu, NULL); + } + + if (kvm_state->hdr.vmx.vmxon_pa == -1ull) + return 0; vmx->nested.vmxon_ptr = kvm_state->hdr.vmx.vmxon_pa; ret = enter_vmx_operation(vcpu); diff --git a/tools/testing/selftests/kvm/x86_64/vmx_set_nested_state_test.c b/tools/testing/selftests/kvm/x86_64/vmx_set_nested_state_test.c index 0648fe6df5a8..e64ca20b315a 100644 --- a/tools/testing/selftests/kvm/x86_64/vmx_set_nested_state_test.c +++ b/tools/testing/selftests/kvm/x86_64/vmx_set_nested_state_test.c @@ -123,36 +123,44 @@ void test_vmx_nested_state(struct kvm_vm *vm) /* * We cannot virtualize anything if the guest does not have VMX * enabled. We expect KVM_SET_NESTED_STATE to return 0 if vmxon_pa - * is set to -1ull. + * is set to -1ull, but the flags must be zero. */ set_default_vmx_state(state, state_sz); state->hdr.vmx.vmxon_pa = -1ull; + test_nested_state_expect_einval(vm, state); + + state->hdr.vmx.vmcs12_pa = -1ull; + state->flags = KVM_STATE_NESTED_EVMCS; + test_nested_state_expect_einval(vm, state); + + state->flags = 0; test_nested_state(vm, state); /* Enable VMX in the guest CPUID. */ vcpu_set_cpuid(vm, VCPU_ID, kvm_get_supported_cpuid()); - /* It is invalid to have vmxon_pa == -1ull and SMM flags non-zero. */ + /* + * Setting vmxon_pa == -1ull and vmcs_pa == -1ull exits early without + * setting the nested state but flags other than eVMCS must be clear. + */ set_default_vmx_state(state, state_sz); state->hdr.vmx.vmxon_pa = -1ull; + state->hdr.vmx.vmcs12_pa = -1ull; + test_nested_state_expect_einval(vm, state); + + state->flags = KVM_STATE_NESTED_EVMCS; + test_nested_state(vm, state); + + /* It is invalid to have vmxon_pa == -1ull and SMM flags non-zero. */ state->hdr.vmx.smm.flags = 1; test_nested_state_expect_einval(vm, state); /* It is invalid to have vmxon_pa == -1ull and vmcs_pa != -1ull. */ set_default_vmx_state(state, state_sz); state->hdr.vmx.vmxon_pa = -1ull; - state->hdr.vmx.vmcs12_pa = 0; + state->flags = 0; test_nested_state_expect_einval(vm, state); - /* - * Setting vmxon_pa == -1ull and vmcs_pa == -1ull exits early without - * setting the nested state. - */ - set_default_vmx_state(state, state_sz); - state->hdr.vmx.vmxon_pa = -1ull; - state->hdr.vmx.vmcs12_pa = -1ull; - test_nested_state(vm, state); - /* It is invalid to have vmxon_pa set to a non-page aligned address. */ set_default_vmx_state(state, state_sz); state->hdr.vmx.vmxon_pa = 1; -- 1.8.3.1