aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/x86.c
diff options
context:
space:
mode:
authorAvi Kivity <avi@redhat.com>2010-06-10 10:02:14 -0400
committerAvi Kivity <avi@redhat.com>2010-08-01 03:46:32 -0400
commit49a9b07edcf4aff159c1f3d3a27e58cf38bc27cd (patch)
tree750ff11b09e7baa3f4c811ce7c85bf7546b051ae /arch/x86/kvm/x86.c
parent2acf923e38fb6a4ce0c57115decbb38d334902ac (diff)
KVM: Fix mov cr0 #GP at wrong instruction
On Intel, we call skip_emulated_instruction() even if we injected a #GP, resulting in the #GP pointing at the wrong address. Fix by injecting the exception and skipping the instruction at the same place, so we can do just one or the other. Signed-off-by: Avi Kivity <avi@redhat.com> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Diffstat (limited to 'arch/x86/kvm/x86.c')
-rw-r--r--arch/x86/kvm/x86.c12
1 files changed, 3 insertions, 9 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index b5e644701cc1..05e9b5dde646 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -425,7 +425,7 @@ out:
425 return changed; 425 return changed;
426} 426}
427 427
428static int __kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) 428int kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
429{ 429{
430 unsigned long old_cr0 = kvm_read_cr0(vcpu); 430 unsigned long old_cr0 = kvm_read_cr0(vcpu);
431 unsigned long update_bits = X86_CR0_PG | X86_CR0_WP | 431 unsigned long update_bits = X86_CR0_PG | X86_CR0_WP |
@@ -468,17 +468,11 @@ static int __kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
468 kvm_mmu_reset_context(vcpu); 468 kvm_mmu_reset_context(vcpu);
469 return 0; 469 return 0;
470} 470}
471
472void kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
473{
474 if (__kvm_set_cr0(vcpu, cr0))
475 kvm_inject_gp(vcpu, 0);
476}
477EXPORT_SYMBOL_GPL(kvm_set_cr0); 471EXPORT_SYMBOL_GPL(kvm_set_cr0);
478 472
479void kvm_lmsw(struct kvm_vcpu *vcpu, unsigned long msw) 473void kvm_lmsw(struct kvm_vcpu *vcpu, unsigned long msw)
480{ 474{
481 kvm_set_cr0(vcpu, kvm_read_cr0_bits(vcpu, ~0x0eul) | (msw & 0x0f)); 475 (void)kvm_set_cr0(vcpu, kvm_read_cr0_bits(vcpu, ~0x0eul) | (msw & 0x0f));
482} 476}
483EXPORT_SYMBOL_GPL(kvm_lmsw); 477EXPORT_SYMBOL_GPL(kvm_lmsw);
484 478
@@ -3732,7 +3726,7 @@ static int emulator_set_cr(int cr, unsigned long val, struct kvm_vcpu *vcpu)
3732 3726
3733 switch (cr) { 3727 switch (cr) {
3734 case 0: 3728 case 0:
3735 res = __kvm_set_cr0(vcpu, mk_cr_64(kvm_read_cr0(vcpu), val)); 3729 res = kvm_set_cr0(vcpu, mk_cr_64(kvm_read_cr0(vcpu), val));
3736 break; 3730 break;
3737 case 2: 3731 case 2:
3738 vcpu->arch.cr2 = val; 3732 vcpu->arch.cr2 = val;