KVM: x86: Move vendor CR4 validity check to dedicated kvm_x86_ops hook
[linux-2.6-microblaze.git] / arch / x86 / kvm / vmx / nested.c
index 19e2265..efebd84 100644 (file)
@@ -233,6 +233,44 @@ static inline void nested_release_evmcs(struct kvm_vcpu *vcpu)
        vmx->nested.hv_evmcs = NULL;
 }
 
+static void vmx_sync_vmcs_host_state(struct vcpu_vmx *vmx,
+                                    struct loaded_vmcs *prev)
+{
+       struct vmcs_host_state *dest, *src;
+
+       if (unlikely(!vmx->guest_state_loaded))
+               return;
+
+       src = &prev->host_state;
+       dest = &vmx->loaded_vmcs->host_state;
+
+       vmx_set_host_fs_gs(dest, src->fs_sel, src->gs_sel, src->fs_base, src->gs_base);
+       dest->ldt_sel = src->ldt_sel;
+#ifdef CONFIG_X86_64
+       dest->ds_sel = src->ds_sel;
+       dest->es_sel = src->es_sel;
+#endif
+}
+
+static void vmx_switch_vmcs(struct kvm_vcpu *vcpu, struct loaded_vmcs *vmcs)
+{
+       struct vcpu_vmx *vmx = to_vmx(vcpu);
+       struct loaded_vmcs *prev;
+       int cpu;
+
+       if (WARN_ON_ONCE(vmx->loaded_vmcs == vmcs))
+               return;
+
+       cpu = get_cpu();
+       prev = vmx->loaded_vmcs;
+       vmx->loaded_vmcs = vmcs;
+       vmx_vcpu_load_vmcs(vcpu, cpu, prev);
+       vmx_sync_vmcs_host_state(vmx, prev);
+       put_cpu();
+
+       vmx_register_cache_reset(vcpu);
+}
+
 /*
  * Free whatever needs to be freed from vmx->nested when L1 goes down, or
  * just stops using VMX.
@@ -241,10 +279,13 @@ static void free_nested(struct kvm_vcpu *vcpu)
 {
        struct vcpu_vmx *vmx = to_vmx(vcpu);
 
+       if (WARN_ON_ONCE(vmx->loaded_vmcs != &vmx->vmcs01))
+               vmx_switch_vmcs(vcpu, &vmx->vmcs01);
+
        if (!vmx->nested.vmxon && !vmx->nested.smm.vmxon)
                return;
 
-       kvm_clear_request(KVM_REQ_GET_VMCS12_PAGES, vcpu);
+       kvm_clear_request(KVM_REQ_GET_NESTED_STATE_PAGES, vcpu);
 
        vmx->nested.vmxon = false;
        vmx->nested.smm.vmxon = false;
@@ -277,44 +318,6 @@ static void free_nested(struct kvm_vcpu *vcpu)
        free_loaded_vmcs(&vmx->nested.vmcs02);
 }
 
-static void vmx_sync_vmcs_host_state(struct vcpu_vmx *vmx,
-                                    struct loaded_vmcs *prev)
-{
-       struct vmcs_host_state *dest, *src;
-
-       if (unlikely(!vmx->guest_state_loaded))
-               return;
-
-       src = &prev->host_state;
-       dest = &vmx->loaded_vmcs->host_state;
-
-       vmx_set_host_fs_gs(dest, src->fs_sel, src->gs_sel, src->fs_base, src->gs_base);
-       dest->ldt_sel = src->ldt_sel;
-#ifdef CONFIG_X86_64
-       dest->ds_sel = src->ds_sel;
-       dest->es_sel = src->es_sel;
-#endif
-}
-
-static void vmx_switch_vmcs(struct kvm_vcpu *vcpu, struct loaded_vmcs *vmcs)
-{
-       struct vcpu_vmx *vmx = to_vmx(vcpu);
-       struct loaded_vmcs *prev;
-       int cpu;
-
-       if (vmx->loaded_vmcs == vmcs)
-               return;
-
-       cpu = get_cpu();
-       prev = vmx->loaded_vmcs;
-       vmx->loaded_vmcs = vmcs;
-       vmx_vcpu_load_vmcs(vcpu, cpu, prev);
-       vmx_sync_vmcs_host_state(vmx, prev);
-       put_cpu();
-
-       vmx_register_cache_reset(vcpu);
-}
-
 /*
  * Ensure that the current vmcs of the logical processor is the
  * vmcs01 of the vcpu before calling free_nested().
@@ -323,8 +326,6 @@ void nested_vmx_free_vcpu(struct kvm_vcpu *vcpu)
 {
        vcpu_load(vcpu);
        vmx_leave_nested(vcpu);
-       vmx_switch_vmcs(vcpu, &to_vmx(vcpu)->vmcs01);
-       free_nested(vcpu);
        vcpu_put(vcpu);
 }
 
@@ -938,11 +939,11 @@ static bool nested_vmx_get_vmexit_msr_value(struct kvm_vcpu *vcpu,
         * VM-exit in L0, use the more accurate value.
         */
        if (msr_index == MSR_IA32_TSC) {
-               int index = vmx_find_msr_index(&vmx->msr_autostore.guest,
-                                              MSR_IA32_TSC);
+               int i = vmx_find_loadstore_msr_slot(&vmx->msr_autostore.guest,
+                                                   MSR_IA32_TSC);
 
-               if (index >= 0) {
-                       u64 val = vmx->msr_autostore.guest.val[index].value;
+               if (i >= 0) {
+                       u64 val = vmx->msr_autostore.guest.val[i].value;
 
                        *data = kvm_read_l1_tsc(vcpu, val);
                        return true;
@@ -1031,16 +1032,16 @@ static void prepare_vmx_msr_autostore_list(struct kvm_vcpu *vcpu,
        struct vcpu_vmx *vmx = to_vmx(vcpu);
        struct vmx_msrs *autostore = &vmx->msr_autostore.guest;
        bool in_vmcs12_store_list;
-       int msr_autostore_index;
+       int msr_autostore_slot;
        bool in_autostore_list;
        int last;
 
-       msr_autostore_index = vmx_find_msr_index(autostore, msr_index);
-       in_autostore_list = msr_autostore_index >= 0;
+       msr_autostore_slot = vmx_find_loadstore_msr_slot(autostore, msr_index);
+       in_autostore_list = msr_autostore_slot >= 0;
        in_vmcs12_store_list = nested_msr_store_list_has_msr(vcpu, msr_index);
 
        if (in_vmcs12_store_list && !in_autostore_list) {
-               if (autostore->nr == NR_LOADSTORE_MSRS) {
+               if (autostore->nr == MAX_NR_LOADSTORE_MSRS) {
                        /*
                         * Emulated VMEntry does not fail here.  Instead a less
                         * accurate value will be returned by
@@ -1057,7 +1058,7 @@ static void prepare_vmx_msr_autostore_list(struct kvm_vcpu *vcpu,
                autostore->val[last].index = msr_index;
        } else if (!in_vmcs12_store_list && in_autostore_list) {
                last = --autostore->nr;
-               autostore->val[msr_autostore_index] = autostore->val[last];
+               autostore->val[msr_autostore_slot] = autostore->val[last];
        }
 }
 
@@ -2286,7 +2287,7 @@ static void prepare_vmcs02_early(struct vcpu_vmx *vmx, struct vmcs12 *vmcs12)
                /* Take the following fields only from vmcs12 */
                exec_control &= ~(SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
                                  SECONDARY_EXEC_ENABLE_INVPCID |
-                                 SECONDARY_EXEC_RDTSCP |
+                                 SECONDARY_EXEC_ENABLE_RDTSCP |
                                  SECONDARY_EXEC_XSAVES |
                                  SECONDARY_EXEC_ENABLE_USR_WAIT_PAUSE |
                                  SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY |
@@ -2314,6 +2315,9 @@ static void prepare_vmcs02_early(struct vcpu_vmx *vmx, struct vmcs12 *vmcs12)
                        vmcs_write16(GUEST_INTR_STATUS,
                                vmcs12->guest_intr_status);
 
+               if (!nested_cpu_has2(vmcs12, SECONDARY_EXEC_UNRESTRICTED_GUEST))
+                   exec_control &= ~SECONDARY_EXEC_UNRESTRICTED_GUEST;
+
                secondary_exec_controls_set(vmx, exec_control);
        }
 
@@ -2408,6 +2412,8 @@ static void prepare_vmcs02_rare(struct vcpu_vmx *vmx, struct vmcs12 *vmcs12)
                vmcs_writel(GUEST_TR_BASE, vmcs12->guest_tr_base);
                vmcs_writel(GUEST_GDTR_BASE, vmcs12->guest_gdtr_base);
                vmcs_writel(GUEST_IDTR_BASE, vmcs12->guest_idtr_base);
+
+               vmx->segment_cache.bitmask = 0;
        }
 
        if (!hv_evmcs || !(hv_evmcs->hv_clean_fields &
@@ -2571,7 +2577,7 @@ static int prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,
         * which means L1 attempted VMEntry to L2 with invalid state.
         * Fail the VMEntry.
         */
-       if (vmx->emulation_required) {
+       if (CC(!vmx_guest_state_valid(vcpu))) {
                *entry_failure_code = ENTRY_FAIL_DEFAULT;
                return -EINVAL;
        }
@@ -3344,8 +3350,10 @@ enum nvmx_vmentry_status nested_vmx_enter_non_root_mode(struct kvm_vcpu *vcpu,
        prepare_vmcs02_early(vmx, vmcs12);
 
        if (from_vmentry) {
-               if (unlikely(!nested_get_vmcs12_pages(vcpu)))
+               if (unlikely(!nested_get_vmcs12_pages(vcpu))) {
+                       vmx_switch_vmcs(vcpu, &vmx->vmcs01);
                        return NVMX_VMENTRY_KVM_INTERNAL_ERROR;
+               }
 
                if (nested_vmx_check_vmentry_hw(vcpu)) {
                        vmx_switch_vmcs(vcpu, &vmx->vmcs01);
@@ -3387,7 +3395,7 @@ enum nvmx_vmentry_status nested_vmx_enter_non_root_mode(struct kvm_vcpu *vcpu,
                 * to nested_get_vmcs12_pages before the next VM-entry.  The MSRs
                 * have already been set at vmentry time and should not be reset.
                 */
-               kvm_make_request(KVM_REQ_GET_VMCS12_PAGES, vcpu);
+               kvm_make_request(KVM_REQ_GET_NESTED_STATE_PAGES, vcpu);
        }
 
        /*
@@ -3468,11 +3476,11 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool launch)
        if (evmptrld_status == EVMPTRLD_ERROR) {
                kvm_queue_exception(vcpu, UD_VECTOR);
                return 1;
-       } else if (evmptrld_status == EVMPTRLD_VMFAIL) {
+       } else if (CC(evmptrld_status == EVMPTRLD_VMFAIL)) {
                return nested_vmx_failInvalid(vcpu);
        }
 
-       if (!vmx->nested.hv_evmcs && vmx->nested.current_vmptr == -1ull)
+       if (CC(!vmx->nested.hv_evmcs && vmx->nested.current_vmptr == -1ull))
                return nested_vmx_failInvalid(vcpu);
 
        vmcs12 = get_vmcs12(vcpu);
@@ -3483,7 +3491,7 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool launch)
         * rather than RFLAGS.ZF, and no error number is stored to the
         * VM-instruction error field.
         */
-       if (vmcs12->hdr.shadow_vmcs)
+       if (CC(vmcs12->hdr.shadow_vmcs))
                return nested_vmx_failInvalid(vcpu);
 
        if (vmx->nested.hv_evmcs) {
@@ -3504,10 +3512,10 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool launch)
         * for misconfigurations which will anyway be caught by the processor
         * when using the merged vmcs02.
         */
-       if (interrupt_shadow & KVM_X86_SHADOW_INT_MOV_SS)
+       if (CC(interrupt_shadow & KVM_X86_SHADOW_INT_MOV_SS))
                return nested_vmx_fail(vcpu, VMXERR_ENTRY_EVENTS_BLOCKED_BY_MOV_SS);
 
-       if (vmcs12->launch_state == launch)
+       if (CC(vmcs12->launch_state == launch))
                return nested_vmx_fail(vcpu,
                        launch ? VMXERR_VMLAUNCH_NONCLEAR_VMCS
                               : VMXERR_VMRESUME_NONLAUNCHED_VMCS);
@@ -3528,6 +3536,14 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool launch)
        if (unlikely(status != NVMX_VMENTRY_SUCCESS))
                goto vmentry_failed;
 
+       /* Emulate processing of posted interrupts on VM-Enter. */
+       if (nested_cpu_has_posted_intr(vmcs12) &&
+           kvm_apic_has_interrupt(vcpu) == vmx->nested.posted_intr_nv) {
+               vmx->nested.pi_pending = true;
+               kvm_make_request(KVM_REQ_EVENT, vcpu);
+               kvm_apic_clear_irr(vcpu, vmx->nested.posted_intr_nv);
+       }
+
        /* Hide L1D cache contents from the nested guest.  */
        vmx->vcpu.arch.l1tf_flush_l1d = true;
 
@@ -4257,7 +4273,7 @@ static void load_vmcs12_host_state(struct kvm_vcpu *vcpu,
 
 static inline u64 nested_vmx_get_vmcs01_guest_efer(struct vcpu_vmx *vmx)
 {
-       struct shared_msr_entry *efer_msr;
+       struct vmx_uret_msr *efer_msr;
        unsigned int i;
 
        if (vm_entry_controls_get(vmx) & VM_ENTRY_LOAD_IA32_EFER)
@@ -4271,7 +4287,7 @@ static inline u64 nested_vmx_get_vmcs01_guest_efer(struct vcpu_vmx *vmx)
                        return vmx->msr_autoload.guest.val[i].value;
        }
 
-       efer_msr = find_msr_entry(vmx, MSR_EFER);
+       efer_msr = vmx_find_uret_msr(vmx, MSR_EFER);
        if (efer_msr)
                return efer_msr->data;
 
@@ -4696,7 +4712,7 @@ static int nested_vmx_get_vmptr(struct kvm_vcpu *vcpu, gpa_t *vmpointer,
 
        r = kvm_read_guest_virt(vcpu, gva, vmpointer, sizeof(*vmpointer), &e);
        if (r != X86EMUL_CONTINUE) {
-               *ret = vmx_handle_memory_failure(vcpu, r, &e);
+               *ret = kvm_handle_memory_failure(vcpu, r, &e);
                return -EINVAL;
        }
 
@@ -4760,7 +4776,7 @@ static int enter_vmx_operation(struct kvm_vcpu *vcpu)
 
        if (vmx_pt_mode_is_host_guest()) {
                vmx->pt_desc.guest.ctl = 0;
-               pt_update_intercept_for_msr(vmx);
+               pt_update_intercept_for_msr(vcpu);
        }
 
        return 0;
@@ -4798,7 +4814,7 @@ static int handle_vmon(struct kvm_vcpu *vcpu)
        /*
         * The Intel VMX Instruction Reference lists a bunch of bits that are
         * prerequisite to running VMXON, most notably cr4.VMXE must be set to
-        * 1 (see vmx_set_cr4() for when we allow the guest to set this).
+        * 1 (see vmx_is_valid_cr4() for when we allow the guest to set this).
         * Otherwise, we should fail with #UD.  But most faulting conditions
         * have already been checked by hardware, prior to the VM-exit for
         * VMXON.  We do test guest cr4.VMXE because processor CR4 always has
@@ -5003,7 +5019,7 @@ static int handle_vmread(struct kvm_vcpu *vcpu)
                /* _system ok, nested_vmx_check_permission has verified cpl=0 */
                r = kvm_write_guest_virt_system(vcpu, gva, &value, len, &e);
                if (r != X86EMUL_CONTINUE)
-                       return vmx_handle_memory_failure(vcpu, r, &e);
+                       return kvm_handle_memory_failure(vcpu, r, &e);
        }
 
        return nested_vmx_succeed(vcpu);
@@ -5076,7 +5092,7 @@ static int handle_vmwrite(struct kvm_vcpu *vcpu)
                        return 1;
                r = kvm_read_guest_virt(vcpu, gva, &value, len, &e);
                if (r != X86EMUL_CONTINUE)
-                       return vmx_handle_memory_failure(vcpu, r, &e);
+                       return kvm_handle_memory_failure(vcpu, r, &e);
        }
 
        field = kvm_register_readl(vcpu, (((instr_info) >> 28) & 0xf));
@@ -5238,7 +5254,7 @@ static int handle_vmptrst(struct kvm_vcpu *vcpu)
        r = kvm_write_guest_virt_system(vcpu, gva, (void *)&current_vmptr,
                                        sizeof(gpa_t), &e);
        if (r != X86EMUL_CONTINUE)
-               return vmx_handle_memory_failure(vcpu, r, &e);
+               return kvm_handle_memory_failure(vcpu, r, &e);
 
        return nested_vmx_succeed(vcpu);
 }
@@ -5291,7 +5307,7 @@ static int handle_invept(struct kvm_vcpu *vcpu)
                return 1;
        r = kvm_read_guest_virt(vcpu, gva, &operand, sizeof(operand), &e);
        if (r != X86EMUL_CONTINUE)
-               return vmx_handle_memory_failure(vcpu, r, &e);
+               return kvm_handle_memory_failure(vcpu, r, &e);
 
        /*
         * Nested EPT roots are always held through guest_mmu,
@@ -5373,7 +5389,7 @@ static int handle_invvpid(struct kvm_vcpu *vcpu)
                return 1;
        r = kvm_read_guest_virt(vcpu, gva, &operand, sizeof(operand), &e);
        if (r != X86EMUL_CONTINUE)
-               return vmx_handle_memory_failure(vcpu, r, &e);
+               return kvm_handle_memory_failure(vcpu, r, &e);
 
        if (operand.vpid >> 16)
                return nested_vmx_fail(vcpu,
@@ -5918,13 +5934,7 @@ bool nested_vmx_reflect_vmexit(struct kvm_vcpu *vcpu)
                goto reflect_vmexit;
        }
 
-       exit_intr_info = vmx_get_intr_info(vcpu);
-       exit_qual = vmx_get_exit_qual(vcpu);
-
-       trace_kvm_nested_vmexit(kvm_rip_read(vcpu), exit_reason, exit_qual,
-                               vmx->idt_vectoring_info, exit_intr_info,
-                               vmcs_read32(VM_EXIT_INTR_ERROR_CODE),
-                               KVM_ISA_VMX);
+       trace_kvm_nested_vmexit(exit_reason, vcpu, KVM_ISA_VMX);
 
        /* If L0 (KVM) wants the exit, it trumps L1's desires. */
        if (nested_vmx_l0_wants_exit(vcpu, exit_reason))
@@ -5940,14 +5950,14 @@ bool nested_vmx_reflect_vmexit(struct kvm_vcpu *vcpu)
         * need to be synthesized by querying the in-kernel LAPIC, but external
         * interrupts are never reflected to L1 so it's a non-issue.
         */
-       if ((exit_intr_info &
-            (INTR_INFO_VALID_MASK | INTR_INFO_DELIVER_CODE_MASK)) ==
-           (INTR_INFO_VALID_MASK | INTR_INFO_DELIVER_CODE_MASK)) {
+       exit_intr_info = vmx_get_intr_info(vcpu);
+       if (is_exception_with_error_code(exit_intr_info)) {
                struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
 
                vmcs12->vm_exit_intr_error_code =
                        vmcs_read32(VM_EXIT_INTR_ERROR_CODE);
        }
+       exit_qual = vmx_get_exit_qual(vcpu);
 
 reflect_vmexit:
        nested_vmx_vmexit(vcpu, exit_reason, exit_intr_info, exit_qual);
@@ -6182,7 +6192,7 @@ static int vmx_set_nested_state(struct kvm_vcpu *vcpu,
                 * restored yet. EVMCS will be mapped from
                 * nested_get_vmcs12_pages().
                 */
-               kvm_make_request(KVM_REQ_GET_VMCS12_PAGES, vcpu);
+               kvm_make_request(KVM_REQ_GET_NESTED_STATE_PAGES, vcpu);
        } else {
                return -EINVAL;
        }
@@ -6318,7 +6328,8 @@ void nested_vmx_setup_ctls_msrs(struct nested_vmx_msrs *msrs, u32 ept_caps)
 #ifdef CONFIG_X86_64
                VM_EXIT_HOST_ADDR_SPACE_SIZE |
 #endif
-               VM_EXIT_LOAD_IA32_PAT | VM_EXIT_SAVE_IA32_PAT;
+               VM_EXIT_LOAD_IA32_PAT | VM_EXIT_SAVE_IA32_PAT |
+               VM_EXIT_CLEAR_BNDCFGS | VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL;
        msrs->exit_ctls_high |=
                VM_EXIT_ALWAYSON_WITHOUT_TRUE_MSR |
                VM_EXIT_LOAD_IA32_EFER | VM_EXIT_SAVE_IA32_EFER |
@@ -6337,7 +6348,8 @@ void nested_vmx_setup_ctls_msrs(struct nested_vmx_msrs *msrs, u32 ept_caps)
 #ifdef CONFIG_X86_64
                VM_ENTRY_IA32E_MODE |
 #endif
-               VM_ENTRY_LOAD_IA32_PAT;
+               VM_ENTRY_LOAD_IA32_PAT | VM_ENTRY_LOAD_BNDCFGS |
+               VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL;
        msrs->entry_ctls_high |=
                (VM_ENTRY_ALWAYSON_WITHOUT_TRUE_MSR | VM_ENTRY_LOAD_IA32_EFER);
 
@@ -6391,7 +6403,7 @@ void nested_vmx_setup_ctls_msrs(struct nested_vmx_msrs *msrs, u32 ept_caps)
        msrs->secondary_ctls_low = 0;
        msrs->secondary_ctls_high &=
                SECONDARY_EXEC_DESC |
-               SECONDARY_EXEC_RDTSCP |
+               SECONDARY_EXEC_ENABLE_RDTSCP |
                SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE |
                SECONDARY_EXEC_WBINVD_EXITING |
                SECONDARY_EXEC_APIC_REGISTER_VIRT |
@@ -6561,7 +6573,7 @@ struct kvm_x86_nested_ops vmx_nested_ops = {
        .hv_timer_pending = nested_vmx_preemption_timer_pending,
        .get_state = vmx_get_nested_state,
        .set_state = vmx_set_nested_state,
-       .get_vmcs12_pages = nested_get_vmcs12_pages,
+       .get_nested_state_pages = nested_get_vmcs12_pages,
        .write_log_dirty = nested_vmx_write_pml_buffer,
        .enable_evmcs = nested_enable_evmcs,
        .get_evmcs_version = nested_get_evmcs_version,