aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm
diff options
context:
space:
mode:
authorLiang Li <liang.z.li@intel.com>2015-05-20 16:41:25 -0400
committerPaolo Bonzini <pbonzini@redhat.com>2015-05-20 06:30:26 -0400
commitc447e76b4cabb49ddae8e49c5758f031f35d55fb (patch)
treed19c11fe52ca9c9078676902fbf893517fe5c626 /arch/x86/kvm
parent0fdd74f7784b5cdff7075736992bbb149b1ae49c (diff)
kvm/fpu: Enable eager restore kvm FPU for MPX
The MPX feature requires eager KVM FPU restore support. We have verified that MPX cannot work correctly with the current lazy KVM FPU restore mechanism. Eager KVM FPU restore should be enabled if the MPX feature is exposed to VM. Signed-off-by: Yang Zhang <yang.z.zhang@intel.com> Signed-off-by: Liang Li <liang.z.li@intel.com> [Also activate the FPU on AMD processors. - Paolo] Cc: stable@vger.kernel.org Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'arch/x86/kvm')
-rw-r--r--arch/x86/kvm/cpuid.c4
-rw-r--r--arch/x86/kvm/cpuid.h8
-rw-r--r--arch/x86/kvm/x86.c16
3 files changed, 26 insertions, 2 deletions
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)