diff options
author | Avi Kivity <avi@redhat.com> | 2010-01-21 08:31:47 -0500 |
---|---|---|
committer | Marcelo Tosatti <mtosatti@redhat.com> | 2010-03-01 10:36:04 -0500 |
commit | 6b52d18605f580bdffaffd48c8da228c3e848deb (patch) | |
tree | b2bf6e704dc5c0b44714d38c955460d70f76b913 /arch | |
parent | e5bb40251a920cdd9d12c569c6aab0bdd0279e4e (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')
-rw-r--r-- | arch/x86/include/asm/kvm_host.h | 1 | ||||
-rw-r--r-- | arch/x86/kvm/svm.c | 8 | ||||
-rw-r--r-- | arch/x86/kvm/vmx.c | 1 | ||||
-rw-r--r-- | arch/x86/kvm/x86.c | 1 |
4 files changed, 10 insertions, 1 deletions
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index d73ed48587e4..7ebf9fe670cd 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h | |||
@@ -511,6 +511,7 @@ struct kvm_x86_ops { | |||
511 | void (*cache_reg)(struct kvm_vcpu *vcpu, enum kvm_reg reg); | 511 | void (*cache_reg)(struct kvm_vcpu *vcpu, enum kvm_reg reg); |
512 | unsigned long (*get_rflags)(struct kvm_vcpu *vcpu); | 512 | unsigned long (*get_rflags)(struct kvm_vcpu *vcpu); |
513 | void (*set_rflags)(struct kvm_vcpu *vcpu, unsigned long rflags); | 513 | void (*set_rflags)(struct kvm_vcpu *vcpu, unsigned long rflags); |
514 | void (*fpu_activate)(struct kvm_vcpu *vcpu); | ||
514 | void (*fpu_deactivate)(struct kvm_vcpu *vcpu); | 515 | void (*fpu_deactivate)(struct kvm_vcpu *vcpu); |
515 | 516 | ||
516 | void (*tlb_flush)(struct kvm_vcpu *vcpu); | 517 | void (*tlb_flush)(struct kvm_vcpu *vcpu); |
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 | ||
1262 | static int nm_interception(struct vcpu_svm *svm) | 1262 | static 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 | ||
1270 | static 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) | |||
3269 | int emulate_clts(struct kvm_vcpu *vcpu) | 3269 | int 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 | ||