@@ -1877,6 +1877,7 @@ int nvmx_handle_vmread(struct cpu_user_regs *regs)
pagefault_info_t pfinfo;
u64 value = 0;
int rc;
+ unsigned long vmcs_encoding = 0;
rc = decode_vmx_inst(regs, &decode, NULL, 0);
if ( rc != X86EMUL_OKAY )
@@ -1888,7 +1889,11 @@ int nvmx_handle_vmread(struct cpu_user_regs *regs)
return X86EMUL_OKAY;
}
- rc = get_vvmcs_safe(v, reg_read(regs, decode.op[1].reg_idx), &value);
+ rc = operand_read(&vmcs_encoding, &decode.op[1], regs, decode.op[1].len);
+ if ( rc != X86EMUL_OKAY )
+ return rc;
+
+ rc = get_vvmcs_safe(v, vmcs_encoding, &value);
if ( rc != VMX_INSN_SUCCEED )
{
vmfail(regs, rc);
@@ -1918,9 +1923,10 @@ int nvmx_handle_vmwrite(struct cpu_user_regs *regs)
struct vcpu *v = current;
struct vmx_inst_decoded decode;
unsigned long operand;
- u64 vmcs_encoding;
+ unsigned long vmcs_encoding = 0;
bool_t okay = 1;
enum vmx_insn_errno err;
+ int rc;
if ( decode_vmx_inst(regs, &decode, &operand, 0)
!= X86EMUL_OKAY )
@@ -1932,7 +1938,10 @@ int nvmx_handle_vmwrite(struct cpu_user_regs *regs)
return X86EMUL_OKAY;
}
- vmcs_encoding = reg_read(regs, decode.op[1].reg_idx);
+ rc = operand_read(&vmcs_encoding, &decode.op[1], regs, decode.op[1].len);
+ if ( rc != X86EMUL_OKAY )
+ return rc;
+
err = set_vvmcs_safe(v, vmcs_encoding, operand);
if ( err != VMX_INSN_SUCCEED )
{
@@ -1965,12 +1974,17 @@ int nvmx_handle_invept(struct cpu_user_regs *regs)
{
struct vmx_inst_decoded decode;
unsigned long eptp;
+ unsigned long invept_type = 0;
int ret;
if ( (ret = decode_vmx_inst(regs, &decode, &eptp, 0)) != X86EMUL_OKAY )
return ret;
- switch ( reg_read(regs, decode.op[1].reg_idx) )
+ ret = operand_read(&invept_type, &decode.op[1], regs, decode.op[1].len);
+ if ( ret != X86EMUL_OKAY )
+ return ret;
+
+ switch ( invept_type )
{
case INVEPT_SINGLE_CONTEXT:
{
@@ -1992,12 +2006,17 @@ 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;
int ret;
if ( (ret = decode_vmx_inst(regs, &decode, NULL, 0)) != X86EMUL_OKAY )
return ret;
- switch ( reg_read(regs, decode.op[1].reg_idx) )
+ ret = operand_read(&invvpid_type, &decode.op[1], regs, decode.op[1].len);
+ if ( ret != X86EMUL_OKAY )
+ return ret;
+
+ switch ( invvpid_type )
{
/* Just invalidate all tlb entries for all types! */
case INVVPID_INDIVIDUAL_ADDR:
Use operand_read() to read register operands in the following functions: * nvmx_handle_vmread() * nvmx_handle_vmwrite() * nvmx_handle_invept() Direct reading of memory operands will be replaced in a separate patch. Signed-off-by: Euan Harris <euan.harris@citrix.com> --- xen/arch/x86/hvm/vmx/vvmx.c | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-)