diff options
author | Avi Kivity <avi@redhat.com> | 2011-04-20 08:32:49 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2011-05-22 08:39:14 -0400 |
commit | 2d04a05bd7e93c13f13a82ac40de4065a99d069b (patch) | |
tree | 6fc122171050ca4b0a6aca5ab5aeb8d94add0108 /arch | |
parent | fd72c4192220d0086fb24356ac6ff9c3b1e067d9 (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>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/include/asm/kvm_host.h | 1 | ||||
-rw-r--r-- | arch/x86/kvm/emulate.c | 12 | ||||
-rw-r--r-- | arch/x86/kvm/x86.c | 7 |
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 a8616ca8320e..9c3567e0f730 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); | |||
691 | void kvm_emulate_cpuid(struct kvm_vcpu *vcpu); | 691 | void kvm_emulate_cpuid(struct kvm_vcpu *vcpu); |
692 | int kvm_emulate_halt(struct kvm_vcpu *vcpu); | 692 | int kvm_emulate_halt(struct kvm_vcpu *vcpu); |
693 | int emulate_invlpg(struct kvm_vcpu *vcpu, gva_t address); | 693 | int emulate_invlpg(struct kvm_vcpu *vcpu, gva_t address); |
694 | int emulate_clts(struct kvm_vcpu *vcpu); | ||
695 | int kvm_emulate_wbinvd(struct kvm_vcpu *vcpu); | 694 | int kvm_emulate_wbinvd(struct kvm_vcpu *vcpu); |
696 | 695 | ||
697 | void kvm_get_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg); | 696 | void 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 6a5125328669..2b903a326096 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 | ||
2582 | static 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 | |||
2582 | static bool valid_cr(int nr) | 2592 | static 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 7cd3a3b491de..a9e83862feb8 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 | } |
4154 | EXPORT_SYMBOL_GPL(kvm_emulate_wbinvd); | 4154 | EXPORT_SYMBOL_GPL(kvm_emulate_wbinvd); |
4155 | 4155 | ||
4156 | int 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 | |||
4163 | int emulator_get_dr(struct x86_emulate_ctxt *ctxt, int dr, unsigned long *dest) | 4156 | int 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); |