From patchwork Mon Mar 13 10:51:42 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sergey Dyasli X-Patchwork-Id: 9620461 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 6E67260414 for ; Mon, 13 Mar 2017 10:54:03 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 61A0C28458 for ; Mon, 13 Mar 2017 10:54:03 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 55E3A2845E; Mon, 13 Mar 2017 10:54:03 +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=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id C9F7B28458 for ; Mon, 13 Mar 2017 10:54:02 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1cnNa2-0007Pw-B2; Mon, 13 Mar 2017 10:51:58 +0000 Received: from mail6.bemta5.messagelabs.com ([195.245.231.135]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1cnNa1-0007P2-6n for xen-devel@lists.xen.org; Mon, 13 Mar 2017 10:51:57 +0000 Received: from [85.158.139.211] by server-17.bemta-5.messagelabs.com id 35/1F-00654-CC976C85; Mon, 13 Mar 2017 10:51:56 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFmphkeJIrShJLcpLzFFi42JxWrrBXvdM5bE Ig0NzOSyWfFzM4sDocXT3b6YAxijWzLyk/IoE1owdCz8yFlyQqujZfYGtgXG/SBcjJ4eEgL/E 9INnWEFsNgE9iY2zXzGB2CICshKru+awdzFycTALHGGUmLrqCDtIQljAVWLKwQXMIDaLgKrEn +O9QDYHB6+ArcTjqz4QM+UkLm37AhbmFLCTOH+AHyQsBFTx9NJ9RghbVeL1i10sIDavgKDEyZ lPwGxmAQmJgy9eME9g5J2FJDULSWoBI9MqRo3i1KKy1CJdQ3O9pKLM9IyS3MTMHF1DA1O93NT i4sT01JzEpGK95PzcTYzA0GEAgh2MF097HmKU5GBSEuV923woQogvKT+lMiOxOCO+qDQntfgQ owwHh5IE7+czQDnBotT01Iq0zBxgEMOkJTh4lER4zc8CpXmLCxJzizPTIVKnGBWlxHn/gvQJg CQySvPg2mCRc4lRVkqYlxHoECGegtSi3MwSVPlXjOIcjErCvDkg43ky80rgpr8CWswEtHga30 GQxSWJCCmpBsaJPWl29yw/7/G780dw/y0+x1AR1m7tXeXvKiPvbvnMIhqVFfY/UrVfWoPZ81F Z57Q119Rr/fb5rmc7XCSXMoFD+at5dXj//EOBzV1WJ53/vXz5v5P53XrB8IqJrZmNq6d9vSW9 y067flFMZUaKobe9cql9kXrBqvaPFY/zIz9NdAtwPdahr8RSnJFoqMVcVJwIAPnBLsGXAgAA X-Env-Sender: prvs=23829f5b7=sergey.dyasli@citrix.com X-Msg-Ref: server-7.tower-206.messagelabs.com!1489402313!86280350!2 X-Originating-IP: [66.165.176.63] X-SpamReason: No, hits=0.0 required=7.0 tests=sa_preprocessor: VHJ1c3RlZCBJUDogNjYuMTY1LjE3Ni42MyA9PiAzMDYwNDg=\n, received_headers: No Received headers X-StarScan-Received: X-StarScan-Version: 9.2.3; banners=-,-,- X-VirusChecked: Checked Received: (qmail 50597 invoked from network); 13 Mar 2017 10:51:55 -0000 Received: from smtp02.citrix.com (HELO SMTP02.CITRIX.COM) (66.165.176.63) by server-7.tower-206.messagelabs.com with RC4-SHA encrypted SMTP; 13 Mar 2017 10:51:55 -0000 X-IronPort-AV: E=Sophos;i="5.36,158,1486425600"; d="scan'208";a="422224507" From: Sergey Dyasli To: Date: Mon, 13 Mar 2017 10:51:42 +0000 Message-ID: <20170313105143.20842-3-sergey.dyasli@citrix.com> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170313105143.20842-1-sergey.dyasli@citrix.com> References: <20170313105143.20842-1-sergey.dyasli@citrix.com> MIME-Version: 1.0 Cc: Andrew Cooper , Kevin Tian , Jan Beulich , Jun Nakajima , Sergey Dyasli Subject: [Xen-devel] [PATCH v1 2/3] x86/vvmx: correct nested shadow VMCS handling X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" X-Virus-Scanned: ClamAV using ClamSMTP Currently xen always sets the shadow VMCS-indicator bit on nested vmptrld and always clears it on nested vmclear. This behavior is wrong when the guest loads a shadow VMCS: shadow bit will be lost on nested vmclear. Fix this by checking if the guest has provided a shadow VMCS. Signed-off-by: Sergey Dyasli Acked-by: Kevin Tian --- xen/arch/x86/hvm/vmx/vvmx.c | 22 ++++++++++++++++++---- xen/include/asm-x86/hvm/vmx/vvmx.h | 1 + 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/xen/arch/x86/hvm/vmx/vvmx.c b/xen/arch/x86/hvm/vmx/vvmx.c index 09e4250..3017849 100644 --- a/xen/arch/x86/hvm/vmx/vvmx.c +++ b/xen/arch/x86/hvm/vmx/vvmx.c @@ -1119,10 +1119,19 @@ static bool_t nvmx_vpid_enabled(const struct vcpu *v) static void nvmx_set_vmcs_pointer(struct vcpu *v, struct vmcs_struct *vvmcs) { + struct nestedvmx *nvmx = &vcpu_2_nvmx(v); paddr_t vvmcs_maddr = v->arch.hvm_vmx.vmcs_shadow_maddr; __vmpclear(vvmcs_maddr); - vvmcs->vmcs_revision_id |= VMCS_RID_TYPE_MASK; + if ( !nvmx->shadow_vmcs ) + { + /* + * We must set the shadow VMCS-indicator in order for the next vmentry + * to succeed with a newly set up link pointer in vmcs01. + * Note: guest can see that this bit was set. + */ + vvmcs->vmcs_revision_id |= VMCS_RID_TYPE_MASK; + } __vmwrite(VMCS_LINK_POINTER, vvmcs_maddr); __vmwrite(VMREAD_BITMAP, page_to_maddr(v->arch.hvm_vmx.vmread_bitmap)); __vmwrite(VMWRITE_BITMAP, page_to_maddr(v->arch.hvm_vmx.vmwrite_bitmap)); @@ -1130,10 +1139,13 @@ static void nvmx_set_vmcs_pointer(struct vcpu *v, struct vmcs_struct *vvmcs) static void nvmx_clear_vmcs_pointer(struct vcpu *v, struct vmcs_struct *vvmcs) { + struct nestedvmx *nvmx = &vcpu_2_nvmx(v); paddr_t vvmcs_maddr = v->arch.hvm_vmx.vmcs_shadow_maddr; __vmpclear(vvmcs_maddr); - vvmcs->vmcs_revision_id &= ~VMCS_RID_TYPE_MASK; + if ( !nvmx->shadow_vmcs ) + vvmcs->vmcs_revision_id &= ~VMCS_RID_TYPE_MASK; + nvmx->shadow_vmcs = false; __vmwrite(VMCS_LINK_POINTER, ~0ul); __vmwrite(VMREAD_BITMAP, 0); __vmwrite(VMWRITE_BITMAP, 0); @@ -1674,12 +1686,14 @@ int nvmx_handle_vmptrld(struct cpu_user_regs *regs) { if ( writable ) { + struct nestedvmx *nvmx = &vcpu_2_nvmx(v); struct vmcs_struct *vvmcs = vvmcx; + nvmx->shadow_vmcs = + vvmcs->vmcs_revision_id & ~VMX_BASIC_REVISION_MASK; if ( ((vvmcs->vmcs_revision_id ^ vmx_basic_msr) & VMX_BASIC_REVISION_MASK) || - (!cpu_has_vmx_vmcs_shadowing && - (vvmcs->vmcs_revision_id & ~VMX_BASIC_REVISION_MASK)) ) + (!cpu_has_vmx_vmcs_shadowing && nvmx->shadow_vmcs) ) { hvm_unmap_guest_frame(vvmcx, 1); vmfail(regs, VMX_INSN_VMPTRLD_INCORRECT_VMCS_ID); diff --git a/xen/include/asm-x86/hvm/vmx/vvmx.h b/xen/include/asm-x86/hvm/vmx/vvmx.h index ca2fb25..9a65218 100644 --- a/xen/include/asm-x86/hvm/vmx/vvmx.h +++ b/xen/include/asm-x86/hvm/vmx/vvmx.h @@ -51,6 +51,7 @@ struct nestedvmx { } ept; uint32_t guest_vpid; struct list_head launched_list; + bool shadow_vmcs; }; #define vcpu_2_nvmx(v) (vcpu_nestedhvm(v).u.nvmx)