KVM: nVMX: Enable nested msr load/restore feature
PATCH v4 3/3 KVM: nVMX: Enable nested msr load/restore feature
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 <[email protected]>
Signed-off-by Eugene Korenevsky <[email protected]>
--- arch/x86/kvm/vmx.c | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-)
arch/x86/kvm/vmx.c +23 -7
@@ -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)
Signature · 1 line
2.0.4