mirror of https://gitee.com/openkylin/linux.git
KVM: nVMX: Success/failure of VMX instructions.
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 <nyh@il.ibm.com> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
This commit is contained in:
parent
22bd035868
commit
0140caea3b
|
@ -426,4 +426,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_AFTER_VMXOFF = 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
|
||||
|
|
|
@ -4776,6 +4776,44 @@ static int get_vmx_mem_address(struct kvm_vcpu *vcpu,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
if (to_vmx(vcpu)->nested.current_vmptr == -1ull) {
|
||||
/*
|
||||
* failValid writes the error number to the current VMCS, which
|
||||
* can't be done there isn't a current VMCS.
|
||||
*/
|
||||
nested_vmx_failInvalid(vcpu);
|
||||
return;
|
||||
}
|
||||
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(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
|
||||
|
|
Loading…
Reference in New Issue