diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2014-07-17 05:55:46 -0400 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2014-07-21 08:29:49 -0400 |
commit | 9a2a05b9ed618b1bb6d4cbec0c2e1f80d6636609 (patch) | |
tree | e2f82e48a6df4ce1df1770ae39de083d0d08475c /arch/x86/kvm | |
parent | 4fa7734c62cdd8c07edd54fa5a5e91482273071a (diff) |
KVM: nVMX: clean up nested_release_vmcs12 and code around it
Make nested_release_vmcs12 idempotent.
Tested-by: Wanpeng Li <wanpeng.li@linux.intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'arch/x86/kvm')
-rw-r--r-- | arch/x86/kvm/vmx.c | 42 |
1 files changed, 21 insertions, 21 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 462334eaa3c0..3300f4f2da48 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -6109,20 +6109,27 @@ static int nested_vmx_check_permission(struct kvm_vcpu *vcpu) | |||
6109 | static inline void nested_release_vmcs12(struct vcpu_vmx *vmx) | 6109 | static inline void nested_release_vmcs12(struct vcpu_vmx *vmx) |
6110 | { | 6110 | { |
6111 | u32 exec_control; | 6111 | u32 exec_control; |
6112 | if (vmx->nested.current_vmptr == -1ull) | ||
6113 | return; | ||
6114 | |||
6115 | /* current_vmptr and current_vmcs12 are always set/reset together */ | ||
6116 | if (WARN_ON(vmx->nested.current_vmcs12 == NULL)) | ||
6117 | return; | ||
6118 | |||
6112 | if (enable_shadow_vmcs) { | 6119 | if (enable_shadow_vmcs) { |
6113 | if (vmx->nested.current_vmcs12 != NULL) { | 6120 | /* copy to memory all shadowed fields in case |
6114 | /* copy to memory all shadowed fields in case | 6121 | they were modified */ |
6115 | they were modified */ | 6122 | copy_shadow_to_vmcs12(vmx); |
6116 | copy_shadow_to_vmcs12(vmx); | 6123 | vmx->nested.sync_shadow_vmcs = false; |
6117 | vmx->nested.sync_shadow_vmcs = false; | 6124 | exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL); |
6118 | exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL); | 6125 | exec_control &= ~SECONDARY_EXEC_SHADOW_VMCS; |
6119 | exec_control &= ~SECONDARY_EXEC_SHADOW_VMCS; | 6126 | vmcs_write32(SECONDARY_VM_EXEC_CONTROL, exec_control); |
6120 | vmcs_write32(SECONDARY_VM_EXEC_CONTROL, exec_control); | 6127 | vmcs_write64(VMCS_LINK_POINTER, -1ull); |
6121 | vmcs_write64(VMCS_LINK_POINTER, -1ull); | ||
6122 | } | ||
6123 | } | 6128 | } |
6124 | kunmap(vmx->nested.current_vmcs12_page); | 6129 | kunmap(vmx->nested.current_vmcs12_page); |
6125 | nested_release_page(vmx->nested.current_vmcs12_page); | 6130 | nested_release_page(vmx->nested.current_vmcs12_page); |
6131 | vmx->nested.current_vmptr = -1ull; | ||
6132 | vmx->nested.current_vmcs12 = NULL; | ||
6126 | } | 6133 | } |
6127 | 6134 | ||
6128 | /* | 6135 | /* |
@@ -6133,12 +6140,9 @@ static void free_nested(struct vcpu_vmx *vmx) | |||
6133 | { | 6140 | { |
6134 | if (!vmx->nested.vmxon) | 6141 | if (!vmx->nested.vmxon) |
6135 | return; | 6142 | return; |
6143 | |||
6136 | vmx->nested.vmxon = false; | 6144 | vmx->nested.vmxon = false; |
6137 | if (vmx->nested.current_vmptr != -1ull) { | 6145 | nested_release_vmcs12(vmx); |
6138 | nested_release_vmcs12(vmx); | ||
6139 | vmx->nested.current_vmptr = -1ull; | ||
6140 | vmx->nested.current_vmcs12 = NULL; | ||
6141 | } | ||
6142 | if (enable_shadow_vmcs) | 6146 | if (enable_shadow_vmcs) |
6143 | free_vmcs(vmx->nested.current_shadow_vmcs); | 6147 | free_vmcs(vmx->nested.current_shadow_vmcs); |
6144 | /* Unpin physical memory we referred to in current vmcs02 */ | 6148 | /* Unpin physical memory we referred to in current vmcs02 */ |
@@ -6175,11 +6179,8 @@ static int handle_vmclear(struct kvm_vcpu *vcpu) | |||
6175 | if (nested_vmx_check_vmptr(vcpu, EXIT_REASON_VMCLEAR, &vmptr)) | 6179 | if (nested_vmx_check_vmptr(vcpu, EXIT_REASON_VMCLEAR, &vmptr)) |
6176 | return 1; | 6180 | return 1; |
6177 | 6181 | ||
6178 | if (vmptr == vmx->nested.current_vmptr) { | 6182 | if (vmptr == vmx->nested.current_vmptr) |
6179 | nested_release_vmcs12(vmx); | 6183 | nested_release_vmcs12(vmx); |
6180 | vmx->nested.current_vmptr = -1ull; | ||
6181 | vmx->nested.current_vmcs12 = NULL; | ||
6182 | } | ||
6183 | 6184 | ||
6184 | page = nested_get_page(vcpu, vmptr); | 6185 | page = nested_get_page(vcpu, vmptr); |
6185 | if (page == NULL) { | 6186 | if (page == NULL) { |
@@ -6521,9 +6522,8 @@ static int handle_vmptrld(struct kvm_vcpu *vcpu) | |||
6521 | skip_emulated_instruction(vcpu); | 6522 | skip_emulated_instruction(vcpu); |
6522 | return 1; | 6523 | return 1; |
6523 | } | 6524 | } |
6524 | if (vmx->nested.current_vmptr != -1ull) | ||
6525 | nested_release_vmcs12(vmx); | ||
6526 | 6525 | ||
6526 | nested_release_vmcs12(vmx); | ||
6527 | vmx->nested.current_vmptr = vmptr; | 6527 | vmx->nested.current_vmptr = vmptr; |
6528 | vmx->nested.current_vmcs12 = new_vmcs12; | 6528 | vmx->nested.current_vmcs12 = new_vmcs12; |
6529 | vmx->nested.current_vmcs12_page = page; | 6529 | vmx->nested.current_vmcs12_page = page; |