KVM: allow emulator to adjust rip for emulated pio instructions
authorGuillaume Thouvenin <guillaume.thouvenin@ext.bull.net>
Tue, 28 Oct 2008 09:51:30 +0000 (10:51 +0100)
committerAvi Kivity <avi@redhat.com>
Wed, 31 Dec 2008 14:51:48 +0000 (16:51 +0200)
If we call the emulator we shouldn't call skip_emulated_instruction()
in the first place, since the emulator already computes the next rip
for us. Thus we move ->skip_emulated_instruction() out of
kvm_emulate_pio() and into handle_io() (and the svm equivalent). We
also replaced "return 0" by "break" in the "do_io:" case because now
the shadow register state needs to be committed. Otherwise eip will never
be updated.

Signed-off-by: Guillaume Thouvenin <guillaume.thouvenin@ext.bull.net>
Signed-off-by: Avi Kivity <avi@redhat.com>
arch/x86/kvm/svm.c
arch/x86/kvm/vmx.c
arch/x86/kvm/x86.c
arch/x86/kvm/x86_emulate.c

index 743aebd7bfcc93e1dfc3e9f86ec528540f9ef155..f0ad4d4217e44a974d915d3a1881614dc0bc6975 100644 (file)
@@ -1115,6 +1115,7 @@ static int io_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
        rep = (io_info & SVM_IOIO_REP_MASK) != 0;
        down = (svm->vmcb->save.rflags & X86_EFLAGS_DF) != 0;
 
+       skip_emulated_instruction(&svm->vcpu);
        return kvm_emulate_pio(&svm->vcpu, kvm_run, in, size, port);
 }
 
index 7623eb7b68d5bba835cff3e28a2f05845d20f6fd..816d23185fb82754c6e006887bb8147377f80950 100644 (file)
@@ -2687,6 +2687,7 @@ static int handle_io(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
        rep = (exit_qualification & 32) != 0;
        port = exit_qualification >> 16;
 
+       skip_emulated_instruction(vcpu);
        return kvm_emulate_pio(vcpu, kvm_run, in, size, port);
 }
 
index ceeac8897143f3267c99a436a0c76850b132109a..38f79b6aaf1e09bd41ea859ad11c4ad9732bc782 100644 (file)
@@ -2478,8 +2478,6 @@ int kvm_emulate_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
        val = kvm_register_read(vcpu, VCPU_REGS_RAX);
        memcpy(vcpu->arch.pio_data, &val, 4);
 
-       kvm_x86_ops->skip_emulated_instruction(vcpu);
-
        pio_dev = vcpu_find_pio_dev(vcpu, port, size, !in);
        if (pio_dev) {
                kernel_pio(pio_dev, vcpu, vcpu->arch.pio_data);
index 57d7cc45be441b3d7f35abea32822daf9e23f02c..8f60ace1387493f63e60d2d945820d2e18e62111 100644 (file)
@@ -1772,7 +1772,7 @@ special_insn:
                        c->eip = saved_eip;
                        goto cannot_emulate;
                }
-               return 0;
+               break;
        case 0xf4:              /* hlt */
                ctxt->vcpu->arch.halt_request = 1;
                break;