aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAvi Kivity <avi@redhat.com>2011-04-20 08:32:49 -0400
committerAvi Kivity <avi@redhat.com>2011-05-22 08:39:14 -0400
commit2d04a05bd7e93c13f13a82ac40de4065a99d069b (patch)
tree6fc122171050ca4b0a6aca5ab5aeb8d94add0108
parentfd72c4192220d0086fb24356ac6ff9c3b1e067d9 (diff)
KVM: x86 emulator: emulate CLTS internally
Avoid using ctxt->vcpu; we can do everything with ->get_cr() and ->set_cr(). A side effect is that we no longer activate the fpu on emulated CLTS; but that should be very rare. Signed-off-by: Avi Kivity <avi@redhat.com>
-rw-r--r--arch/x86/include/asm/kvm_host.h1
-rw-r--r--arch/x86/kvm/emulate.c12
-rw-r--r--arch/x86/kvm/x86.c7
3 files changed, 11 insertions, 9 deletions
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index a8616ca8320..9c3567e0f73 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -691,7 +691,6 @@ int kvm_fast_pio_out(struct kvm_vcpu *vcpu, int size, unsigned short port);
691void kvm_emulate_cpuid(struct kvm_vcpu *vcpu); 691void kvm_emulate_cpuid(struct kvm_vcpu *vcpu);
692int kvm_emulate_halt(struct kvm_vcpu *vcpu); 692int kvm_emulate_halt(struct kvm_vcpu *vcpu);
693int emulate_invlpg(struct kvm_vcpu *vcpu, gva_t address); 693int emulate_invlpg(struct kvm_vcpu *vcpu, gva_t address);
694int emulate_clts(struct kvm_vcpu *vcpu);
695int kvm_emulate_wbinvd(struct kvm_vcpu *vcpu); 694int kvm_emulate_wbinvd(struct kvm_vcpu *vcpu);
696 695
697void kvm_get_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg); 696void kvm_get_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg);
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 6a512532866..2b903a32609 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -2579,6 +2579,16 @@ static int em_invlpg(struct x86_emulate_ctxt *ctxt)
2579 return X86EMUL_CONTINUE; 2579 return X86EMUL_CONTINUE;
2580} 2580}
2581 2581
2582static int em_clts(struct x86_emulate_ctxt *ctxt)
2583{
2584 ulong cr0;
2585
2586 cr0 = ctxt->ops->get_cr(ctxt, 0);
2587 cr0 &= ~X86_CR0_TS;
2588 ctxt->ops->set_cr(ctxt, 0, cr0);
2589 return X86EMUL_CONTINUE;
2590}
2591
2582static bool valid_cr(int nr) 2592static bool valid_cr(int nr)
2583{ 2593{
2584 switch (nr) { 2594 switch (nr) {
@@ -4079,7 +4089,7 @@ twobyte_insn:
4079 rc = emulate_syscall(ctxt, ops); 4089 rc = emulate_syscall(ctxt, ops);
4080 break; 4090 break;
4081 case 0x06: 4091 case 0x06:
4082 emulate_clts(ctxt->vcpu); 4092 rc = em_clts(ctxt);
4083 break; 4093 break;
4084 case 0x09: /* wbinvd */ 4094 case 0x09: /* wbinvd */
4085 kvm_emulate_wbinvd(ctxt->vcpu); 4095 kvm_emulate_wbinvd(ctxt->vcpu);
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 7cd3a3b491d..a9e83862feb 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -4153,13 +4153,6 @@ int kvm_emulate_wbinvd(struct kvm_vcpu *vcpu)
4153} 4153}
4154EXPORT_SYMBOL_GPL(kvm_emulate_wbinvd); 4154EXPORT_SYMBOL_GPL(kvm_emulate_wbinvd);
4155 4155
4156int emulate_clts(struct kvm_vcpu *vcpu)
4157{
4158 kvm_x86_ops->set_cr0(vcpu, kvm_read_cr0_bits(vcpu, ~X86_CR0_TS));
4159 kvm_x86_ops->fpu_activate(vcpu);
4160 return X86EMUL_CONTINUE;
4161}
4162
4163int emulator_get_dr(struct x86_emulate_ctxt *ctxt, int dr, unsigned long *dest) 4156int emulator_get_dr(struct x86_emulate_ctxt *ctxt, int dr, unsigned long *dest)
4164{ 4157{
4165 return _kvm_get_dr(emul_to_vcpu(ctxt), dr, dest); 4158 return _kvm_get_dr(emul_to_vcpu(ctxt), dr, dest);