From patchwork Thu Oct 26 17:03:17 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Euan Harris X-Patchwork-Id: 10028655 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 2496C601E8 for ; Thu, 26 Oct 2017 17:06:34 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 10A3628E75 for ; Thu, 26 Oct 2017 17:06:34 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 051E328E7F; Thu, 26 Oct 2017 17:06:34 +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 6AD3228E75 for ; Thu, 26 Oct 2017 17:06:33 +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 1e7lZj-0002mE-4y; Thu, 26 Oct 2017 17:04:11 +0000 Received: from mail6.bemta6.messagelabs.com ([193.109.254.103]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1e7lZi-0002kL-3o for xen-devel@lists.xenproject.org; Thu, 26 Oct 2017 17:04:10 +0000 Received: from [193.109.254.147] by server-5.bemta-6.messagelabs.com id 45/E5-29911-98512F95; Thu, 26 Oct 2017 17:04:09 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFprDIsWRWlGSWpSXmKPExsXitHRDpG6H6Kd IgwkNZhbft0xmcmD0OPzhCksAYxRrZl5SfkUCa8bLt0eYC2bYV1w6m9DAeFa/i5GTQ0LAX6L9 xj42EJtNQEti94eF7F2MHBwiAioSt/cadDFycTAL9DJKLH1/gQmkRljATWL12dksIDaLgKrEv 9PPwGxeoPihOz/ZIWYqSEx5+J4ZxOYUcJc4tHAT2HwhoJqL336xQtjKEh+urGGH6BWUODnzCd gcZgEJiYMvXjBPYOSdhSQ1C0lqASPTKkaN4tSistQiXSNLvaSizPSMktzEzBxdQwMzvdzU4uL E9NScxKRiveT83E2MwNBhAIIdjAcWBR5ilORgUhLlZdjzIVKILyk/pTIjsTgjvqg0J7X4EKMM B4eSBK+syKdIIcGi1PTUirTMHGAQw6QlOHiURHg7QNK8xQWJucWZ6RCpU4yWHMvOXfrDxNFx8 y6QfDbzdQOzEEtefl6qlDivKUiDAEhDRmke3DhYpF1ilJUS5mUEOlCIpyC1KDezBFX+FaM4B6 OSMG8zyBSezLwSuK2vgA5iAjqoSfUDyEEliQgpqQbGLPnsw6YzbDdnH7xb2zwnYAIbR9ulrbf e64sq+cj3vTC289JdoeF1b5dd2P9yY33GtZEKvC921Vj85T4n+6hixXLb7l+nJf6+0NyjGf3l yMUKvl8c3HtfTVayXPdJ8MSMuCMb3055anWxT3vFtZXGqmy6twLf39JR8LwQYZA2/9vty9/DO s++UWIpzkg01GIuKk4EAF6iK5yvAgAA X-Env-Sender: prvs=465eced58=euan.harris@citrix.com X-Msg-Ref: server-7.tower-27.messagelabs.com!1509037444!108999864!3 X-Originating-IP: [66.165.176.89] X-SpamReason: No, hits=0.0 required=7.0 tests=sa_preprocessor: VHJ1c3RlZCBJUDogNjYuMTY1LjE3Ni44OSA9PiAyMDMwMDc=\n, received_headers: No Received headers X-StarScan-Received: X-StarScan-Version: 9.4.45; banners=-,-,- X-VirusChecked: Checked Received: (qmail 48653 invoked from network); 26 Oct 2017 17:04:08 -0000 Received: from smtp.citrix.com (HELO SMTP.CITRIX.COM) (66.165.176.89) by server-7.tower-27.messagelabs.com with RC4-SHA encrypted SMTP; 26 Oct 2017 17:04:08 -0000 X-IronPort-AV: E=Sophos;i="5.44,301,1505779200"; d="scan'208";a="448413592" From: Euan Harris To: Date: Thu, 26 Oct 2017 18:03:17 +0100 Message-ID: <1509037399-48926-8-git-send-email-euan.harris@citrix.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1509037399-48926-1-git-send-email-euan.harris@citrix.com> References: <1509037399-48926-1-git-send-email-euan.harris@citrix.com> MIME-Version: 1.0 Cc: andrew.cooper3@citrix.com, kevin.tian@intel.com, Euan Harris , jun.nakajima@intel.com, jbeulich@suse.com Subject: [Xen-devel] [PATCH 7/9] x86/vvmx: Use correct sizes when reading operands 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 The sizes of VMX operands are defined in the Intel SDM and have nothing to do with the addr_size field of struct vmx_inst_info: invept: r32/r64, m128 invvpid: r32/r64, m128 vmclear: m64 vmptrld: m64 vmptrst: m64 vmread: r32/64 or m32/64, r32/64 vmwrite: r32/r64, r32/64 or m32/64 vmon: m64 * Register operands are 32-bit or 64-bit depending on the guest mode. * Memory operands are almost always of fixed size, usually 64-bit, but for vmread and vmwrite their size depends on the guest mode. * invept has a 128-bit memory operand but the upper 64 bits are reserved and therefore need not be read. * invvpid has a 128-bit memory operand but we only require the VPID value which lies in the lower 64 bits. When reading variable-size operands, we pass the operand size calculated by decode_vmx_inst() and stored in strcut vmx_inst_op. When reading fixed-size operands, we pass the size of the variable into which the operand is to be read. Signed-off-by: Euan Harris --- xen/arch/x86/hvm/vmx/vvmx.c | 48 +++++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/xen/arch/x86/hvm/vmx/vvmx.c b/xen/arch/x86/hvm/vmx/vvmx.c index fc2123c7c0..9a4e6177ad 100644 --- a/xen/arch/x86/hvm/vmx/vvmx.c +++ b/xen/arch/x86/hvm/vmx/vvmx.c @@ -197,11 +197,9 @@ struct vmx_inst_decoded { #define VMX_INST_MEMREG_TYPE_REG 1 struct vmx_inst_op { int type; + unsigned int bytes; union { - struct { - unsigned long mem; - unsigned int len; - }; + unsigned long mem; unsigned int reg_idx; }; } op[2]; @@ -464,6 +462,8 @@ static int decode_vmx_inst(struct cpu_user_regs *regs, unsigned long base, index, seg_base, disp, offset; int scale, size; + unsigned int bytes = vmx_guest_x86_mode(v); + if ( vmx_inst_check_privilege(regs, vmxon_check) != X86EMUL_OKAY ) return X86EMUL_EXCEPTION; @@ -473,10 +473,11 @@ static int decode_vmx_inst(struct cpu_user_regs *regs, if ( info.fields.memreg ) { decode->op[0].type = VMX_INST_MEMREG_TYPE_REG; decode->op[0].reg_idx = info.fields.reg1; + decode->op[0].bytes = bytes; } else { - bool mode_64bit = (vmx_guest_x86_mode(v) == 8); + bool mode_64bit = (bytes == 8); decode->op[0].type = VMX_INST_MEMREG_TYPE_MEMORY; @@ -508,11 +509,12 @@ static int decode_vmx_inst(struct cpu_user_regs *regs, goto gp_fault; decode->op[0].mem = base; - decode->op[0].len = size; + decode->op[0].bytes = bytes; } decode->op[1].type = VMX_INST_MEMREG_TYPE_REG; decode->op[1].reg_idx = info.fields.reg2; + decode->op[1].bytes = bytes; return X86EMUL_OKAY; @@ -1494,7 +1496,7 @@ int nvmx_handle_vmxon(struct cpu_user_regs *regs) struct nestedvmx *nvmx = &vcpu_2_nvmx(v); struct nestedvcpu *nvcpu = &vcpu_nestedhvm(v); struct vmx_inst_decoded decode; - unsigned long gpa = 0; + uint64_t gpa; uint32_t nvmcs_revid; int rc; @@ -1502,7 +1504,7 @@ int nvmx_handle_vmxon(struct cpu_user_regs *regs) if ( rc != X86EMUL_OKAY ) return rc; - rc = operand_read(&gpa, &decode.op[0], regs, decode.op[0].len); + rc = operand_read(&gpa, &decode.op[0], regs, sizeof(gpa)); if ( rc != X86EMUL_OKAY ) return rc; @@ -1715,14 +1717,14 @@ int nvmx_handle_vmptrld(struct cpu_user_regs *regs) struct vcpu *v = current; struct vmx_inst_decoded decode; struct nestedvcpu *nvcpu = &vcpu_nestedhvm(v); - unsigned long gpa = 0; + uint64_t gpa; int rc; rc = decode_vmx_inst(regs, &decode, 0); if ( rc != X86EMUL_OKAY ) return rc; - rc = operand_read(&gpa, &decode.op[0], regs, decode.op[0].len); + rc = operand_read(&gpa, &decode.op[0], regs, sizeof(gpa)); if ( rc != X86EMUL_OKAY ) return rc; @@ -1801,7 +1803,7 @@ int nvmx_handle_vmptrst(struct cpu_user_regs *regs) gpa = nvcpu->nv_vvmcxaddr; rc = hvm_copy_to_guest_linear(decode.op[0].mem, &gpa, - decode.op[0].len, 0, &pfinfo); + decode.op[0].bytes, 0, &pfinfo); if ( rc == HVMTRANS_bad_linear_to_gfn ) hvm_inject_page_fault(pfinfo.ec, pfinfo.linear); if ( rc != HVMTRANS_okay ) @@ -1817,7 +1819,7 @@ int nvmx_handle_vmclear(struct cpu_user_regs *regs) struct vmx_inst_decoded decode; struct nestedvcpu *nvcpu = &vcpu_nestedhvm(v); struct nestedvmx *nvmx = &vcpu_2_nvmx(v); - unsigned long gpa = 0; + uint64_t gpa; void *vvmcs; int rc; @@ -1825,7 +1827,7 @@ int nvmx_handle_vmclear(struct cpu_user_regs *regs) if ( rc != X86EMUL_OKAY ) return rc; - rc = operand_read(&gpa, &decode.op[0], regs, decode.op[0].len); + rc = operand_read(&gpa, &decode.op[0], regs, sizeof(gpa)); if ( rc != X86EMUL_OKAY ) return rc; @@ -1886,7 +1888,7 @@ int nvmx_handle_vmread(struct cpu_user_regs *regs) return X86EMUL_OKAY; } - rc = operand_read(&vmcs_encoding, &decode.op[1], regs, decode.op[1].len); + rc = operand_read(&vmcs_encoding, &decode.op[1], regs, decode.op[1].bytes); if ( rc != X86EMUL_OKAY ) return rc; @@ -1900,7 +1902,7 @@ int nvmx_handle_vmread(struct cpu_user_regs *regs) switch ( decode.op[0].type ) { case VMX_INST_MEMREG_TYPE_MEMORY: rc = hvm_copy_to_guest_linear(decode.op[0].mem, &value, - decode.op[0].len, 0, &pfinfo); + decode.op[0].bytes, 0, &pfinfo); if ( rc == HVMTRANS_bad_linear_to_gfn ) hvm_inject_page_fault(pfinfo.ec, pfinfo.linear); if ( rc != HVMTRANS_okay ) @@ -1928,7 +1930,7 @@ int nvmx_handle_vmwrite(struct cpu_user_regs *regs) if ( decode_vmx_inst(regs, &decode, 0) != X86EMUL_OKAY ) return X86EMUL_EXCEPTION; - rc = operand_read(&operand, &decode.op[0], regs, decode.op[0].len); + rc = operand_read(&operand, &decode.op[0], regs, decode.op[0].bytes); if ( rc != X86EMUL_OKAY ) return rc; @@ -1938,7 +1940,7 @@ int nvmx_handle_vmwrite(struct cpu_user_regs *regs) return X86EMUL_OKAY; } - rc = operand_read(&vmcs_encoding, &decode.op[1], regs, decode.op[1].len); + rc = operand_read(&vmcs_encoding, &decode.op[1], regs, decode.op[1].bytes); if ( rc != X86EMUL_OKAY ) return rc; @@ -1973,13 +1975,13 @@ int nvmx_handle_vmwrite(struct cpu_user_regs *regs) int nvmx_handle_invept(struct cpu_user_regs *regs) { struct vmx_inst_decoded decode; - unsigned long invept_type = 0; + uint64_t invept_type; int ret; if ( (ret = decode_vmx_inst(regs, &decode, 0)) != X86EMUL_OKAY ) return ret; - ret = operand_read(&invept_type, &decode.op[1], regs, decode.op[1].len); + ret = operand_read(&invept_type, &decode.op[1], regs, decode.op[1].bytes); if ( ret != X86EMUL_OKAY ) return ret; @@ -1987,9 +1989,9 @@ int nvmx_handle_invept(struct cpu_user_regs *regs) { case INVEPT_SINGLE_CONTEXT: { - unsigned long eptp; + uint64_t eptp; - ret = operand_read(&eptp, &decode.op[0], regs, decode.op[0].len); + ret = operand_read(&eptp, &decode.op[0], regs, sizeof(eptp)); if ( ret ) return ret; @@ -2011,13 +2013,13 @@ int nvmx_handle_invept(struct cpu_user_regs *regs) int nvmx_handle_invvpid(struct cpu_user_regs *regs) { struct vmx_inst_decoded decode; - unsigned long invvpid_type = 0; + uint64_t invvpid_type; int ret; if ( (ret = decode_vmx_inst(regs, &decode, 0)) != X86EMUL_OKAY ) return ret; - ret = operand_read(&invvpid_type, &decode.op[1], regs, decode.op[1].len); + ret = operand_read(&invvpid_type, &decode.op[1], regs, decode.op[1].bytes); if ( ret != X86EMUL_OKAY ) return ret;