From mboxrd@z Thu Jan 1 00:00:00 1970 From: Eugene Korenevsky Subject: [PATCH v4 3/3] KVM: nVMX: Enable nested msr load/restore feature Date: Sun, 14 Dec 2014 03:36:57 +0300 Message-ID: <20141214003657.GA16842@gnote> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii To: Paolo Bonzini , Bandan Das , kvm@vger.kernel.org Return-path: Received: from mail-la0-f46.google.com ([209.85.215.46]:55186 "EHLO mail-la0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752229AbaLNAfY (ORCPT ); Sat, 13 Dec 2014 19:35:24 -0500 Received: by mail-la0-f46.google.com with SMTP id q1so7842439lam.19 for ; Sat, 13 Dec 2014 16:35:23 -0800 (PST) Content-Disposition: inline Sender: kvm-owner@vger.kernel.org List-ID: 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 Signed-off-by: Eugene Korenevsky --- 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