From: Orit Wasserman <or...@il.ibm.com>

---
 arch/x86/kvm/vmx.c |   27 +++++++++++++++++----------
 1 files changed, 17 insertions(+), 10 deletions(-)

diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 8745d44..de1f596 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -1244,8 +1244,6 @@ static void update_exception_bitmap(struct kvm_vcpu *vcpu)
        u32 eb;
 
        eb = (1u << PF_VECTOR) | (1u << UD_VECTOR) | (1u << MC_VECTOR);
-       if (!vcpu->fpu_active)
-               eb |= 1u << NM_VECTOR;
        /*
         * Unconditionally intercept #DB so we can maintain dr6 without
         * reading it every exit.
@@ -1463,10 +1461,6 @@ static void vmx_fpu_activate(struct kvm_vcpu *vcpu)
        if (vcpu->fpu_active)
                return;
        vcpu->fpu_active = 1;
-       vmcs_clear_bits(GUEST_CR0, X86_CR0_TS);
-       if (vcpu->arch.cr0 & X86_CR0_TS)
-               vmcs_set_bits(GUEST_CR0, X86_CR0_TS);
-       update_exception_bitmap(vcpu);
 }
 
 static void vmx_fpu_deactivate(struct kvm_vcpu *vcpu)
@@ -1474,8 +1468,6 @@ static void vmx_fpu_deactivate(struct kvm_vcpu *vcpu)
        if (!vcpu->fpu_active)
                return;
        vcpu->fpu_active = 0;
-       vmcs_set_bits(GUEST_CR0, X86_CR0_TS);
-       update_exception_bitmap(vcpu);
 }
 
 static unsigned long vmx_get_rflags(struct kvm_vcpu *vcpu)
@@ -2715,8 +2707,10 @@ static void vmx_set_cr3(struct kvm_vcpu *vcpu, unsigned 
long cr3)
 
        vmx_flush_tlb(vcpu);
        vmcs_writel(GUEST_CR3, guest_cr3);
-       if (vcpu->arch.cr0 & X86_CR0_PE)
-               vmx_fpu_deactivate(vcpu);
+       if (vcpu->arch.cr0 & X86_CR0_PE) {
+               if (guest_cr3 != vmcs_readl(GUEST_CR3))
+                       vmx_fpu_deactivate(vcpu);
+       }
 }
 
 static void vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
@@ -5208,6 +5202,19 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu)
        if (vcpu->arch.switch_db_regs)
                get_debugreg(vcpu->arch.dr6, 6);
 
+       if (vcpu->fpu_active) {
+               if (vmcs_readl(CR0_READ_SHADOW) & X86_CR0_TS)
+                       vmcs_set_bits(GUEST_CR0, X86_CR0_TS);
+               else
+                       vmcs_clear_bits(GUEST_CR0, X86_CR0_TS);
+                       vmcs_write32(EXCEPTION_BITMAP,
+                                    vmcs_read32(EXCEPTION_BITMAP) &  ~(1u << 
NM_VECTOR));
+       } else {
+               vmcs_set_bits(GUEST_CR0, X86_CR0_TS);
+               vmcs_write32(EXCEPTION_BITMAP,
+                            vmcs_read32(EXCEPTION_BITMAP) |  (1u << 
NM_VECTOR));
+       }
+
        vmx->idt_vectoring_info = vmcs_read32(IDT_VECTORING_INFO_FIELD);
        if (vmx->rmode.irq.pending)
                fixup_rmode_irq(vmx);
-- 
1.6.0.4

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to