VMX instructions specify success or failure by setting certain RFLAGS bits.
This patch contains common functions to do this, and they will be used in
the following patches which emulate the various VMX instructions.

Signed-off-by: Nadav Har'El <n...@il.ibm.com>
---
 arch/x86/include/asm/vmx.h |   31 +++++++++++++++++++++++++++++++
 arch/x86/kvm/vmx.c         |   30 ++++++++++++++++++++++++++++++
 2 files changed, 61 insertions(+)

--- .before/arch/x86/kvm/vmx.c  2010-12-08 18:56:49.000000000 +0200
+++ .after/arch/x86/kvm/vmx.c   2010-12-08 18:56:49.000000000 +0200
@@ -4384,6 +4384,36 @@ static int get_vmx_mem_address(struct kv
 }
 
 /*
+ * The following 3 functions, nested_vmx_succeed()/failValid()/failInvalid(),
+ * set the success or error code of an emulated VMX instruction, as specified
+ * by Vol 2B, VMX Instruction Reference, "Conventions".
+ */
+static void nested_vmx_succeed(struct kvm_vcpu *vcpu)
+{
+       vmx_set_rflags(vcpu, vmx_get_rflags(vcpu)
+                       & ~(X86_EFLAGS_CF | X86_EFLAGS_PF | X86_EFLAGS_AF |
+                           X86_EFLAGS_ZF | X86_EFLAGS_SF | X86_EFLAGS_OF));
+}
+
+static void nested_vmx_failInvalid(struct kvm_vcpu *vcpu)
+{
+       vmx_set_rflags(vcpu, (vmx_get_rflags(vcpu)
+                       & ~(X86_EFLAGS_PF | X86_EFLAGS_AF | X86_EFLAGS_ZF |
+                           X86_EFLAGS_SF | X86_EFLAGS_OF))
+                       | X86_EFLAGS_CF);
+}
+
+static void nested_vmx_failValid(struct kvm_vcpu *vcpu,
+                                       u32 vm_instruction_error)
+{
+       vmx_set_rflags(vcpu, (vmx_get_rflags(vcpu)
+                       & ~(X86_EFLAGS_CF | X86_EFLAGS_PF | X86_EFLAGS_AF |
+                           X86_EFLAGS_SF | X86_EFLAGS_OF))
+                       | X86_EFLAGS_ZF);
+       get_vmcs12_fields(vcpu)->vm_instruction_error = vm_instruction_error;
+}
+
+/*
  * The exit handlers return 1 if the exit was handled fully and guest execution
  * may resume.  Otherwise they set the kvm_run parameter to indicate what needs
  * to be done to userspace and return 0.
--- .before/arch/x86/include/asm/vmx.h  2010-12-08 18:56:49.000000000 +0200
+++ .after/arch/x86/include/asm/vmx.h   2010-12-08 18:56:49.000000000 +0200
@@ -412,4 +412,35 @@ struct vmx_msr_entry {
        u64 value;
 } __aligned(16);
 
+/*
+ * VM-instruction error numbers
+ */
+enum vm_instruction_error_number {
+       VMXERR_VMCALL_IN_VMX_ROOT_OPERATION = 1,
+       VMXERR_VMCLEAR_INVALID_ADDRESS = 2,
+       VMXERR_VMCLEAR_VMXON_POINTER = 3,
+       VMXERR_VMLAUNCH_NONCLEAR_VMCS = 4,
+       VMXERR_VMRESUME_NONLAUNCHED_VMCS = 5,
+       VMXERR_VMRESUME_CORRUPTED_VMCS = 6,
+       VMXERR_ENTRY_INVALID_CONTROL_FIELD = 7,
+       VMXERR_ENTRY_INVALID_HOST_STATE_FIELD = 8,
+       VMXERR_VMPTRLD_INVALID_ADDRESS = 9,
+       VMXERR_VMPTRLD_VMXON_POINTER = 10,
+       VMXERR_VMPTRLD_INCORRECT_VMCS_REVISION_ID = 11,
+       VMXERR_UNSUPPORTED_VMCS_COMPONENT = 12,
+       VMXERR_VMWRITE_READ_ONLY_VMCS_COMPONENT = 13,
+       VMXERR_VMXON_IN_VMX_ROOT_OPERATION = 15,
+       VMXERR_ENTRY_INVALID_EXECUTIVE_VMCS_POINTER = 16,
+       VMXERR_ENTRY_NONLAUNCHED_EXECUTIVE_VMCS = 17,
+       VMXERR_ENTRY_EXECUTIVE_VMCS_POINTER_NOT_VMXON_POINTER = 18,
+       VMXERR_VMCALL_NONCLEAR_VMCS = 19,
+       VMXERR_VMCALL_INVALID_VM_EXIT_CONTROL_FIELDS = 20,
+       VMXERR_VMCALL_INCORRECT_MSEG_REVISION_ID = 22,
+       VMXERR_VMXOFF_UNDER_DUAL_MONITOR_TREATMENT_OF_SMIS_AND_SMM = 23,
+       VMXERR_VMCALL_INVALID_SMM_MONITOR_FEATURES = 24,
+       VMXERR_ENTRY_INVALID_VM_EXECUTION_CONTROL_FIELDS_IN_EXECUTIVE_VMCS = 25,
+       VMXERR_ENTRY_EVENTS_BLOCKED_BY_MOV_SS = 26,
+       VMXERR_INVALID_OPERAND_TO_INVEPT_INVVPID = 28,
+};
+
 #endif
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to