KVM: x86: Intel MPX vmx and msr handle
[deliverable/linux.git] / arch / x86 / kvm / vmx.c
index da7837e1349da8ac4ac06468fb2f05e798e136f1..e4e4b50f57e6453b0755df779f981a6cf2815349 100644 (file)
@@ -418,6 +418,8 @@ struct vcpu_vmx {
        u64                   msr_host_kernel_gs_base;
        u64                   msr_guest_kernel_gs_base;
 #endif
+       u32 vm_entry_controls_shadow;
+       u32 vm_exit_controls_shadow;
        /*
         * loaded_vmcs points to the VMCS currently used in this vcpu. For a
         * non-nested (L1) guest, it always points to vmcs01. For a nested
@@ -439,6 +441,7 @@ struct vcpu_vmx {
 #endif
                int           gs_ldt_reload_needed;
                int           fs_reload_needed;
+               u64           msr_host_bndcfgs;
        } host_state;
        struct {
                int vm86_active;
@@ -1056,7 +1059,9 @@ static inline bool is_exception(u32 intr_info)
                == (INTR_TYPE_HARD_EXCEPTION | INTR_INFO_VALID_MASK);
 }
 
-static void nested_vmx_vmexit(struct kvm_vcpu *vcpu);
+static void nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 exit_reason,
+                             u32 exit_intr_info,
+                             unsigned long exit_qualification);
 static void nested_vmx_entry_failure(struct kvm_vcpu *vcpu,
                        struct vmcs12 *vmcs12,
                        u32 reason, unsigned long qualification);
@@ -1326,6 +1331,62 @@ static void vmcs_set_bits(unsigned long field, u32 mask)
        vmcs_writel(field, vmcs_readl(field) | mask);
 }
 
+static inline void vm_entry_controls_init(struct vcpu_vmx *vmx, u32 val)
+{
+       vmcs_write32(VM_ENTRY_CONTROLS, val);
+       vmx->vm_entry_controls_shadow = val;
+}
+
+static inline void vm_entry_controls_set(struct vcpu_vmx *vmx, u32 val)
+{
+       if (vmx->vm_entry_controls_shadow != val)
+               vm_entry_controls_init(vmx, val);
+}
+
+static inline u32 vm_entry_controls_get(struct vcpu_vmx *vmx)
+{
+       return vmx->vm_entry_controls_shadow;
+}
+
+
+static inline void vm_entry_controls_setbit(struct vcpu_vmx *vmx, u32 val)
+{
+       vm_entry_controls_set(vmx, vm_entry_controls_get(vmx) | val);
+}
+
+static inline void vm_entry_controls_clearbit(struct vcpu_vmx *vmx, u32 val)
+{
+       vm_entry_controls_set(vmx, vm_entry_controls_get(vmx) & ~val);
+}
+
+static inline void vm_exit_controls_init(struct vcpu_vmx *vmx, u32 val)
+{
+       vmcs_write32(VM_EXIT_CONTROLS, val);
+       vmx->vm_exit_controls_shadow = val;
+}
+
+static inline void vm_exit_controls_set(struct vcpu_vmx *vmx, u32 val)
+{
+       if (vmx->vm_exit_controls_shadow != val)
+               vm_exit_controls_init(vmx, val);
+}
+
+static inline u32 vm_exit_controls_get(struct vcpu_vmx *vmx)
+{
+       return vmx->vm_exit_controls_shadow;
+}
+
+
+static inline void vm_exit_controls_setbit(struct vcpu_vmx *vmx, u32 val)
+{
+       vm_exit_controls_set(vmx, vm_exit_controls_get(vmx) | val);
+}
+
+static inline void vm_exit_controls_clearbit(struct vcpu_vmx *vmx, u32 val)
+{
+       vm_exit_controls_set(vmx, vm_exit_controls_get(vmx) & ~val);
+}
+
 static void vmx_segment_cache_clear(struct vcpu_vmx *vmx)
 {
        vmx->segment_cache.bitmask = 0;
@@ -1410,11 +1471,11 @@ static void update_exception_bitmap(struct kvm_vcpu *vcpu)
        vmcs_write32(EXCEPTION_BITMAP, eb);
 }
 
-static void clear_atomic_switch_msr_special(unsigned long entry,
-               unsigned long exit)
+static void clear_atomic_switch_msr_special(struct vcpu_vmx *vmx,
+               unsigned long entry, unsigned long exit)
 {
-       vmcs_clear_bits(VM_ENTRY_CONTROLS, entry);
-       vmcs_clear_bits(VM_EXIT_CONTROLS, exit);
+       vm_entry_controls_clearbit(vmx, entry);
+       vm_exit_controls_clearbit(vmx, exit);
 }
 
 static void clear_atomic_switch_msr(struct vcpu_vmx *vmx, unsigned msr)
@@ -1425,14 +1486,15 @@ static void clear_atomic_switch_msr(struct vcpu_vmx *vmx, unsigned msr)
        switch (msr) {
        case MSR_EFER:
                if (cpu_has_load_ia32_efer) {
-                       clear_atomic_switch_msr_special(VM_ENTRY_LOAD_IA32_EFER,
+                       clear_atomic_switch_msr_special(vmx,
+                                       VM_ENTRY_LOAD_IA32_EFER,
                                        VM_EXIT_LOAD_IA32_EFER);
                        return;
                }
                break;
        case MSR_CORE_PERF_GLOBAL_CTRL:
                if (cpu_has_load_perf_global_ctrl) {
-                       clear_atomic_switch_msr_special(
+                       clear_atomic_switch_msr_special(vmx,
                                        VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL,
                                        VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL);
                        return;
@@ -1453,14 +1515,15 @@ static void clear_atomic_switch_msr(struct vcpu_vmx *vmx, unsigned msr)
        vmcs_write32(VM_EXIT_MSR_LOAD_COUNT, m->nr);
 }
 
-static void add_atomic_switch_msr_special(unsigned long entry,
-               unsigned long exit, unsigned long guest_val_vmcs,
-               unsigned long host_val_vmcs, u64 guest_val, u64 host_val)
+static void add_atomic_switch_msr_special(struct vcpu_vmx *vmx,
+               unsigned long entry, unsigned long exit,
+               unsigned long guest_val_vmcs, unsigned long host_val_vmcs,
+               u64 guest_val, u64 host_val)
 {
        vmcs_write64(guest_val_vmcs, guest_val);
        vmcs_write64(host_val_vmcs, host_val);
-       vmcs_set_bits(VM_ENTRY_CONTROLS, entry);
-       vmcs_set_bits(VM_EXIT_CONTROLS, exit);
+       vm_entry_controls_setbit(vmx, entry);
+       vm_exit_controls_setbit(vmx, exit);
 }
 
 static void add_atomic_switch_msr(struct vcpu_vmx *vmx, unsigned msr,
@@ -1472,7 +1535,8 @@ static void add_atomic_switch_msr(struct vcpu_vmx *vmx, unsigned msr,
        switch (msr) {
        case MSR_EFER:
                if (cpu_has_load_ia32_efer) {
-                       add_atomic_switch_msr_special(VM_ENTRY_LOAD_IA32_EFER,
+                       add_atomic_switch_msr_special(vmx,
+                                       VM_ENTRY_LOAD_IA32_EFER,
                                        VM_EXIT_LOAD_IA32_EFER,
                                        GUEST_IA32_EFER,
                                        HOST_IA32_EFER,
@@ -1482,7 +1546,7 @@ static void add_atomic_switch_msr(struct vcpu_vmx *vmx, unsigned msr,
                break;
        case MSR_CORE_PERF_GLOBAL_CTRL:
                if (cpu_has_load_perf_global_ctrl) {
-                       add_atomic_switch_msr_special(
+                       add_atomic_switch_msr_special(vmx,
                                        VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL,
                                        VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL,
                                        GUEST_IA32_PERF_GLOBAL_CTRL,
@@ -1647,6 +1711,8 @@ static void vmx_save_host_state(struct kvm_vcpu *vcpu)
        if (is_long_mode(&vmx->vcpu))
                wrmsrl(MSR_KERNEL_GS_BASE, vmx->msr_guest_kernel_gs_base);
 #endif
+       if (boot_cpu_has(X86_FEATURE_MPX))
+               rdmsrl(MSR_IA32_BNDCFGS, vmx->host_state.msr_host_bndcfgs);
        for (i = 0; i < vmx->save_nmsrs; ++i)
                kvm_set_shared_msr(vmx->guest_msrs[i].index,
                                   vmx->guest_msrs[i].data,
@@ -1684,6 +1750,8 @@ static void __vmx_load_host_state(struct vcpu_vmx *vmx)
 #ifdef CONFIG_X86_64
        wrmsrl(MSR_KERNEL_GS_BASE, vmx->msr_host_kernel_gs_base);
 #endif
+       if (vmx->host_state.msr_host_bndcfgs)
+               wrmsrl(MSR_IA32_BNDCFGS, vmx->host_state.msr_host_bndcfgs);
        /*
         * If the FPU is not active (through the host task or
         * the guest vcpu), then restore the cr0.TS bit.
@@ -1906,7 +1974,9 @@ static int nested_vmx_check_exception(struct kvm_vcpu *vcpu, unsigned nr)
        if (!(vmcs12->exception_bitmap & (1u << nr)))
                return 0;
 
-       nested_vmx_vmexit(vcpu);
+       nested_vmx_vmexit(vcpu, to_vmx(vcpu)->exit_reason,
+                         vmcs_read32(VM_EXIT_INTR_INFO),
+                         vmcs_readl(EXIT_QUALIFICATION));
        return 1;
 }
 
@@ -2279,6 +2349,7 @@ static __init void nested_vmx_setup_ctls_msrs(void)
        rdmsr(MSR_IA32_VMX_MISC, nested_vmx_misc_low, nested_vmx_misc_high);
        nested_vmx_misc_low &= VMX_MISC_PREEMPTION_TIMER_RATE_MASK |
                VMX_MISC_SAVE_EFER_LMA;
+       nested_vmx_misc_low |= VMX_MISC_ACTIVITY_HLT;
        nested_vmx_misc_high = 0;
 }
 
@@ -2295,32 +2366,10 @@ static inline u64 vmx_control_msr(u32 low, u32 high)
        return low | ((u64)high << 32);
 }
 
-/*
- * If we allow our guest to use VMX instructions (i.e., nested VMX), we should
- * also let it use VMX-specific MSRs.
- * vmx_get_vmx_msr() and vmx_set_vmx_msr() return 1 when we handled a
- * VMX-specific MSR, or 0 when we haven't (and the caller should handle it
- * like all other MSRs).
- */
+/* Returns 0 on success, non-0 otherwise. */
 static int vmx_get_vmx_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata)
 {
-       if (!nested_vmx_allowed(vcpu) && msr_index >= MSR_IA32_VMX_BASIC &&
-                    msr_index <= MSR_IA32_VMX_TRUE_ENTRY_CTLS) {
-               /*
-                * According to the spec, processors which do not support VMX
-                * should throw a #GP(0) when VMX capability MSRs are read.
-                */
-               kvm_queue_exception_e(vcpu, GP_VECTOR, 0);
-               return 1;
-       }
-
        switch (msr_index) {
-       case MSR_IA32_FEATURE_CONTROL:
-               if (nested_vmx_allowed(vcpu)) {
-                       *pdata = to_vmx(vcpu)->nested.msr_ia32_feature_control;
-                       break;
-               }
-               return 0;
        case MSR_IA32_VMX_BASIC:
                /*
                 * This MSR reports some information about VMX support. We
@@ -2387,34 +2436,9 @@ static int vmx_get_vmx_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata)
                *pdata = nested_vmx_ept_caps;
                break;
        default:
-               return 0;
-       }
-
-       return 1;
-}
-
-static int vmx_set_vmx_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
-{
-       u32 msr_index = msr_info->index;
-       u64 data = msr_info->data;
-       bool host_initialized = msr_info->host_initiated;
-
-       if (!nested_vmx_allowed(vcpu))
-               return 0;
-
-       if (msr_index == MSR_IA32_FEATURE_CONTROL) {
-               if (!host_initialized &&
-                               to_vmx(vcpu)->nested.msr_ia32_feature_control
-                               & FEATURE_CONTROL_LOCKED)
-                       return 0;
-               to_vmx(vcpu)->nested.msr_ia32_feature_control = data;
                return 1;
        }
 
-       /*
-        * No need to treat VMX capability MSRs specially: If we don't handle
-        * them, handle_wrmsr will #GP(0), which is correct (they are readonly)
-        */
        return 0;
 }
 
@@ -2460,13 +2484,20 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata)
        case MSR_IA32_SYSENTER_ESP:
                data = vmcs_readl(GUEST_SYSENTER_ESP);
                break;
+       case MSR_IA32_FEATURE_CONTROL:
+               if (!nested_vmx_allowed(vcpu))
+                       return 1;
+               data = to_vmx(vcpu)->nested.msr_ia32_feature_control;
+               break;
+       case MSR_IA32_VMX_BASIC ... MSR_IA32_VMX_VMFUNC:
+               if (!nested_vmx_allowed(vcpu))
+                       return 1;
+               return vmx_get_vmx_msr(vcpu, msr_index, pdata);
        case MSR_TSC_AUX:
                if (!to_vmx(vcpu)->rdtscp_enabled)
                        return 1;
                /* Otherwise falls through */
        default:
-               if (vmx_get_vmx_msr(vcpu, msr_index, pdata))
-                       return 0;
                msr = find_msr_entry(to_vmx(vcpu), msr_index);
                if (msr) {
                        data = msr->data;
@@ -2479,6 +2510,8 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata)
        return 0;
 }
 
+static void vmx_leave_nested(struct kvm_vcpu *vcpu);
+
 /*
  * Writes msr value into into the appropriate "register".
  * Returns 0 on success, non-0 otherwise.
@@ -2533,6 +2566,17 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
        case MSR_IA32_TSC_ADJUST:
                ret = kvm_set_msr_common(vcpu, msr_info);
                break;
+       case MSR_IA32_FEATURE_CONTROL:
+               if (!nested_vmx_allowed(vcpu) ||
+                   (to_vmx(vcpu)->nested.msr_ia32_feature_control &
+                    FEATURE_CONTROL_LOCKED && !msr_info->host_initiated))
+                       return 1;
+               vmx->nested.msr_ia32_feature_control = data;
+               if (msr_info->host_initiated && data == 0)
+                       vmx_leave_nested(vcpu);
+               break;
+       case MSR_IA32_VMX_BASIC ... MSR_IA32_VMX_VMFUNC:
+               return 1; /* they are read-only */
        case MSR_TSC_AUX:
                if (!vmx->rdtscp_enabled)
                        return 1;
@@ -2541,8 +2585,6 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
                        return 1;
                /* Otherwise falls through */
        default:
-               if (vmx_set_vmx_msr(vcpu, msr_info))
-                       break;
                msr = find_msr_entry(vmx, msr_index);
                if (msr) {
                        msr->data = data;
@@ -2800,7 +2842,7 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf)
        min |= VM_EXIT_HOST_ADDR_SPACE_SIZE;
 #endif
        opt = VM_EXIT_SAVE_IA32_PAT | VM_EXIT_LOAD_IA32_PAT |
-               VM_EXIT_ACK_INTR_ON_EXIT;
+               VM_EXIT_ACK_INTR_ON_EXIT | VM_EXIT_CLEAR_BNDCFGS;
        if (adjust_vmx_controls(min, opt, MSR_IA32_VMX_EXIT_CTLS,
                                &_vmexit_control) < 0)
                return -EIO;
@@ -2817,7 +2859,7 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf)
                _pin_based_exec_control &= ~PIN_BASED_POSTED_INTR;
 
        min = 0;
-       opt = VM_ENTRY_LOAD_IA32_PAT;
+       opt = VM_ENTRY_LOAD_IA32_PAT | VM_ENTRY_LOAD_BNDCFGS;
        if (adjust_vmx_controls(min, opt, MSR_IA32_VMX_ENTRY_CTLS,
                                &_vmentry_control) < 0)
                return -EIO;
@@ -3182,14 +3224,10 @@ static void vmx_set_efer(struct kvm_vcpu *vcpu, u64 efer)
        vmx_load_host_state(to_vmx(vcpu));
        vcpu->arch.efer = efer;
        if (efer & EFER_LMA) {
-               vmcs_write32(VM_ENTRY_CONTROLS,
-                            vmcs_read32(VM_ENTRY_CONTROLS) |
-                            VM_ENTRY_IA32E_MODE);
+               vm_entry_controls_setbit(to_vmx(vcpu), VM_ENTRY_IA32E_MODE);
                msr->data = efer;
        } else {
-               vmcs_write32(VM_ENTRY_CONTROLS,
-                            vmcs_read32(VM_ENTRY_CONTROLS) &
-                            ~VM_ENTRY_IA32E_MODE);
+               vm_entry_controls_clearbit(to_vmx(vcpu), VM_ENTRY_IA32E_MODE);
 
                msr->data = efer & ~EFER_LME;
        }
@@ -3217,9 +3255,7 @@ static void enter_lmode(struct kvm_vcpu *vcpu)
 
 static void exit_lmode(struct kvm_vcpu *vcpu)
 {
-       vmcs_write32(VM_ENTRY_CONTROLS,
-                    vmcs_read32(VM_ENTRY_CONTROLS)
-                    & ~VM_ENTRY_IA32E_MODE);
+       vm_entry_controls_clearbit(to_vmx(vcpu), VM_ENTRY_IA32E_MODE);
        vmx_set_efer(vcpu, vcpu->arch.efer & ~EFER_LMA);
 }
 
@@ -4346,10 +4382,11 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx)
                ++vmx->nmsrs;
        }
 
-       vmcs_write32(VM_EXIT_CONTROLS, vmcs_config.vmexit_ctrl);
+
+       vm_exit_controls_init(vmx, vmcs_config.vmexit_ctrl);
 
        /* 22.2.1, 20.8.1 */
-       vmcs_write32(VM_ENTRY_CONTROLS, vmcs_config.vmentry_ctrl);
+       vm_entry_controls_init(vmx, vmcs_config.vmentry_ctrl);
 
        vmcs_writel(CR0_GUEST_HOST_MASK, ~0UL);
        set_cr4_guest_host_mask(vmx);
@@ -4360,7 +4397,7 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx)
 static void vmx_vcpu_reset(struct kvm_vcpu *vcpu)
 {
        struct vcpu_vmx *vmx = to_vmx(vcpu);
-       u64 msr;
+       struct msr_data apic_base_msr;
 
        vmx->rmode.vm86_active = 0;
 
@@ -4368,10 +4405,11 @@ static void vmx_vcpu_reset(struct kvm_vcpu *vcpu)
 
        vmx->vcpu.arch.regs[VCPU_REGS_RDX] = get_rdx_init_val();
        kvm_set_cr8(&vmx->vcpu, 0);
-       msr = 0xfee00000 | MSR_IA32_APICBASE_ENABLE;
+       apic_base_msr.data = 0xfee00000 | MSR_IA32_APICBASE_ENABLE;
        if (kvm_vcpu_is_bsp(&vmx->vcpu))
-               msr |= MSR_IA32_APICBASE_BSP;
-       kvm_set_apic_base(&vmx->vcpu, msr);
+               apic_base_msr.data |= MSR_IA32_APICBASE_BSP;
+       apic_base_msr.host_initiated = true;
+       kvm_set_apic_base(&vmx->vcpu, &apic_base_msr);
 
        vmx_segment_cache_clear(vmx);
 
@@ -4588,15 +4626,12 @@ static void vmx_set_nmi_mask(struct kvm_vcpu *vcpu, bool masked)
 static int vmx_nmi_allowed(struct kvm_vcpu *vcpu)
 {
        if (is_guest_mode(vcpu)) {
-               struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
-
                if (to_vmx(vcpu)->nested.nested_run_pending)
                        return 0;
                if (nested_exit_on_nmi(vcpu)) {
-                       nested_vmx_vmexit(vcpu);
-                       vmcs12->vm_exit_reason = EXIT_REASON_EXCEPTION_NMI;
-                       vmcs12->vm_exit_intr_info = NMI_VECTOR |
-                               INTR_TYPE_NMI_INTR | INTR_INFO_VALID_MASK;
+                       nested_vmx_vmexit(vcpu, EXIT_REASON_EXCEPTION_NMI,
+                                         NMI_VECTOR | INTR_TYPE_NMI_INTR |
+                                         INTR_INFO_VALID_MASK, 0);
                        /*
                         * The NMI-triggered VM exit counts as injection:
                         * clear this one and block further NMIs.
@@ -4618,15 +4653,11 @@ static int vmx_nmi_allowed(struct kvm_vcpu *vcpu)
 static int vmx_interrupt_allowed(struct kvm_vcpu *vcpu)
 {
        if (is_guest_mode(vcpu)) {
-               struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
-
                if (to_vmx(vcpu)->nested.nested_run_pending)
                        return 0;
                if (nested_exit_on_intr(vcpu)) {
-                       nested_vmx_vmexit(vcpu);
-                       vmcs12->vm_exit_reason =
-                               EXIT_REASON_EXTERNAL_INTERRUPT;
-                       vmcs12->vm_exit_intr_info = 0;
+                       nested_vmx_vmexit(vcpu, EXIT_REASON_EXTERNAL_INTERRUPT,
+                                         0, 0);
                        /*
                         * fall through to normal code, but now in L1, not L2
                         */
@@ -4812,7 +4843,8 @@ static int handle_exception(struct kvm_vcpu *vcpu)
                dr6 = vmcs_readl(EXIT_QUALIFICATION);
                if (!(vcpu->guest_debug &
                      (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP))) {
-                       vcpu->arch.dr6 = dr6 | DR6_FIXED_1;
+                       vcpu->arch.dr6 &= ~15;
+                       vcpu->arch.dr6 |= dr6;
                        kvm_queue_exception(vcpu, DB_VECTOR);
                        return 1;
                }
@@ -5080,14 +5112,27 @@ static int handle_dr(struct kvm_vcpu *vcpu)
        reg = DEBUG_REG_ACCESS_REG(exit_qualification);
        if (exit_qualification & TYPE_MOV_FROM_DR) {
                unsigned long val;
-               if (!kvm_get_dr(vcpu, dr, &val))
-                       kvm_register_write(vcpu, reg, val);
+
+               if (kvm_get_dr(vcpu, dr, &val))
+                       return 1;
+               kvm_register_write(vcpu, reg, val);
        } else
-               kvm_set_dr(vcpu, dr, vcpu->arch.regs[reg]);
+               if (kvm_set_dr(vcpu, dr, vcpu->arch.regs[reg]))
+                       return 1;
+
        skip_emulated_instruction(vcpu);
        return 1;
 }
 
+static u64 vmx_get_dr6(struct kvm_vcpu *vcpu)
+{
+       return vcpu->arch.dr6;
+}
+
+static void vmx_set_dr6(struct kvm_vcpu *vcpu, unsigned long val)
+{
+}
+
 static void vmx_set_dr7(struct kvm_vcpu *vcpu, unsigned long val)
 {
        vmcs_writel(GUEST_DR7, val);
@@ -6460,11 +6505,8 @@ static bool nested_vmx_exit_handled_io(struct kvm_vcpu *vcpu,
        int size;
        u8 b;
 
-       if (nested_cpu_has(vmcs12, CPU_BASED_UNCOND_IO_EXITING))
-               return 1;
-
        if (!nested_cpu_has(vmcs12, CPU_BASED_USE_IO_BITMAPS))
-               return 0;
+               return nested_cpu_has(vmcs12, CPU_BASED_UNCOND_IO_EXITING);
 
        exit_qualification = vmcs_readl(EXIT_QUALIFICATION);
 
@@ -6628,6 +6670,13 @@ static bool nested_vmx_exit_handled(struct kvm_vcpu *vcpu)
        struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
        u32 exit_reason = vmx->exit_reason;
 
+       trace_kvm_nested_vmexit(kvm_rip_read(vcpu), exit_reason,
+                               vmcs_readl(EXIT_QUALIFICATION),
+                               vmx->idt_vectoring_info,
+                               intr_info,
+                               vmcs_read32(VM_EXIT_INTR_ERROR_CODE),
+                               KVM_ISA_VMX);
+
        if (vmx->nested.nested_run_pending)
                return 0;
 
@@ -6777,7 +6826,9 @@ static int vmx_handle_exit(struct kvm_vcpu *vcpu)
                return handle_invalid_guest_state(vcpu);
 
        if (is_guest_mode(vcpu) && nested_vmx_exit_handled(vcpu)) {
-               nested_vmx_vmexit(vcpu);
+               nested_vmx_vmexit(vcpu, exit_reason,
+                                 vmcs_read32(VM_EXIT_INTR_INFO),
+                                 vmcs_readl(EXIT_QUALIFICATION));
                return 1;
        }
 
@@ -7006,6 +7057,12 @@ static void vmx_handle_external_intr(struct kvm_vcpu *vcpu)
                local_irq_enable();
 }
 
+static bool vmx_mpx_supported(void)
+{
+       return (vmcs_config.vmexit_ctrl & VM_EXIT_CLEAR_BNDCFGS) &&
+               (vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_BNDCFGS);
+}
+
 static void vmx_recover_nmi_blocking(struct vcpu_vmx *vmx)
 {
        u32 exit_intr_info;
@@ -7332,8 +7389,8 @@ static void vmx_free_vcpu(struct kvm_vcpu *vcpu)
        struct vcpu_vmx *vmx = to_vmx(vcpu);
 
        free_vpid(vmx);
-       free_nested(vmx);
        free_loaded_vmcs(vmx->loaded_vmcs);
+       free_nested(vmx);
        kfree(vmx->guest_msrs);
        kvm_vcpu_uninit(vcpu);
        kmem_cache_free(kvm_vcpu_cache, vmx);
@@ -7518,15 +7575,14 @@ static void vmx_set_supported_cpuid(u32 func, struct kvm_cpuid_entry2 *entry)
 static void nested_ept_inject_page_fault(struct kvm_vcpu *vcpu,
                struct x86_exception *fault)
 {
-       struct vmcs12 *vmcs12;
-       nested_vmx_vmexit(vcpu);
-       vmcs12 = get_vmcs12(vcpu);
+       struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
+       u32 exit_reason;
 
        if (fault->error_code & PFERR_RSVD_MASK)
-               vmcs12->vm_exit_reason = EXIT_REASON_EPT_MISCONFIG;
+               exit_reason = EXIT_REASON_EPT_MISCONFIG;
        else
-               vmcs12->vm_exit_reason = EXIT_REASON_EPT_VIOLATION;
-       vmcs12->exit_qualification = vcpu->arch.exit_qualification;
+               exit_reason = EXIT_REASON_EPT_VIOLATION;
+       nested_vmx_vmexit(vcpu, exit_reason, 0, vcpu->arch.exit_qualification);
        vmcs12->guest_physical_address = fault->address;
 }
 
@@ -7564,7 +7620,9 @@ static void vmx_inject_page_fault_nested(struct kvm_vcpu *vcpu,
 
        /* TODO: also check PFEC_MATCH/MASK, not just EB.PF. */
        if (vmcs12->exception_bitmap & (1u << PF_VECTOR))
-               nested_vmx_vmexit(vcpu);
+               nested_vmx_vmexit(vcpu, to_vmx(vcpu)->exit_reason,
+                                 vmcs_read32(VM_EXIT_INTR_INFO),
+                                 vmcs_readl(EXIT_QUALIFICATION));
        else
                kvm_inject_page_fault(vcpu, fault);
 }
@@ -7706,6 +7764,11 @@ static void prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12)
                        else
                                vmcs_write64(APIC_ACCESS_ADDR,
                                  page_to_phys(vmx->nested.apic_access_page));
+               } else if (vm_need_virtualize_apic_accesses(vmx->vcpu.kvm)) {
+                       exec_control |=
+                               SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES;
+                       vmcs_write64(APIC_ACCESS_ADDR,
+                               page_to_phys(vcpu->kvm->arch.apic_access_page));
                }
 
                vmcs_write32(SECONDARY_VM_EXEC_CONTROL, exec_control);
@@ -7759,12 +7822,12 @@ static void prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12)
        exit_control = vmcs_config.vmexit_ctrl;
        if (vmcs12->pin_based_vm_exec_control & PIN_BASED_VMX_PREEMPTION_TIMER)
                exit_control |= VM_EXIT_SAVE_VMX_PREEMPTION_TIMER;
-       vmcs_write32(VM_EXIT_CONTROLS, exit_control);
+       vm_exit_controls_init(vmx, exit_control);
 
        /* vmcs12's VM_ENTRY_LOAD_IA32_EFER and VM_ENTRY_IA32E_MODE are
         * emulated by vmx_set_efer(), below.
         */
-       vmcs_write32(VM_ENTRY_CONTROLS,
+       vm_entry_controls_init(vmx, 
                (vmcs12->vm_entry_controls & ~VM_ENTRY_LOAD_IA32_EFER &
                        ~VM_ENTRY_IA32E_MODE) |
                (vmcs_config.vmentry_ctrl & ~VM_ENTRY_IA32E_MODE));
@@ -7882,7 +7945,8 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool launch)
                return 1;
        }
 
-       if (vmcs12->guest_activity_state != GUEST_ACTIVITY_ACTIVE) {
+       if (vmcs12->guest_activity_state != GUEST_ACTIVITY_ACTIVE &&
+           vmcs12->guest_activity_state != GUEST_ACTIVITY_HLT) {
                nested_vmx_failValid(vcpu, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
                return 1;
        }
@@ -7994,8 +8058,6 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool launch)
 
        enter_guest_mode(vcpu);
 
-       vmx->nested.nested_run_pending = 1;
-
        vmx->nested.vmcs01_tsc_offset = vmcs_read64(TSC_OFFSET);
 
        cpu = get_cpu();
@@ -8011,6 +8073,11 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool launch)
 
        prepare_vmcs02(vcpu, vmcs12);
 
+       if (vmcs12->guest_activity_state == GUEST_ACTIVITY_HLT)
+               return kvm_emulate_halt(vcpu);
+
+       vmx->nested.nested_run_pending = 1;
+
        /*
         * Note no nested_vmx_succeed or nested_vmx_fail here. At this point
         * we are no longer running L1, and VMLAUNCH/VMRESUME has not yet
@@ -8110,7 +8177,9 @@ static void vmcs12_save_pending_event(struct kvm_vcpu *vcpu,
  * exit-information fields only. Other fields are modified by L1 with VMWRITE,
  * which already writes to vmcs12 directly.
  */
-static void prepare_vmcs12(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12)
+static void prepare_vmcs12(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,
+                          u32 exit_reason, u32 exit_intr_info,
+                          unsigned long exit_qualification)
 {
        /* update guest state fields: */
        vmcs12->guest_cr0 = vmcs12_guest_cr0(vcpu, vmcs12);
@@ -8162,6 +8231,10 @@ static void prepare_vmcs12(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12)
                vmcs_read32(GUEST_INTERRUPTIBILITY_INFO);
        vmcs12->guest_pending_dbg_exceptions =
                vmcs_readl(GUEST_PENDING_DBG_EXCEPTIONS);
+       if (vcpu->arch.mp_state == KVM_MP_STATE_HALTED)
+               vmcs12->guest_activity_state = GUEST_ACTIVITY_HLT;
+       else
+               vmcs12->guest_activity_state = GUEST_ACTIVITY_ACTIVE;
 
        if ((vmcs12->pin_based_vm_exec_control & PIN_BASED_VMX_PREEMPTION_TIMER) &&
            (vmcs12->vm_exit_controls & VM_EXIT_SAVE_VMX_PREEMPTION_TIMER))
@@ -8186,7 +8259,7 @@ static void prepare_vmcs12(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12)
 
        vmcs12->vm_entry_controls =
                (vmcs12->vm_entry_controls & ~VM_ENTRY_IA32E_MODE) |
-               (vmcs_read32(VM_ENTRY_CONTROLS) & VM_ENTRY_IA32E_MODE);
+               (vm_entry_controls_get(to_vmx(vcpu)) & VM_ENTRY_IA32E_MODE);
 
        /* TODO: These cannot have changed unless we have MSR bitmaps and
         * the relevant bit asks not to trap the change */
@@ -8201,10 +8274,10 @@ static void prepare_vmcs12(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12)
 
        /* update exit information fields: */
 
-       vmcs12->vm_exit_reason  = to_vmx(vcpu)->exit_reason;
-       vmcs12->exit_qualification = vmcs_readl(EXIT_QUALIFICATION);
+       vmcs12->vm_exit_reason exit_reason;
+       vmcs12->exit_qualification = exit_qualification;
 
-       vmcs12->vm_exit_intr_info = vmcs_read32(VM_EXIT_INTR_INFO);
+       vmcs12->vm_exit_intr_info = exit_intr_info;
        if ((vmcs12->vm_exit_intr_info &
             (INTR_INFO_VALID_MASK | INTR_INFO_DELIVER_CODE_MASK)) ==
            (INTR_INFO_VALID_MASK | INTR_INFO_DELIVER_CODE_MASK))
@@ -8370,7 +8443,9 @@ static void load_vmcs12_host_state(struct kvm_vcpu *vcpu,
  * and modify vmcs12 to make it see what it would expect to see there if
  * L2 was its real guest. Must only be called when in L2 (is_guest_mode())
  */
-static void nested_vmx_vmexit(struct kvm_vcpu *vcpu)
+static void nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 exit_reason,
+                             u32 exit_intr_info,
+                             unsigned long exit_qualification)
 {
        struct vcpu_vmx *vmx = to_vmx(vcpu);
        int cpu;
@@ -8380,7 +8455,15 @@ static void nested_vmx_vmexit(struct kvm_vcpu *vcpu)
        WARN_ON_ONCE(vmx->nested.nested_run_pending);
 
        leave_guest_mode(vcpu);
-       prepare_vmcs12(vcpu, vmcs12);
+       prepare_vmcs12(vcpu, vmcs12, exit_reason, exit_intr_info,
+                      exit_qualification);
+
+       trace_kvm_nested_vmexit_inject(vmcs12->vm_exit_reason,
+                                      vmcs12->exit_qualification,
+                                      vmcs12->idt_vectoring_info_field,
+                                      vmcs12->vm_exit_intr_info,
+                                      vmcs12->vm_exit_intr_error_code,
+                                      KVM_ISA_VMX);
 
        cpu = get_cpu();
        vmx->loaded_vmcs = &vmx->vmcs01;
@@ -8389,6 +8472,8 @@ static void nested_vmx_vmexit(struct kvm_vcpu *vcpu)
        vcpu->cpu = cpu;
        put_cpu();
 
+       vm_entry_controls_init(vmx, vmcs_read32(VM_ENTRY_CONTROLS));
+       vm_exit_controls_init(vmx, vmcs_read32(VM_EXIT_CONTROLS));
        vmx_segment_cache_clear(vmx);
 
        /* if no vmcs02 cache requested, remove the one we used */
@@ -8423,6 +8508,16 @@ static void nested_vmx_vmexit(struct kvm_vcpu *vcpu)
                vmx->nested.sync_shadow_vmcs = true;
 }
 
+/*
+ * Forcibly leave nested mode in order to be able to reset the VCPU later on.
+ */
+static void vmx_leave_nested(struct kvm_vcpu *vcpu)
+{
+       if (is_guest_mode(vcpu))
+               nested_vmx_vmexit(vcpu, -1, 0, 0);
+       free_nested(to_vmx(vcpu));
+}
+
 /*
  * L1's failure to enter L2 is a subset of a normal exit, as explained in
  * 23.7 "VM-entry failures during or after loading guest state" (this also
@@ -8486,6 +8581,8 @@ static struct kvm_x86_ops vmx_x86_ops = {
        .set_idt = vmx_set_idt,
        .get_gdt = vmx_get_gdt,
        .set_gdt = vmx_set_gdt,
+       .get_dr6 = vmx_get_dr6,
+       .set_dr6 = vmx_set_dr6,
        .set_dr7 = vmx_set_dr7,
        .cache_reg = vmx_cache_reg,
        .get_rflags = vmx_get_rflags,
@@ -8548,6 +8645,7 @@ static struct kvm_x86_ops vmx_x86_ops = {
 
        .check_intercept = vmx_check_intercept,
        .handle_external_intr = vmx_handle_external_intr,
+       .mpx_supported = vmx_mpx_supported,
 };
 
 static int __init vmx_init(void)
@@ -8635,6 +8733,8 @@ static int __init vmx_init(void)
        vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_CS, false);
        vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_ESP, false);
        vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_EIP, false);
+       vmx_disable_intercept_for_msr(MSR_IA32_BNDCFGS, true);
+
        memcpy(vmx_msr_bitmap_legacy_x2apic,
                        vmx_msr_bitmap_legacy, PAGE_SIZE);
        memcpy(vmx_msr_bitmap_longmode_x2apic,
This page took 0.051832 seconds and 5 git commands to generate.