diff options
-rw-r--r-- | arch/x86/kvm/vmx.c | 83 |
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 | */ | ||
5575 | static 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 | |||
5582 | static 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 | |||
5570 | static void nested_vmx_failValid(struct kvm_vcpu *vcpu, | 5590 | static 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 | */ | ||
5776 | static 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 | |||
5783 | static 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 | |||
5791 | static 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 */ |
5814 | static int handle_vmclear(struct kvm_vcpu *vcpu) | 5811 | static int handle_vmclear(struct kvm_vcpu *vcpu) |
5815 | { | 5812 | { |