On nested entry:
 - check msr switch area.
 - load L2's MSRs. If failed, terminate nested entry
   and load L1's state. If failed on loading L1's MSRs
   again, do nested vmx abort.

On nested exit:
 - restore L2's MSRs. If failed, do nested vmx abort.
 - load L1's MSRs. If failed, do nested vmx abort.

Signed-off-by: Wincy Van <fanwenyi0...@gmail.com>
Signed-off-by: Eugene Korenevsky <ekorenev...@gmail.com>
---
 arch/x86/kvm/vmx.c | 30 +++++++++++++++++++++++-------
 1 file changed, 23 insertions(+), 7 deletions(-)

diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index ac1fa1c2..ddb28e2 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -8745,6 +8745,7 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool 
launch)
        int cpu;
        struct loaded_vmcs *vmcs02;
        bool ia32e;
+       u32 msr_entry_idx;
 
        if (!nested_vmx_check_permission(vcpu) ||
            !nested_vmx_check_vmcs12(vcpu))
@@ -8792,11 +8793,7 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool 
launch)
                return 1;
        }
 
-       if (vmcs12->vm_entry_msr_load_count > 0 ||
-           vmcs12->vm_exit_msr_load_count > 0 ||
-           vmcs12->vm_exit_msr_store_count > 0) {
-               pr_warn_ratelimited("%s: VMCS MSR_{LOAD,STORE} unsupported\n",
-                                   __func__);
+       if (nested_vmx_check_msr_switch_controls(vcpu, vmcs12)) {
                nested_vmx_failValid(vcpu, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
                return 1;
        }
@@ -8902,10 +8899,21 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool 
launch)
 
        vmx_segment_cache_clear(vmx);
 
-       vmcs12->launch_state = 1;
-
        prepare_vmcs02(vcpu, vmcs12);
 
+       msr_entry_idx = nested_vmx_load_msr(vcpu,
+                                           vmcs12->vm_entry_msr_load_addr,
+                                           vmcs12->vm_entry_msr_load_count);
+       if (msr_entry_idx) {
+               leave_guest_mode(vcpu);
+               vmx_load_vmcs01(vcpu);
+               nested_vmx_entry_failure(vcpu, vmcs12,
+                               EXIT_REASON_MSR_LOAD_FAIL, msr_entry_idx);
+               return 1;
+       }
+
+       vmcs12->launch_state = 1;
+
        if (vmcs12->guest_activity_state == GUEST_ACTIVITY_HLT)
                return kvm_emulate_halt(vcpu);
 
@@ -9335,6 +9343,10 @@ static void load_vmcs12_host_state(struct kvm_vcpu *vcpu,
 
        kvm_set_dr(vcpu, 7, 0x400);
        vmcs_write64(GUEST_IA32_DEBUGCTL, 0);
+
+       if (nested_vmx_load_msr(vcpu, vmcs12->vm_exit_msr_load_addr,
+                               vmcs12->vm_exit_msr_load_count))
+               nested_vmx_abort(vcpu, VMX_ABORT_LOAD_HOST_MSR_FAIL);
 }
 
 /*
@@ -9356,6 +9368,10 @@ static void nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 
exit_reason,
        prepare_vmcs12(vcpu, vmcs12, exit_reason, exit_intr_info,
                       exit_qualification);
 
+       if (nested_vmx_store_msr(vcpu, vmcs12->vm_exit_msr_store_addr,
+                                vmcs12->vm_exit_msr_store_count))
+               nested_vmx_abort(vcpu, VMX_ABORT_SAVE_GUEST_MSR_FAIL);
+
        vmx_load_vmcs01(vcpu);
 
        if ((exit_reason == EXIT_REASON_EXTERNAL_INTERRUPT)
-- 
2.0.4

--
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