diff options
Diffstat (limited to 'arch/x86/kvm/vmx.c')
-rw-r--r-- | arch/x86/kvm/vmx.c | 25 |
1 files changed, 9 insertions, 16 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index dbcdb55094f7..d11be3fb7c80 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -66,7 +66,7 @@ module_param(emulate_invalid_guest_state, bool, S_IRUGO); | |||
66 | #define KVM_GUEST_CR0_MASK \ | 66 | #define KVM_GUEST_CR0_MASK \ |
67 | (KVM_GUEST_CR0_MASK_UNRESTRICTED_GUEST | X86_CR0_PG | X86_CR0_PE) | 67 | (KVM_GUEST_CR0_MASK_UNRESTRICTED_GUEST | X86_CR0_PG | X86_CR0_PE) |
68 | #define KVM_VM_CR0_ALWAYS_ON_UNRESTRICTED_GUEST \ | 68 | #define KVM_VM_CR0_ALWAYS_ON_UNRESTRICTED_GUEST \ |
69 | (X86_CR0_WP | X86_CR0_NE | X86_CR0_TS | X86_CR0_MP) | 69 | (X86_CR0_WP | X86_CR0_NE | X86_CR0_MP) |
70 | #define KVM_VM_CR0_ALWAYS_ON \ | 70 | #define KVM_VM_CR0_ALWAYS_ON \ |
71 | (KVM_VM_CR0_ALWAYS_ON_UNRESTRICTED_GUEST | X86_CR0_PG | X86_CR0_PE) | 71 | (KVM_VM_CR0_ALWAYS_ON_UNRESTRICTED_GUEST | X86_CR0_PG | X86_CR0_PE) |
72 | #define KVM_CR4_GUEST_OWNED_BITS \ | 72 | #define KVM_CR4_GUEST_OWNED_BITS \ |
@@ -579,9 +579,8 @@ static void update_exception_bitmap(struct kvm_vcpu *vcpu) | |||
579 | { | 579 | { |
580 | u32 eb; | 580 | u32 eb; |
581 | 581 | ||
582 | eb = (1u << PF_VECTOR) | (1u << UD_VECTOR) | (1u << MC_VECTOR); | 582 | eb = (1u << PF_VECTOR) | (1u << UD_VECTOR) | (1u << MC_VECTOR) |
583 | if (!vcpu->fpu_active) | 583 | | (1u << NM_VECTOR); |
584 | eb |= 1u << NM_VECTOR; | ||
585 | /* | 584 | /* |
586 | * Unconditionally intercept #DB so we can maintain dr6 without | 585 | * Unconditionally intercept #DB so we can maintain dr6 without |
587 | * reading it every exit. | 586 | * reading it every exit. |
@@ -595,6 +594,8 @@ static void update_exception_bitmap(struct kvm_vcpu *vcpu) | |||
595 | eb = ~0; | 594 | eb = ~0; |
596 | if (enable_ept) | 595 | if (enable_ept) |
597 | eb &= ~(1u << PF_VECTOR); /* bypass_guest_pf = 0 */ | 596 | eb &= ~(1u << PF_VECTOR); /* bypass_guest_pf = 0 */ |
597 | if (vcpu->fpu_active) | ||
598 | eb &= ~(1u << NM_VECTOR); | ||
598 | vmcs_write32(EXCEPTION_BITMAP, eb); | 599 | vmcs_write32(EXCEPTION_BITMAP, eb); |
599 | } | 600 | } |
600 | 601 | ||
@@ -806,9 +807,6 @@ static void vmx_fpu_activate(struct kvm_vcpu *vcpu) | |||
806 | 807 | ||
807 | static void vmx_fpu_deactivate(struct kvm_vcpu *vcpu) | 808 | static void vmx_fpu_deactivate(struct kvm_vcpu *vcpu) |
808 | { | 809 | { |
809 | if (!vcpu->fpu_active) | ||
810 | return; | ||
811 | vcpu->fpu_active = 0; | ||
812 | vmcs_set_bits(GUEST_CR0, X86_CR0_TS); | 810 | vmcs_set_bits(GUEST_CR0, X86_CR0_TS); |
813 | update_exception_bitmap(vcpu); | 811 | update_exception_bitmap(vcpu); |
814 | } | 812 | } |
@@ -1737,8 +1735,6 @@ static void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) | |||
1737 | else | 1735 | else |
1738 | hw_cr0 = (cr0 & ~KVM_GUEST_CR0_MASK) | KVM_VM_CR0_ALWAYS_ON; | 1736 | hw_cr0 = (cr0 & ~KVM_GUEST_CR0_MASK) | KVM_VM_CR0_ALWAYS_ON; |
1739 | 1737 | ||
1740 | vmx_fpu_deactivate(vcpu); | ||
1741 | |||
1742 | if (vmx->rmode.vm86_active && (cr0 & X86_CR0_PE)) | 1738 | if (vmx->rmode.vm86_active && (cr0 & X86_CR0_PE)) |
1743 | enter_pmode(vcpu); | 1739 | enter_pmode(vcpu); |
1744 | 1740 | ||
@@ -1757,12 +1753,12 @@ static void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) | |||
1757 | if (enable_ept) | 1753 | if (enable_ept) |
1758 | ept_update_paging_mode_cr0(&hw_cr0, cr0, vcpu); | 1754 | ept_update_paging_mode_cr0(&hw_cr0, cr0, vcpu); |
1759 | 1755 | ||
1756 | if (!vcpu->fpu_active) | ||
1757 | hw_cr0 |= X86_CR0_TS; | ||
1758 | |||
1760 | vmcs_writel(CR0_READ_SHADOW, cr0); | 1759 | vmcs_writel(CR0_READ_SHADOW, cr0); |
1761 | vmcs_writel(GUEST_CR0, hw_cr0); | 1760 | vmcs_writel(GUEST_CR0, hw_cr0); |
1762 | vcpu->arch.cr0 = cr0; | 1761 | vcpu->arch.cr0 = cr0; |
1763 | |||
1764 | if (!(cr0 & X86_CR0_TS) || !(cr0 & X86_CR0_PE)) | ||
1765 | vmx_fpu_activate(vcpu); | ||
1766 | } | 1762 | } |
1767 | 1763 | ||
1768 | static u64 construct_eptp(unsigned long root_hpa) | 1764 | static u64 construct_eptp(unsigned long root_hpa) |
@@ -1793,8 +1789,6 @@ static void vmx_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3) | |||
1793 | 1789 | ||
1794 | vmx_flush_tlb(vcpu); | 1790 | vmx_flush_tlb(vcpu); |
1795 | vmcs_writel(GUEST_CR3, guest_cr3); | 1791 | vmcs_writel(GUEST_CR3, guest_cr3); |
1796 | if (kvm_read_cr0_bits(vcpu, X86_CR0_PE)) | ||
1797 | vmx_fpu_deactivate(vcpu); | ||
1798 | } | 1792 | } |
1799 | 1793 | ||
1800 | static void vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) | 1794 | static void vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) |
@@ -3002,11 +2996,9 @@ static int handle_cr(struct kvm_vcpu *vcpu) | |||
3002 | }; | 2996 | }; |
3003 | break; | 2997 | break; |
3004 | case 2: /* clts */ | 2998 | case 2: /* clts */ |
3005 | vmx_fpu_deactivate(vcpu); | ||
3006 | vcpu->arch.cr0 &= ~X86_CR0_TS; | 2999 | vcpu->arch.cr0 &= ~X86_CR0_TS; |
3007 | vmcs_writel(CR0_READ_SHADOW, kvm_read_cr0(vcpu)); | 3000 | vmcs_writel(CR0_READ_SHADOW, kvm_read_cr0(vcpu)); |
3008 | trace_kvm_cr_write(0, kvm_read_cr0(vcpu)); | 3001 | trace_kvm_cr_write(0, kvm_read_cr0(vcpu)); |
3009 | vmx_fpu_activate(vcpu); | ||
3010 | skip_emulated_instruction(vcpu); | 3002 | skip_emulated_instruction(vcpu); |
3011 | return 1; | 3003 | return 1; |
3012 | case 1: /*mov from cr*/ | 3004 | case 1: /*mov from cr*/ |
@@ -4127,6 +4119,7 @@ static struct kvm_x86_ops vmx_x86_ops = { | |||
4127 | .cache_reg = vmx_cache_reg, | 4119 | .cache_reg = vmx_cache_reg, |
4128 | .get_rflags = vmx_get_rflags, | 4120 | .get_rflags = vmx_get_rflags, |
4129 | .set_rflags = vmx_set_rflags, | 4121 | .set_rflags = vmx_set_rflags, |
4122 | .fpu_deactivate = vmx_fpu_deactivate, | ||
4130 | 4123 | ||
4131 | .tlb_flush = vmx_flush_tlb, | 4124 | .tlb_flush = vmx_flush_tlb, |
4132 | 4125 | ||