diff options
-rw-r--r-- | arch/x86/include/asm/kvm_host.h | 1 | ||||
-rw-r--r-- | arch/x86/kvm/cpuid.c | 4 | ||||
-rw-r--r-- | arch/x86/kvm/cpuid.h | 8 | ||||
-rw-r--r-- | arch/x86/kvm/x86.c | 16 |
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 | |||
121 | static 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) | |||
7076 | struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, | 7078 | struct 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 | ||
7086 | int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) | 7098 | int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) |