aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm
diff options
context:
space:
mode:
authorAvi Kivity <avi@redhat.com>2010-01-21 08:31:47 -0500
committerMarcelo Tosatti <mtosatti@redhat.com>2010-03-01 10:36:04 -0500
commit6b52d18605f580bdffaffd48c8da228c3e848deb (patch)
treeb2bf6e704dc5c0b44714d38c955460d70f76b913 /arch/x86/kvm
parente5bb40251a920cdd9d12c569c6aab0bdd0279e4e (diff)
KVM: Activate fpu on clts
Assume that if the guest executes clts, it knows what it's doing, and load the guest fpu to prevent an #NM exception. Signed-off-by: Avi Kivity <avi@redhat.com> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Diffstat (limited to 'arch/x86/kvm')
-rw-r--r--arch/x86/kvm/svm.c8
-rw-r--r--arch/x86/kvm/vmx.c1
-rw-r--r--arch/x86/kvm/x86.c1
3 files changed, 9 insertions, 1 deletions
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index a281368c3b96..800208a60a51 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -1259,12 +1259,17 @@ static int ud_interception(struct vcpu_svm *svm)
1259 return 1; 1259 return 1;
1260} 1260}
1261 1261
1262static int nm_interception(struct vcpu_svm *svm) 1262static void svm_fpu_activate(struct kvm_vcpu *vcpu)
1263{ 1263{
1264 struct vcpu_svm *svm = to_svm(vcpu);
1264 svm->vmcb->control.intercept_exceptions &= ~(1 << NM_VECTOR); 1265 svm->vmcb->control.intercept_exceptions &= ~(1 << NM_VECTOR);
1265 svm->vcpu.fpu_active = 1; 1266 svm->vcpu.fpu_active = 1;
1266 update_cr0_intercept(svm); 1267 update_cr0_intercept(svm);
1268}
1267 1269
1270static int nm_interception(struct vcpu_svm *svm)
1271{
1272 svm_fpu_activate(&svm->vcpu);
1268 return 1; 1273 return 1;
1269} 1274}
1270 1275
@@ -2977,6 +2982,7 @@ static struct kvm_x86_ops svm_x86_ops = {
2977 .cache_reg = svm_cache_reg, 2982 .cache_reg = svm_cache_reg,
2978 .get_rflags = svm_get_rflags, 2983 .get_rflags = svm_get_rflags,
2979 .set_rflags = svm_set_rflags, 2984 .set_rflags = svm_set_rflags,
2985 .fpu_activate = svm_fpu_activate,
2980 .fpu_deactivate = svm_fpu_deactivate, 2986 .fpu_deactivate = svm_fpu_deactivate,
2981 2987
2982 .tlb_flush = svm_flush_tlb, 2988 .tlb_flush = svm_flush_tlb,
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index b7e812e9c299..fad871cbed19 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -3002,6 +3002,7 @@ static int handle_cr(struct kvm_vcpu *vcpu)
3002 vmx_set_cr0(vcpu, kvm_read_cr0_bits(vcpu, ~X86_CR0_TS)); 3002 vmx_set_cr0(vcpu, kvm_read_cr0_bits(vcpu, ~X86_CR0_TS));
3003 trace_kvm_cr_write(0, kvm_read_cr0(vcpu)); 3003 trace_kvm_cr_write(0, kvm_read_cr0(vcpu));
3004 skip_emulated_instruction(vcpu); 3004 skip_emulated_instruction(vcpu);
3005 vmx_fpu_activate(vcpu);
3005 return 1; 3006 return 1;
3006 case 1: /*mov from cr*/ 3007 case 1: /*mov from cr*/
3007 switch (cr) { 3008 switch (cr) {
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index c61ec9c69267..4db0c8a9082e 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -3269,6 +3269,7 @@ int emulate_invlpg(struct kvm_vcpu *vcpu, gva_t address)
3269int emulate_clts(struct kvm_vcpu *vcpu) 3269int emulate_clts(struct kvm_vcpu *vcpu)
3270{ 3270{
3271 kvm_x86_ops->set_cr0(vcpu, kvm_read_cr0_bits(vcpu, ~X86_CR0_TS)); 3271 kvm_x86_ops->set_cr0(vcpu, kvm_read_cr0_bits(vcpu, ~X86_CR0_TS));
3272 kvm_x86_ops->fpu_activate(vcpu);
3272 return X86EMUL_CONTINUE; 3273 return X86EMUL_CONTINUE;
3273} 3274}
3274 3275