aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/x86.c
diff options
context:
space:
mode:
authorGleb Natapov <gleb@redhat.com>2010-04-28 12:15:35 -0400
committerAvi Kivity <avi@redhat.com>2010-08-01 03:35:33 -0400
commitc3cd7ffaf57ae6ead5b394cebaeb76164059a57f (patch)
treed6867ce238cb63a0c8ec69eb7752073569687025 /arch/x86/kvm/x86.c
parent411c35b7ef02aefb91e166ffeffad0891d955fcb (diff)
KVM: x86 emulator: x86_emulate_insn() return -1 only in case of emulation failure
Currently emulator returns -1 when emulation failed or IO is needed. Caller tries to guess whether emulation failed by looking at other variables. Make it easier for caller to recognise error condition by always returning -1 in case of failure. For this new emulator internal return value X86EMUL_IO_NEEDED is introduced. It is used to distinguish between error condition (which returns X86EMUL_UNHANDLEABLE) and condition that requires IO exit to userspace to continue emulation. Signed-off-by: Gleb Natapov <gleb@redhat.com> Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86/kvm/x86.c')
-rw-r--r--arch/x86/kvm/x86.c36
1 files changed, 18 insertions, 18 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index b976c4c1fa8f..4cb65d82abca 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -3275,7 +3275,7 @@ static int kvm_read_guest_virt_helper(gva_t addr, void *val, unsigned int bytes,
3275 } 3275 }
3276 ret = kvm_read_guest(vcpu->kvm, gpa, data, toread); 3276 ret = kvm_read_guest(vcpu->kvm, gpa, data, toread);
3277 if (ret < 0) { 3277 if (ret < 0) {
3278 r = X86EMUL_UNHANDLEABLE; 3278 r = X86EMUL_IO_NEEDED;
3279 goto out; 3279 goto out;
3280 } 3280 }
3281 3281
@@ -3331,7 +3331,7 @@ static int kvm_write_guest_virt_system(gva_t addr, void *val,
3331 } 3331 }
3332 ret = kvm_write_guest(vcpu->kvm, gpa, data, towrite); 3332 ret = kvm_write_guest(vcpu->kvm, gpa, data, towrite);
3333 if (ret < 0) { 3333 if (ret < 0) {
3334 r = X86EMUL_UNHANDLEABLE; 3334 r = X86EMUL_IO_NEEDED;
3335 goto out; 3335 goto out;
3336 } 3336 }
3337 3337
@@ -3391,7 +3391,7 @@ mmio:
3391 vcpu->run->mmio.len = vcpu->mmio_size = bytes; 3391 vcpu->run->mmio.len = vcpu->mmio_size = bytes;
3392 vcpu->run->mmio.is_write = vcpu->mmio_is_write = 0; 3392 vcpu->run->mmio.is_write = vcpu->mmio_is_write = 0;
3393 3393
3394 return X86EMUL_UNHANDLEABLE; 3394 return X86EMUL_IO_NEEDED;
3395} 3395}
3396 3396
3397int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa, 3397int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa,
@@ -3863,8 +3863,6 @@ int emulate_instruction(struct kvm_vcpu *vcpu,
3863 */ 3863 */
3864 cache_all_regs(vcpu); 3864 cache_all_regs(vcpu);
3865 3865
3866 vcpu->mmio_is_write = 0;
3867
3868 if (!(emulation_type & EMULTYPE_NO_DECODE)) { 3866 if (!(emulation_type & EMULTYPE_NO_DECODE)) {
3869 int cs_db, cs_l; 3867 int cs_db, cs_l;
3870 kvm_x86_ops->get_cs_db_l_bits(vcpu, &cs_db, &cs_l); 3868 kvm_x86_ops->get_cs_db_l_bits(vcpu, &cs_db, &cs_l);
@@ -3938,24 +3936,26 @@ restart:
3938 return EMULATE_DO_MMIO; 3936 return EMULATE_DO_MMIO;
3939 } 3937 }
3940 3938
3941 if (r) { 3939 if (vcpu->mmio_needed) {
3942 if (kvm_mmu_unprotect_page_virt(vcpu, cr2)) 3940 if (vcpu->mmio_is_write)
3943 goto done; 3941 vcpu->mmio_needed = 0;
3944 if (!vcpu->mmio_needed) {
3945 ++vcpu->stat.insn_emulation_fail;
3946 trace_kvm_emulate_insn_failed(vcpu);
3947 kvm_report_emulation_failure(vcpu, "mmio");
3948 return EMULATE_FAIL;
3949 }
3950 return EMULATE_DO_MMIO; 3942 return EMULATE_DO_MMIO;
3951 } 3943 }
3952 3944
3953 if (vcpu->mmio_is_write) { 3945 if (r) { /* emulation failed */
3954 vcpu->mmio_needed = 0; 3946 /*
3955 return EMULATE_DO_MMIO; 3947 * if emulation was due to access to shadowed page table
3948 * and it failed try to unshadow page and re-entetr the
3949 * guest to let CPU execute the instruction.
3950 */
3951 if (kvm_mmu_unprotect_page_virt(vcpu, cr2))
3952 return EMULATE_DONE;
3953
3954 trace_kvm_emulate_insn_failed(vcpu);
3955 kvm_report_emulation_failure(vcpu, "mmio");
3956 return EMULATE_FAIL;
3956 } 3957 }
3957 3958
3958done:
3959 if (vcpu->arch.exception.pending) 3959 if (vcpu->arch.exception.pending)
3960 vcpu->arch.emulate_ctxt.restart = false; 3960 vcpu->arch.emulate_ctxt.restart = false;
3961 3961