From patchwork Thu May 2 18:31:25 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aaron Lewis X-Patchwork-Id: 10927487 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 506D41515 for ; Thu, 2 May 2019 18:31:32 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3F91520008 for ; Thu, 2 May 2019 18:31:32 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3130D22B39; Thu, 2 May 2019 18:31:32 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.5 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI, USER_IN_DEF_DKIM_WL autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 25FE220008 for ; Thu, 2 May 2019 18:31:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726138AbfEBSb3 (ORCPT ); Thu, 2 May 2019 14:31:29 -0400 Received: from mail-pg1-f201.google.com ([209.85.215.201]:53316 "EHLO mail-pg1-f201.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725962AbfEBSb3 (ORCPT ); Thu, 2 May 2019 14:31:29 -0400 Received: by mail-pg1-f201.google.com with SMTP id f7so1643283pgi.20 for ; Thu, 02 May 2019 11:31:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:message-id:mime-version:subject:from:to:cc; bh=m5JSsxatSQCQI+MuUyatr4tj7uv59zzuOhugSBaN6yI=; b=YFYeiXVSCnWmk22yNTIkpGdBrlp7Tp9X5UU2uiuZ4C1eqVLnFnvGeuGm6XxIPq5s0S g7+V9UanOCRj1x9d47DOF+rGse3js9Arf4I8qqt6cP5rpc81kodJR82YHV46qamXT9bt nNuUao+xcM8scHeXH/U5e9TGJ0R7zlYQ6BjHg1VvEp3d581N7BrD2oRSWB5YGWAtHif+ OCRyqL3FWUVebOUZSeCZCmR7Jues1BOF+eabuhjsF/n3Xs7P29oN0TOcYtTXvdOmPa5T 3amKt166WBH/mzXkBmEIGLubK7Ne0SA+LU+NCEiz99BqDt8L4fs5aurnLCtOqV+0td/u 4o+A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:message-id:mime-version:subject:from:to:cc; bh=m5JSsxatSQCQI+MuUyatr4tj7uv59zzuOhugSBaN6yI=; b=ZF0PNim+v2kowwafF1xm+JXgukaQyCETB83yZB+xIDYcN45IkUNQ2xrUxH1QXQx8iG BIAXN6L9nrgKiybx3I8mrqnVpktnV8qBi2uDt7eg+U/qhMrpCsKN9YmaYxqaqBCaZyfe WtAXNR5YoNi9nu1sCOJwZc6Zhkrm8Q9sIECNK7gAvzB2sff2ckXuUXZPtKzhWD+E29QW olLYxs5d5gmj1x8vw31YsGoBir9W8nhQHZcGJ0sjdsbfq05mxf7TvMqOaibzjd9/kpO8 AHkHU2dCHAeB4y1wyIS5C7cKb6rWwVbM1ex/zxaid+vEVBJNV3BBswR8METeiCQZeegG H3aQ== X-Gm-Message-State: APjAAAXfDh61YbbY2M3sNKDVTLkK6GiasqEg7bRiT3ZakBCldjiEqCRR D+K81XaPDyBoqqk48hA0Mj5Te0jUB/bgvrPS X-Google-Smtp-Source: APXvYqywx9WB2Xv3CMIWBPaAl3vup69e8gWrmIhnv0nVrSCQHq08ARFHwKGc9j9WhL/eZLnDpRBN5XBxqD6qZ/mL X-Received: by 2002:a63:2b41:: with SMTP id r62mr5467572pgr.403.1556821888761; Thu, 02 May 2019 11:31:28 -0700 (PDT) Date: Thu, 2 May 2019 11:31:25 -0700 Message-Id: <20190502183125.257005-1-aaronlewis@google.com> Mime-Version: 1.0 X-Mailer: git-send-email 2.21.0.593.g511ec345e18-goog Subject: [PATCH 1/3] kvm: nVMX: Set nested_run_pending in vmx_set_nested_state after checks complete From: Aaron Lewis To: pbonzini@redhat.com, rkrcmar@redhat.com, jmattson@google.com, marcorr@google.com, kvm@vger.kernel.org Cc: Aaron Lewis , Peter Shier Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP nested_run_pending=1 implies we have successfully entered guest mode. Move setting from external state in vmx_set_nested_state() until after all other checks are complete. Signed-off-by: Aaron Lewis Reviewed-by: Peter Shier --- arch/x86/kvm/vmx/nested.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index 6401eb7ef19c..081dea6e211a 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -5460,9 +5460,6 @@ static int vmx_set_nested_state(struct kvm_vcpu *vcpu, if (!(kvm_state->flags & KVM_STATE_NESTED_GUEST_MODE)) return 0; - vmx->nested.nested_run_pending = - !!(kvm_state->flags & KVM_STATE_NESTED_RUN_PENDING); - if (nested_cpu_has_shadow_vmcs(vmcs12) && vmcs12->vmcs_link_pointer != -1ull) { struct vmcs12 *shadow_vmcs12 = get_shadow_vmcs12(vcpu); @@ -5489,6 +5486,9 @@ static int vmx_set_nested_state(struct kvm_vcpu *vcpu, if (ret) return -EINVAL; + vmx->nested.nested_run_pending = + !!(kvm_state->flags & KVM_STATE_NESTED_RUN_PENDING); + return 0; } From patchwork Thu May 2 18:31:33 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aaron Lewis X-Patchwork-Id: 10927489 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3C1EC14B6 for ; Thu, 2 May 2019 18:31:38 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2DAFA20008 for ; Thu, 2 May 2019 18:31:38 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2145722B39; Thu, 2 May 2019 18:31:38 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.5 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI, USER_IN_DEF_DKIM_WL autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C92A120008 for ; Thu, 2 May 2019 18:31:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726150AbfEBSbh (ORCPT ); Thu, 2 May 2019 14:31:37 -0400 Received: from mail-oi1-f202.google.com ([209.85.167.202]:34985 "EHLO mail-oi1-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725962AbfEBSbg (ORCPT ); Thu, 2 May 2019 14:31:36 -0400 Received: by mail-oi1-f202.google.com with SMTP id u135so1589806oia.2 for ; Thu, 02 May 2019 11:31:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:message-id:mime-version:subject:from:to:cc; bh=1wdEmKD5eKqokJpkPtk7KxNlmpgJyCP7ZVZyjPalqFQ=; b=IeehO9RnlCiTUA2VOiiZqB+jKOwia0KHRn7+6c+ldMsfGqEriioKb+vI1ESbWulumz tJbpzgInJe9bKcGaEodscJilcyKUHtabgwtXvRpI2HVYePITko0migtOstdLP8Is/REo G+yQC0Gmz/iEQRZNTtMp+cyPpYg5SLXb4nL5d/0b/li96MzkjAhqYqe20D9NQi4Wzn2k h48R2o2icuPTKBvoU1Gl8jzkQUH4iNmABH/KVDij3xqxTkT3cGoEwUIWVML9M9jCOSLP sv3ePCsskh/z2zmmL+6j79Thup1I/2GkYdh9nqOYuLHdkKhxMRKTHsCa+6KTG6w68OlF MOTA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:message-id:mime-version:subject:from:to:cc; bh=1wdEmKD5eKqokJpkPtk7KxNlmpgJyCP7ZVZyjPalqFQ=; b=bZhRnSPIJ10fCnS2/cgZqeHAE0dnFiP1MdQkHgy8HCZxS0gpvYH3t2fVE1Uf/vwk6h 4bpbek9LzKqNiyLnh5oHc8viwsqTv+KBe1cA8LeZx8iXynCMLLjnAlLuO15m1zo8Plwe BFQr8XRrV3KGqN0drUSHVflBBEIZfCpd1Z7HXNSXHTlxPZSa8Fval6evEtLPBJMfcbHv C3bE+3XV5DMkWNfx2jPosjutTg8mSHluzwb389fSUtXuova9BDDe9o7OJGdpnzdSwKei 1uxVvhRrVaBVxCSn79VqMSpazepETx7jOZlFQoiawj5dlGCF30dVeqHBDkF9qYlWrOC4 9K7A== X-Gm-Message-State: APjAAAUOJp4HLEet+PDGi2JD0+Va3hH0+uULOdIwsgJTvVgGBDZztwKW UwD9sMiq7xmTcEHlBSJbv6m26Y2zUvLvNO8E X-Google-Smtp-Source: APXvYqwFLDglIgcl+4nmlpRLh0xry9cy3Le36WYlcplIkwb+bTOLWa5+rzeee0VTT4k/PnWrGbpv7PS0r0P0a41g X-Received: by 2002:aca:ac08:: with SMTP id v8mr3457668oie.44.1556821896206; Thu, 02 May 2019 11:31:36 -0700 (PDT) Date: Thu, 2 May 2019 11:31:33 -0700 Message-Id: <20190502183133.258026-1-aaronlewis@google.com> Mime-Version: 1.0 X-Mailer: git-send-email 2.21.0.593.g511ec345e18-goog Subject: [PATCH 2/3] KVM: nVMX: KVM_SET_NESTED_STATE - Tear down old EVMCS state before setting new state From: Aaron Lewis To: pbonzini@redhat.com, rkrcmar@redhat.com, jmattson@google.com, marcorr@google.com, vkuznets@redhat.com, kvm@vger.kernel.org Cc: Aaron Lewis , Peter Shier Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Move call to nested_enable_evmcs until after free_nested() is complete. Signed-off-by: Aaron Lewis Reviewed-by: Marc Orr Reviewed-by: Peter Shier Signed-off-by: Aaron Lewis Reviewed-by: Marc Orr Reviewed-by: Peter Shier --- arch/x86/kvm/vmx/nested.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index 081dea6e211a..3b39c60951ac 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -5373,9 +5373,6 @@ static int vmx_set_nested_state(struct kvm_vcpu *vcpu, if (kvm_state->format != 0) return -EINVAL; - if (kvm_state->flags & KVM_STATE_NESTED_EVMCS) - nested_enable_evmcs(vcpu, NULL); - if (!nested_vmx_allowed(vcpu)) return kvm_state->vmx.vmxon_pa == -1ull ? 0 : -EINVAL; @@ -5417,6 +5414,9 @@ static int vmx_set_nested_state(struct kvm_vcpu *vcpu, if (kvm_state->vmx.vmxon_pa == -1ull) return 0; + if (kvm_state->flags & KVM_STATE_NESTED_EVMCS) + nested_enable_evmcs(vcpu, NULL); + vmx->nested.vmxon_ptr = kvm_state->vmx.vmxon_pa; ret = enter_vmx_operation(vcpu); if (ret) From patchwork Thu May 2 18:31:41 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aaron Lewis X-Patchwork-Id: 10927491 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 064591515 for ; Thu, 2 May 2019 18:31:49 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EB5CE20008 for ; Thu, 2 May 2019 18:31:48 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id DFAE522B39; Thu, 2 May 2019 18:31:48 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.5 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI, USER_IN_DEF_DKIM_WL autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0C20320008 for ; Thu, 2 May 2019 18:31:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726201AbfEBSbr (ORCPT ); Thu, 2 May 2019 14:31:47 -0400 Received: from mail-yw1-f73.google.com ([209.85.161.73]:42879 "EHLO mail-yw1-f73.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726193AbfEBSbq (ORCPT ); Thu, 2 May 2019 14:31:46 -0400 Received: by mail-yw1-f73.google.com with SMTP id q2so5092598ywd.9 for ; Thu, 02 May 2019 11:31:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:message-id:mime-version:subject:from:to:cc; bh=nttFQl4+ZyYOOOXVU4coa0ys0cbTGwDwPaM88r9bviQ=; b=W6Oj0OKmvQ/NNikjF23W0wA20glHyARLpnelj9Z94hCer7cD/EvWbTMG+Lv4exSWpE gdB87Y/pP8IS9RWkgHlH6V+4bIdsqrawXO2cyI6+koXahdNZOtjPw0S9/ltHkVc0gcVZ thyJm5ieoiGZcTZicNid5EAby+j7v7IzeWcd4QdZq43PPtQiZV4iPtW2sMNa275/qWww vA93pIRZWiwF1Qd5leqKinATWydHMPczqdOG3umej1ntTiPZaOFm28W4PGpOVRe/6t/L j/Tm89lswikwt56SIWhtgj1Cu85/eys9FPTaMJRs2sWUcE2aMYqNAZci4Rn+52hZ2l7q JhbQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:message-id:mime-version:subject:from:to:cc; bh=nttFQl4+ZyYOOOXVU4coa0ys0cbTGwDwPaM88r9bviQ=; b=aaybNmoY/0jelcmnet9udHd6EXHQCYzmy+k5UZeYhhQFibbTi+V47b9nLKLHoaYzVg doe2nHOsmhr4ZjwtfP18viHsqsmIgNRD9dV6BTaxHR5a2zbn1IVMYQl2IzSSrPQnTIwn joP6+rwbDmoApShA68OYUjmTkBnyhxYEN1k3iZHxPacz7pTS9/VNBo+AUGaohLP6l3Qx bBghhmTrsZucvAfPdrh4HBcol9M1S/5SJmCnOnFzOs1UEH88NlArQdHWlMtgvmj4P7bC N19Z8pWxFx0EwVYJ2kaWCf+dIZS4q/Y04FmDCgxCfB7xPvbgbeQ7sZIVaSo9yURNHG4p gISA== X-Gm-Message-State: APjAAAUN2wzrYa375h4dgPLqEUrTwn+BGdMqhOFj63epH3zABGqxS3cJ UJ1fETqN70xwkLdwpYzODwwPh7YMsCNRc6WX X-Google-Smtp-Source: APXvYqy3e8IFu87JztVhU26+Qd4krEjo0uuoir4n0tEPKsCxndrVp9pEqNfyl+z2fO2UzH3szE1iQT+iiEdN9ulx X-Received: by 2002:a25:bc0a:: with SMTP id i10mr4467444ybh.121.1556821905858; Thu, 02 May 2019 11:31:45 -0700 (PDT) Date: Thu, 2 May 2019 11:31:41 -0700 Message-Id: <20190502183141.258667-1-aaronlewis@google.com> Mime-Version: 1.0 X-Mailer: git-send-email 2.21.0.593.g511ec345e18-goog Subject: [PATCH 3/3] tests: kvm: Add tests for KVM_SET_NESTED_STATE From: Aaron Lewis To: pbonzini@redhat.com, rkrcmar@redhat.com, jmattson@google.com, marcorr@google.com, kvm@vger.kernel.org Cc: Aaron Lewis , Peter Shier Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add tests for KVM_SET_NESTED_STATE and for various code paths in its implementation in vmx_set_nested_state(). Signed-off-by: Aaron Lewis Reviewed-by: Marc Orr Reviewed-by: Peter Shier --- tools/testing/selftests/kvm/.gitignore | 1 + tools/testing/selftests/kvm/Makefile | 1 + .../testing/selftests/kvm/include/kvm_util.h | 4 + tools/testing/selftests/kvm/lib/kvm_util.c | 32 ++ .../kvm/x86_64/vmx_set_nested_state_test.c | 275 ++++++++++++++++++ 5 files changed, 313 insertions(+) create mode 100644 tools/testing/selftests/kvm/x86_64/vmx_set_nested_state_test.c diff --git a/tools/testing/selftests/kvm/.gitignore b/tools/testing/selftests/kvm/.gitignore index 2689d1ea6d7a..bbaa97dbd19e 100644 --- a/tools/testing/selftests/kvm/.gitignore +++ b/tools/testing/selftests/kvm/.gitignore @@ -6,4 +6,5 @@ /x86_64/vmx_close_while_nested_test /x86_64/vmx_tsc_adjust_test /x86_64/state_test +/x86_64/vmx_set_nested_state_test /dirty_log_test diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile index f8588cca2bef..10eff4317226 100644 --- a/tools/testing/selftests/kvm/Makefile +++ b/tools/testing/selftests/kvm/Makefile @@ -20,6 +20,7 @@ TEST_GEN_PROGS_x86_64 += x86_64/evmcs_test TEST_GEN_PROGS_x86_64 += x86_64/hyperv_cpuid TEST_GEN_PROGS_x86_64 += x86_64/vmx_close_while_nested_test TEST_GEN_PROGS_x86_64 += x86_64/smm_test +TEST_GEN_PROGS_x86_64 += x86_64/vmx_set_nested_state_test TEST_GEN_PROGS_x86_64 += dirty_log_test TEST_GEN_PROGS_x86_64 += clear_dirty_log_test diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h index 07b71ad9734a..8c6b9619797d 100644 --- a/tools/testing/selftests/kvm/include/kvm_util.h +++ b/tools/testing/selftests/kvm/include/kvm_util.h @@ -118,6 +118,10 @@ void vcpu_events_get(struct kvm_vm *vm, uint32_t vcpuid, struct kvm_vcpu_events *events); void vcpu_events_set(struct kvm_vm *vm, uint32_t vcpuid, struct kvm_vcpu_events *events); +void vcpu_nested_state_get(struct kvm_vm *vm, uint32_t vcpuid, + struct kvm_nested_state *state); +int vcpu_nested_state_set(struct kvm_vm *vm, uint32_t vcpuid, + struct kvm_nested_state *state, bool ignore_error); const char *exit_reason_str(unsigned int exit_reason); diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c index 4ca96b228e46..e9113857f44e 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -1250,6 +1250,38 @@ void vcpu_events_set(struct kvm_vm *vm, uint32_t vcpuid, ret, errno); } +void vcpu_nested_state_get(struct kvm_vm *vm, uint32_t vcpuid, + struct kvm_nested_state *state) +{ + struct vcpu *vcpu = vcpu_find(vm, vcpuid); + int ret; + + TEST_ASSERT(vcpu != NULL, "vcpu not found, vcpuid: %u", vcpuid); + + ret = ioctl(vcpu->fd, KVM_GET_NESTED_STATE, state); + TEST_ASSERT(ret == 0, + "KVM_SET_NESTED_STATE failed, ret: %i errno: %i", + ret, errno); +} + +int vcpu_nested_state_set(struct kvm_vm *vm, uint32_t vcpuid, + struct kvm_nested_state *state, bool ignore_error) +{ + struct vcpu *vcpu = vcpu_find(vm, vcpuid); + int ret; + + TEST_ASSERT(vcpu != NULL, "vcpu not found, vcpuid: %u", vcpuid); + + ret = ioctl(vcpu->fd, KVM_SET_NESTED_STATE, state); + if (!ignore_error) { + TEST_ASSERT(ret == 0, + "KVM_SET_NESTED_STATE failed, ret: %i errno: %i", + ret, errno); + } + + return ret; +} + /* * VM VCPU System Regs Get * 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 new file mode 100644 index 000000000000..5eea24087d19 --- /dev/null +++ b/tools/testing/selftests/kvm/x86_64/vmx_set_nested_state_test.c @@ -0,0 +1,275 @@ +/* + * vmx_set_nested_state_test + * + * Copyright (C) 2019, Google LLC. + * + * This work is licensed under the terms of the GNU GPL, version 2. + * + * This test verifies the integrity of calling the ioctl KVM_SET_NESTED_STATE. + */ + +#include "test_util.h" +#include "kvm_util.h" +#include "processor.h" +#include "vmx.h" + +#include +#include +#include +#include +#include + +/* + * Mirror of VMCS12_REVISION in arch/x86/kvm/vmx/vmcs12.h. If that value + * changes this should be updated. + */ +#define VMCS12_REVISION 0x11e57ed0 +#define VCPU_ID 5 + +void test_nested_state(struct kvm_vm *vm, struct kvm_nested_state *state) +{ + volatile struct kvm_run *run; + + vcpu_nested_state_set(vm, VCPU_ID, state, false); + run = vcpu_state(vm, VCPU_ID); + vcpu_run(vm, VCPU_ID); + TEST_ASSERT(run->exit_reason == KVM_EXIT_SHUTDOWN, + "Got exit_reason other than KVM_EXIT_SHUTDOWN: %u (%s),\n", + run->exit_reason, + exit_reason_str(run->exit_reason)); +} + +void test_nested_state_expect_errno(struct kvm_vm *vm, + struct kvm_nested_state *state, + int expected_errno) +{ + volatile struct kvm_run *run; + int rv; + + rv = vcpu_nested_state_set(vm, VCPU_ID, state, true); + TEST_ASSERT(rv == -1 && errno == expected_errno, + "Expected %s (%d) from vcpu_nested_state_set but got rv: %i errno: %s (%d)", + strerror(expected_errno), expected_errno, rv, strerror(errno), + errno); + run = vcpu_state(vm, VCPU_ID); + vcpu_run(vm, VCPU_ID); + TEST_ASSERT(run->exit_reason == KVM_EXIT_SHUTDOWN, + "Got exit_reason other than KVM_EXIT_SHUTDOWN: %u (%s),\n", + run->exit_reason, + exit_reason_str(run->exit_reason)); +} + +void test_nested_state_expect_einval(struct kvm_vm *vm, + struct kvm_nested_state *state) +{ + test_nested_state_expect_errno(vm, state, EINVAL); +} + +void test_nested_state_expect_efault(struct kvm_vm *vm, + struct kvm_nested_state *state) +{ + test_nested_state_expect_errno(vm, state, EFAULT); +} + +void set_revision_id_for_vmcs12(struct kvm_nested_state *state, + u32 vmcs12_revision) +{ + /* Set revision_id in vmcs12 to vmcs12_revision. */ + *(u32 *)(state->data) = vmcs12_revision; +} + +void set_default_state(struct kvm_nested_state *state) +{ + memset(state, 0, sizeof(*state)); + state->flags = KVM_STATE_NESTED_RUN_PENDING | + KVM_STATE_NESTED_GUEST_MODE; + state->format = 0; + state->size = sizeof(*state); +} + +void set_default_vmx_state(struct kvm_nested_state *state, int size) +{ + memset(state, 0, size); + state->flags = KVM_STATE_NESTED_GUEST_MODE | + KVM_STATE_NESTED_RUN_PENDING | + KVM_STATE_NESTED_EVMCS; + state->format = 0; + state->size = size; + state->vmx.vmxon_pa = 0x1000; + state->vmx.vmcs_pa = 0x2000; + state->vmx.smm.flags = 0; + set_revision_id_for_vmcs12(state, VMCS12_REVISION); +} + +void test_vmx_nested_state(struct kvm_vm *vm) +{ + /* Add a page for VMCS12. */ + const int state_sz = sizeof(struct kvm_nested_state) + getpagesize(); + struct kvm_nested_state *state = + (struct kvm_nested_state *)malloc(state_sz); + + /* The format must be set to 0. 0 for VMX, 1 for SVM. */ + set_default_vmx_state(state, state_sz); + state->format = 1; + test_nested_state_expect_einval(vm, state); + + /* + * We cannot virtualize anything if the guest does not have VMX + * enabled. + */ + set_default_vmx_state(state, state_sz); + test_nested_state_expect_einval(vm, state); + + /* + * 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. + */ + set_default_vmx_state(state, state_sz); + state->vmx.vmxon_pa = -1ull; + 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. */ + set_default_vmx_state(state, state_sz); + state->vmx.vmxon_pa = -1ull; + state->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->vmx.vmxon_pa = -1ull; + state->vmx.vmcs_pa = 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->vmx.vmxon_pa = -1ull; + state->vmx.vmcs_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->vmx.vmxon_pa = 1; + test_nested_state_expect_einval(vm, state); + + /* + * It is invalid to have KVM_STATE_NESTED_SMM_GUEST_MODE and + * KVM_STATE_NESTED_GUEST_MODE set together. + */ + set_default_vmx_state(state, state_sz); + state->flags = KVM_STATE_NESTED_GUEST_MODE | + KVM_STATE_NESTED_RUN_PENDING; + state->vmx.smm.flags = KVM_STATE_NESTED_SMM_GUEST_MODE; + test_nested_state_expect_einval(vm, state); + + /* + * It is invalid to have any of the SMM flags set besides: + * KVM_STATE_NESTED_SMM_GUEST_MODE + * KVM_STATE_NESTED_SMM_VMXON + */ + set_default_vmx_state(state, state_sz); + state->vmx.smm.flags = ~(KVM_STATE_NESTED_SMM_GUEST_MODE | + KVM_STATE_NESTED_SMM_VMXON); + test_nested_state_expect_einval(vm, state); + + /* Outside SMM, SMM flags must be zero. */ + set_default_vmx_state(state, state_sz); + state->flags = 0; + state->vmx.smm.flags = KVM_STATE_NESTED_SMM_GUEST_MODE; + test_nested_state_expect_einval(vm, state); + + /* Size must be large enough to fit kvm_nested_state and vmcs12. */ + set_default_vmx_state(state, state_sz); + state->size = sizeof(*state); + test_nested_state(vm, state); + + /* vmxon_pa cannot be the same address as vmcs_pa. */ + set_default_vmx_state(state, state_sz); + state->vmx.vmxon_pa = 0; + state->vmx.vmcs_pa = 0; + test_nested_state_expect_einval(vm, state); + + /* The revision id for vmcs12 must be VMCS12_REVISION. */ + set_default_vmx_state(state, state_sz); + set_revision_id_for_vmcs12(state, 0); + test_nested_state_expect_einval(vm, state); + + /* + * Test that if we leave nesting the state reflects that when we get + * it again. + */ + set_default_vmx_state(state, state_sz); + state->vmx.vmxon_pa = -1ull; + state->vmx.vmcs_pa = -1ull; + state->flags = 0; + test_nested_state(vm, state); + vcpu_nested_state_get(vm, VCPU_ID, state); + TEST_ASSERT(state->size >= sizeof(*state) && state->size <= state_sz, + "Size must be between %d and %d. The size returned was %d.", + sizeof(*state), state_sz, state->size); + TEST_ASSERT(state->vmx.vmxon_pa == -1ull, "vmxon_pa must be -1ull."); + TEST_ASSERT(state->vmx.vmcs_pa == -1ull, "vmcs_pa must be -1ull."); + + free(state); +} + +int main(int argc, char *argv[]) +{ + struct kvm_vm *vm; + struct kvm_nested_state state; + struct kvm_cpuid_entry2 *entry = kvm_get_supported_cpuid_entry(1); + + /* + * AMD currently does not implement set_nested_state, so for now we + * just early out. + */ + if (!(entry->ecx & CPUID_VMX)) { + fprintf(stderr, "nested VMX not enabled, skipping test\n"); + exit(KSFT_SKIP); + } + + vm = vm_create_default(VCPU_ID, 0, 0); + + /* Passing a NULL kvm_nested_state causes a EFAULT. */ + test_nested_state_expect_efault(vm, NULL); + + /* 'size' cannot be smaller than sizeof(kvm_nested_state). */ + set_default_state(&state); + state.size = 0; + test_nested_state_expect_einval(vm, &state); + + /* + * Setting the flags 0xf fails the flags check. The only flags that + * can be used are: + * KVM_STATE_NESTED_GUEST_MODE + * KVM_STATE_NESTED_RUN_PENDING + * KVM_STATE_NESTED_EVMCS + */ + set_default_state(&state); + state.flags = 0xf; + test_nested_state_expect_einval(vm, &state); + + /* + * If KVM_STATE_NESTED_RUN_PENDING is set then + * KVM_STATE_NESTED_GUEST_MODE has to be set as well. + */ + set_default_state(&state); + state.flags = KVM_STATE_NESTED_RUN_PENDING; + test_nested_state_expect_einval(vm, &state); + + /* + * TODO: When SVM support is added for KVM_SET_NESTED_STATE + * add tests here to support it like VMX. + */ + if (entry->ecx & CPUID_VMX) + test_vmx_nested_state(vm); + + kvm_vm_free(vm); + return 0; +}