aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/include/asm/kvm_host.h1
-rw-r--r--arch/x86/kvm/cpuid.c4
-rw-r--r--arch/x86/kvm/cpuid.h8
-rw-r--r--arch/x86/kvm/x86.c16
4 files changed, 27 insertions, 2 deletions
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 5a1faf3f043e..f4a555beef19 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -401,6 +401,7 @@ struct kvm_vcpu_arch {
401 struct kvm_mmu_memory_cache mmu_page_header_cache; 401 struct kvm_mmu_memory_cache mmu_page_header_cache;
402 402
403 struct fpu guest_fpu; 403 struct fpu guest_fpu;
404 bool eager_fpu;
404 u64 xcr0; 405 u64 xcr0;
405 u64 guest_supported_xcr0; 406 u64 guest_supported_xcr0;
406 u32 guest_xstate_size; 407 u32 guest_xstate_size;
diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
index 59b69f6a2844..1d08ad3582d0 100644
--- a/arch/x86/kvm/cpuid.c
+++ b/arch/x86/kvm/cpuid.c
@@ -16,6 +16,8 @@
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/vmalloc.h> 17#include <linux/vmalloc.h>
18#include <linux/uaccess.h> 18#include <linux/uaccess.h>
19#include <asm/i387.h> /* For use_eager_fpu. Ugh! */
20#include <asm/fpu-internal.h> /* For use_eager_fpu. Ugh! */
19#include <asm/user.h> 21#include <asm/user.h>
20#include <asm/xsave.h> 22#include <asm/xsave.h>
21#include "cpuid.h" 23#include "cpuid.h"
@@ -95,6 +97,8 @@ int kvm_update_cpuid(struct kvm_vcpu *vcpu)
95 if (best && (best->eax & (F(XSAVES) | F(XSAVEC)))) 97 if (best && (best->eax & (F(XSAVES) | F(XSAVEC))))
96 best->ebx = xstate_required_size(vcpu->arch.xcr0, true); 98 best->ebx = xstate_required_size(vcpu->arch.xcr0, true);
97 99
100 vcpu->arch.eager_fpu = guest_cpuid_has_mpx(vcpu);
101
98 /* 102 /*
99 * The existing code assumes virtual address is 48-bit in the canonical 103 * The existing code assumes virtual address is 48-bit in the canonical
100 * address checks; exit if it is ever changed. 104 * address checks; exit if it is ever changed.
diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h
index c3b1ad9fca81..496b3695d3d3 100644
--- a/arch/x86/kvm/cpuid.h
+++ b/arch/x86/kvm/cpuid.h
@@ -117,4 +117,12 @@ static inline bool guest_cpuid_has_rtm(struct kvm_vcpu *vcpu)
117 best = kvm_find_cpuid_entry(vcpu, 7, 0); 117 best = kvm_find_cpuid_entry(vcpu, 7, 0);
118 return best && (best->ebx & bit(X86_FEATURE_RTM)); 118 return best && (best->ebx & bit(X86_FEATURE_RTM));
119} 119}
120
121static inline bool guest_cpuid_has_mpx(struct kvm_vcpu *vcpu)
122{
123 struct kvm_cpuid_entry2 *best;
124
125 best = kvm_find_cpuid_entry(vcpu, 7, 0);
126 return best && (best->ebx & bit(X86_FEATURE_MPX));
127}
120#endif 128#endif
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 5f3818846465..ea306adbbc13 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -7060,7 +7060,9 @@ void kvm_put_guest_fpu(struct kvm_vcpu *vcpu)
7060 fpu_save_init(&vcpu->arch.guest_fpu); 7060 fpu_save_init(&vcpu->arch.guest_fpu);
7061 __kernel_fpu_end(); 7061 __kernel_fpu_end();
7062 ++vcpu->stat.fpu_reload; 7062 ++vcpu->stat.fpu_reload;
7063 kvm_make_request(KVM_REQ_DEACTIVATE_FPU, vcpu); 7063 if (!vcpu->arch.eager_fpu)
7064 kvm_make_request(KVM_REQ_DEACTIVATE_FPU, vcpu);
7065
7064 trace_kvm_fpu(0); 7066 trace_kvm_fpu(0);
7065} 7067}
7066 7068
@@ -7076,11 +7078,21 @@ void kvm_arch_vcpu_free(struct kvm_vcpu *vcpu)
7076struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, 7078struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
7077 unsigned int id) 7079 unsigned int id)
7078{ 7080{
7081 struct kvm_vcpu *vcpu;
7082
7079 if (check_tsc_unstable() && atomic_read(&kvm->online_vcpus) != 0) 7083 if (check_tsc_unstable() && atomic_read(&kvm->online_vcpus) != 0)
7080 printk_once(KERN_WARNING 7084 printk_once(KERN_WARNING
7081 "kvm: SMP vm created on host with unstable TSC; " 7085 "kvm: SMP vm created on host with unstable TSC; "
7082 "guest TSC will not be reliable\n"); 7086 "guest TSC will not be reliable\n");
7083 return kvm_x86_ops->vcpu_create(kvm, id); 7087
7088 vcpu = kvm_x86_ops->vcpu_create(kvm, id);
7089
7090 /*
7091 * Activate fpu unconditionally in case the guest needs eager FPU. It will be
7092 * deactivated soon if it doesn't.
7093 */
7094 kvm_x86_ops->fpu_activate(vcpu);
7095 return vcpu;
7084} 7096}
7085 7097
7086int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) 7098int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)