Merge branch 'v2.6.34-rc2' into drm-linus
[pandora-kernel.git] / arch / x86 / kvm / vmx.c
index a680d93..14873b9 100644 (file)
@@ -66,7 +66,7 @@ module_param(emulate_invalid_guest_state, bool, S_IRUGO);
 #define KVM_GUEST_CR0_MASK                                             \
        (KVM_GUEST_CR0_MASK_UNRESTRICTED_GUEST | X86_CR0_PG | X86_CR0_PE)
 #define KVM_VM_CR0_ALWAYS_ON_UNRESTRICTED_GUEST                                \
-       (X86_CR0_WP | X86_CR0_NE | X86_CR0_MP)
+       (X86_CR0_WP | X86_CR0_NE)
 #define KVM_VM_CR0_ALWAYS_ON                                           \
        (KVM_VM_CR0_ALWAYS_ON_UNRESTRICTED_GUEST | X86_CR0_PG | X86_CR0_PE)
 #define KVM_CR4_GUEST_OWNED_BITS                                     \
@@ -358,9 +358,7 @@ static inline int cpu_has_vmx_ple(void)
 
 static inline int vm_need_virtualize_apic_accesses(struct kvm *kvm)
 {
-       return flexpriority_enabled &&
-               (cpu_has_vmx_virtualize_apic_accesses()) &&
-               (irqchip_in_kernel(kvm));
+       return flexpriority_enabled && irqchip_in_kernel(kvm);
 }
 
 static inline int cpu_has_vmx_vpid(void)
@@ -791,12 +789,15 @@ static void vmx_vcpu_put(struct kvm_vcpu *vcpu)
 
 static void vmx_fpu_activate(struct kvm_vcpu *vcpu)
 {
+       ulong cr0;
+
        if (vcpu->fpu_active)
                return;
        vcpu->fpu_active = 1;
-       vmcs_clear_bits(GUEST_CR0, X86_CR0_TS);
-       if (kvm_read_cr0_bits(vcpu, X86_CR0_TS))
-               vmcs_set_bits(GUEST_CR0, X86_CR0_TS);
+       cr0 = vmcs_readl(GUEST_CR0);
+       cr0 &= ~(X86_CR0_TS | X86_CR0_MP);
+       cr0 |= kvm_read_cr0_bits(vcpu, X86_CR0_TS | X86_CR0_MP);
+       vmcs_writel(GUEST_CR0, cr0);
        update_exception_bitmap(vcpu);
        vcpu->arch.cr0_guest_owned_bits = X86_CR0_TS;
        vmcs_writel(CR0_GUEST_HOST_MASK, ~vcpu->arch.cr0_guest_owned_bits);
@@ -807,7 +808,7 @@ static void vmx_decache_cr0_guest_bits(struct kvm_vcpu *vcpu);
 static void vmx_fpu_deactivate(struct kvm_vcpu *vcpu)
 {
        vmx_decache_cr0_guest_bits(vcpu);
-       vmcs_set_bits(GUEST_CR0, X86_CR0_TS);
+       vmcs_set_bits(GUEST_CR0, X86_CR0_TS | X86_CR0_MP);
        update_exception_bitmap(vcpu);
        vcpu->arch.cr0_guest_owned_bits = 0;
        vmcs_writel(CR0_GUEST_HOST_MASK, ~vcpu->arch.cr0_guest_owned_bits);
@@ -1601,8 +1602,6 @@ static void vmx_set_efer(struct kvm_vcpu *vcpu, u64 efer)
         */
        vmx_load_host_state(to_vmx(vcpu));
        vcpu->arch.efer = efer;
-       if (!msr)
-               return;
        if (efer & EFER_LMA) {
                vmcs_write32(VM_ENTRY_CONTROLS,
                             vmcs_read32(VM_ENTRY_CONTROLS) |
@@ -1757,7 +1756,7 @@ static void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
                ept_update_paging_mode_cr0(&hw_cr0, cr0, vcpu);
 
        if (!vcpu->fpu_active)
-               hw_cr0 |= X86_CR0_TS;
+               hw_cr0 |= X86_CR0_TS | X86_CR0_MP;
 
        vmcs_writel(CR0_READ_SHADOW, cr0);
        vmcs_writel(GUEST_CR0, hw_cr0);
@@ -2776,6 +2775,12 @@ static int handle_rmode_exception(struct kvm_vcpu *vcpu,
                kvm_queue_exception(vcpu, vec);
                return 1;
        case BP_VECTOR:
+               /*
+                * Update instruction length as we may reinject the exception
+                * from user space while in guest debugging mode.
+                */
+               to_vmx(vcpu)->vcpu.arch.event_exit_inst_len =
+                       vmcs_read32(VM_EXIT_INSTRUCTION_LEN);
                if (vcpu->guest_debug & KVM_GUESTDBG_USE_SW_BP)
                        return 0;
                /* fall through */
@@ -2898,6 +2903,13 @@ static int handle_exception(struct kvm_vcpu *vcpu)
                kvm_run->debug.arch.dr7 = vmcs_readl(GUEST_DR7);
                /* fall through */
        case BP_VECTOR:
+               /*
+                * Update instruction length as we may reinject #BP from
+                * user space while in guest debugging mode. Reading it for
+                * #DB as well causes no harm, it is not used in that case.
+                */
+               vmx->vcpu.arch.event_exit_inst_len =
+                       vmcs_read32(VM_EXIT_INSTRUCTION_LEN);
                kvm_run->exit_reason = KVM_EXIT_DEBUG;
                kvm_run->debug.arch.pc = vmcs_readl(GUEST_CS_BASE) + rip;
                kvm_run->debug.arch.exception = ex_no;
@@ -3155,6 +3167,7 @@ static int handle_rdmsr(struct kvm_vcpu *vcpu)
        u64 data;
 
        if (vmx_get_msr(vcpu, ecx, &data)) {
+               trace_kvm_msr_read_ex(ecx);
                kvm_inject_gp(vcpu, 0);
                return 1;
        }
@@ -3174,13 +3187,13 @@ static int handle_wrmsr(struct kvm_vcpu *vcpu)
        u64 data = (vcpu->arch.regs[VCPU_REGS_RAX] & -1u)
                | ((u64)(vcpu->arch.regs[VCPU_REGS_RDX] & -1u) << 32);
 
-       trace_kvm_msr_write(ecx, data);
-
        if (vmx_set_msr(vcpu, ecx, data) != 0) {
+               trace_kvm_msr_write_ex(ecx, data);
                kvm_inject_gp(vcpu, 0);
                return 1;
        }
 
+       trace_kvm_msr_write(ecx, data);
        skip_emulated_instruction(vcpu);
        return 1;
 }
@@ -4001,7 +4014,7 @@ static u64 vmx_get_mt_mask(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio)
         *   b. VT-d with snooping control feature: snooping control feature of
         *      VT-d engine can guarantee the cache correctness. Just set it
         *      to WB to keep consistent with host. So the same as item 3.
-        * 3. EPT without VT-d: always map as WB and set IGMT=1 to keep
+        * 3. EPT without VT-d: always map as WB and set IPAT=1 to keep
         *    consistent with host MTRR
         */
        if (is_mmio)
@@ -4012,7 +4025,7 @@ static u64 vmx_get_mt_mask(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio)
                      VMX_EPT_MT_EPTE_SHIFT;
        else
                ret = (MTRR_TYPE_WRBACK << VMX_EPT_MT_EPTE_SHIFT)
-                       | VMX_EPT_IGMT_BIT;
+                       | VMX_EPT_IPAT_BIT;
 
        return ret;
 }
@@ -4135,6 +4148,7 @@ static struct kvm_x86_ops vmx_x86_ops = {
        .cache_reg = vmx_cache_reg,
        .get_rflags = vmx_get_rflags,
        .set_rflags = vmx_set_rflags,
+       .fpu_activate = vmx_fpu_activate,
        .fpu_deactivate = vmx_fpu_deactivate,
 
        .tlb_flush = vmx_flush_tlb,