]> xenbits.xensource.com Git - people/royger/xen.git/commitdiff
x86/vvmx: add mov-ss blocking check to vmentry
authorSergey Dyasli <sergey.dyasli@citrix.com>
Tue, 14 Mar 2017 11:24:38 +0000 (12:24 +0100)
committerJan Beulich <jbeulich@suse.com>
Tue, 14 Mar 2017 11:24:38 +0000 (12:24 +0100)
Intel SDM states that if there is a current VMCS and there is MOV-SS
blocking, VMFailValid occurs and control passes to the next instruction.

Implement such behaviour for nested vmlaunch and vmresume.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Kevin Tian <kevin.tian@intel.com>
xen/arch/x86/hvm/vmx/vvmx.c
xen/include/asm-x86/hvm/vmx/vmcs.h

index e2c09515d34a2b735b1aa277f7f24c5944534500..09e4250bd350f70d0f6fd2fbff26c53aa5b1ecb8 100644 (file)
@@ -1572,6 +1572,7 @@ int nvmx_handle_vmresume(struct cpu_user_regs *regs)
     bool_t launched;
     struct vcpu *v = current;
     struct nestedvmx *nvmx = &vcpu_2_nvmx(v);
+    unsigned long intr_shadow;
     int rc = vmx_inst_check_privilege(regs, 0);
 
     if ( rc != X86EMUL_OKAY )
@@ -1583,6 +1584,13 @@ int nvmx_handle_vmresume(struct cpu_user_regs *regs)
         return X86EMUL_OKAY;        
     }
 
+    __vmread(GUEST_INTERRUPTIBILITY_INFO, &intr_shadow);
+    if ( intr_shadow & VMX_INTR_SHADOW_MOV_SS )
+    {
+        vmfail_valid(regs, VMX_INSN_VMENTRY_BLOCKED_BY_MOV_SS);
+        return X86EMUL_OKAY;
+    }
+
     launched = vvmcs_launched(&nvmx->launched_list,
                               PFN_DOWN(v->arch.hvm_vmx.vmcs_shadow_maddr));
     if ( !launched )
@@ -1598,6 +1606,7 @@ int nvmx_handle_vmlaunch(struct cpu_user_regs *regs)
     bool_t launched;
     struct vcpu *v = current;
     struct nestedvmx *nvmx = &vcpu_2_nvmx(v);
+    unsigned long intr_shadow;
     int rc = vmx_inst_check_privilege(regs, 0);
 
     if ( rc != X86EMUL_OKAY )
@@ -1609,6 +1618,13 @@ int nvmx_handle_vmlaunch(struct cpu_user_regs *regs)
         return X86EMUL_OKAY;
     }
 
+    __vmread(GUEST_INTERRUPTIBILITY_INFO, &intr_shadow);
+    if ( intr_shadow & VMX_INTR_SHADOW_MOV_SS )
+    {
+        vmfail_valid(regs, VMX_INSN_VMENTRY_BLOCKED_BY_MOV_SS);
+        return X86EMUL_OKAY;
+    }
+
     launched = vvmcs_launched(&nvmx->launched_list,
                               PFN_DOWN(v->arch.hvm_vmx.vmcs_shadow_maddr));
     if ( launched )
index f465fff6bc251ae24107427a6e5e1d11cf698c27..dc5d91f1740465695c4f190ad7f8fa41fcc83a08 100644 (file)
@@ -515,6 +515,7 @@ enum vmx_insn_errno
     VMX_INSN_VMPTRLD_INCORRECT_VMCS_ID     = 11,
     VMX_INSN_UNSUPPORTED_VMCS_COMPONENT    = 12,
     VMX_INSN_VMXON_IN_VMX_ROOT             = 15,
+    VMX_INSN_VMENTRY_BLOCKED_BY_MOV_SS     = 26,
     VMX_INSN_FAIL_INVALID                  = ~0,
 };