aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kvm/vmx.c83
1 files changed, 40 insertions, 43 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 064d0be67ecc..264147129d20 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -5567,8 +5567,47 @@ static void nested_free_all_saved_vmcss(struct vcpu_vmx *vmx)
5567 free_loaded_vmcs(&vmx->vmcs01); 5567 free_loaded_vmcs(&vmx->vmcs01);
5568} 5568}
5569 5569
5570/*
5571 * The following 3 functions, nested_vmx_succeed()/failValid()/failInvalid(),
5572 * set the success or error code of an emulated VMX instruction, as specified
5573 * by Vol 2B, VMX Instruction Reference, "Conventions".
5574 */
5575static void nested_vmx_succeed(struct kvm_vcpu *vcpu)
5576{
5577 vmx_set_rflags(vcpu, vmx_get_rflags(vcpu)
5578 & ~(X86_EFLAGS_CF | X86_EFLAGS_PF | X86_EFLAGS_AF |
5579 X86_EFLAGS_ZF | X86_EFLAGS_SF | X86_EFLAGS_OF));
5580}
5581
5582static void nested_vmx_failInvalid(struct kvm_vcpu *vcpu)
5583{
5584 vmx_set_rflags(vcpu, (vmx_get_rflags(vcpu)
5585 & ~(X86_EFLAGS_PF | X86_EFLAGS_AF | X86_EFLAGS_ZF |
5586 X86_EFLAGS_SF | X86_EFLAGS_OF))
5587 | X86_EFLAGS_CF);
5588}
5589
5570static void nested_vmx_failValid(struct kvm_vcpu *vcpu, 5590static void nested_vmx_failValid(struct kvm_vcpu *vcpu,
5571 u32 vm_instruction_error); 5591 u32 vm_instruction_error)
5592{
5593 if (to_vmx(vcpu)->nested.current_vmptr == -1ull) {
5594 /*
5595 * failValid writes the error number to the current VMCS, which
5596 * can't be done there isn't a current VMCS.
5597 */
5598 nested_vmx_failInvalid(vcpu);
5599 return;
5600 }
5601 vmx_set_rflags(vcpu, (vmx_get_rflags(vcpu)
5602 & ~(X86_EFLAGS_CF | X86_EFLAGS_PF | X86_EFLAGS_AF |
5603 X86_EFLAGS_SF | X86_EFLAGS_OF))
5604 | X86_EFLAGS_ZF);
5605 get_vmcs12(vcpu)->vm_instruction_error = vm_instruction_error;
5606 /*
5607 * We don't need to force a shadow sync because
5608 * VM_INSTRUCTION_ERROR is not shadowed
5609 */
5610}
5572 5611
5573/* 5612/*
5574 * Emulate the VMXON instruction. 5613 * Emulate the VMXON instruction.
@@ -5768,48 +5807,6 @@ static int get_vmx_mem_address(struct kvm_vcpu *vcpu,
5768 return 0; 5807 return 0;
5769} 5808}
5770 5809
5771/*
5772 * The following 3 functions, nested_vmx_succeed()/failValid()/failInvalid(),
5773 * set the success or error code of an emulated VMX instruction, as specified
5774 * by Vol 2B, VMX Instruction Reference, "Conventions".
5775 */
5776static void nested_vmx_succeed(struct kvm_vcpu *vcpu)
5777{
5778 vmx_set_rflags(vcpu, vmx_get_rflags(vcpu)
5779 & ~(X86_EFLAGS_CF | X86_EFLAGS_PF | X86_EFLAGS_AF |
5780 X86_EFLAGS_ZF | X86_EFLAGS_SF | X86_EFLAGS_OF));
5781}
5782
5783static void nested_vmx_failInvalid(struct kvm_vcpu *vcpu)
5784{
5785 vmx_set_rflags(vcpu, (vmx_get_rflags(vcpu)
5786 & ~(X86_EFLAGS_PF | X86_EFLAGS_AF | X86_EFLAGS_ZF |
5787 X86_EFLAGS_SF | X86_EFLAGS_OF))
5788 | X86_EFLAGS_CF);
5789}
5790
5791static void nested_vmx_failValid(struct kvm_vcpu *vcpu,
5792 u32 vm_instruction_error)
5793{
5794 if (to_vmx(vcpu)->nested.current_vmptr == -1ull) {
5795 /*
5796 * failValid writes the error number to the current VMCS, which
5797 * can't be done there isn't a current VMCS.
5798 */
5799 nested_vmx_failInvalid(vcpu);
5800 return;
5801 }
5802 vmx_set_rflags(vcpu, (vmx_get_rflags(vcpu)
5803 & ~(X86_EFLAGS_CF | X86_EFLAGS_PF | X86_EFLAGS_AF |
5804 X86_EFLAGS_SF | X86_EFLAGS_OF))
5805 | X86_EFLAGS_ZF);
5806 get_vmcs12(vcpu)->vm_instruction_error = vm_instruction_error;
5807 /*
5808 * We don't need to force a shadow sync because
5809 * VM_INSTRUCTION_ERROR is not shadowed
5810 */
5811}
5812
5813/* Emulate the VMCLEAR instruction */ 5810/* Emulate the VMCLEAR instruction */
5814static int handle_vmclear(struct kvm_vcpu *vcpu) 5811static int handle_vmclear(struct kvm_vcpu *vcpu)
5815{ 5812{