KVM: allow emulator to adjust rip for emulated pio instructions
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>
This commit is contained in:
committed by
Avi Kivity
parent
c0d09828c8
commit
e93f36bcfa
@ -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;
|
rep = (io_info & SVM_IOIO_REP_MASK) != 0;
|
||||||
down = (svm->vmcb->save.rflags & X86_EFLAGS_DF) != 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);
|
return kvm_emulate_pio(&svm->vcpu, kvm_run, in, size, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2687,6 +2687,7 @@ static int handle_io(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
|
|||||||
rep = (exit_qualification & 32) != 0;
|
rep = (exit_qualification & 32) != 0;
|
||||||
port = exit_qualification >> 16;
|
port = exit_qualification >> 16;
|
||||||
|
|
||||||
|
skip_emulated_instruction(vcpu);
|
||||||
return kvm_emulate_pio(vcpu, kvm_run, in, size, port);
|
return kvm_emulate_pio(vcpu, kvm_run, in, size, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
val = kvm_register_read(vcpu, VCPU_REGS_RAX);
|
||||||
memcpy(vcpu->arch.pio_data, &val, 4);
|
memcpy(vcpu->arch.pio_data, &val, 4);
|
||||||
|
|
||||||
kvm_x86_ops->skip_emulated_instruction(vcpu);
|
|
||||||
|
|
||||||
pio_dev = vcpu_find_pio_dev(vcpu, port, size, !in);
|
pio_dev = vcpu_find_pio_dev(vcpu, port, size, !in);
|
||||||
if (pio_dev) {
|
if (pio_dev) {
|
||||||
kernel_pio(pio_dev, vcpu, vcpu->arch.pio_data);
|
kernel_pio(pio_dev, vcpu, vcpu->arch.pio_data);
|
||||||
|
@ -1772,7 +1772,7 @@ special_insn:
|
|||||||
c->eip = saved_eip;
|
c->eip = saved_eip;
|
||||||
goto cannot_emulate;
|
goto cannot_emulate;
|
||||||
}
|
}
|
||||||
return 0;
|
break;
|
||||||
case 0xf4: /* hlt */
|
case 0xf4: /* hlt */
|
||||||
ctxt->vcpu->arch.halt_request = 1;
|
ctxt->vcpu->arch.halt_request = 1;
|
||||||
break;
|
break;
|
||||||
|
Reference in New Issue
Block a user