Skip to content

Commit

Permalink
KVM: VMX: Handle mmio emulation when guest state is invalid
Browse files Browse the repository at this point in the history
If emulate_invalid_guest_state is enabled, the emulator is called
when guest state is invalid.  Until now, we reported an mmio failure
when emulate_instruction() returned EMULATE_DO_MMIO.  This patch adds
the case where emulate_instruction() failed and an MMIO emulation
is needed.

Signed-off-by: Guillaume Thouvenin <guillaume.thouvenin@ext.bull.net>
Signed-off-by: Avi Kivity <avi@redhat.com>
  • Loading branch information
Guillaume Thouvenin authored and Avi Kivity committed Dec 31, 2008
1 parent e93f36b commit 1d5a4d9
Showing 1 changed file with 15 additions and 12 deletions.
27 changes: 15 additions & 12 deletions arch/x86/kvm/vmx.c
Original file line number Diff line number Diff line change
Expand Up @@ -3052,16 +3052,12 @@ static void handle_invalid_guest_state(struct kvm_vcpu *vcpu,
while (!guest_state_valid(vcpu)) {
err = emulate_instruction(vcpu, kvm_run, 0, 0, 0);

switch (err) {
case EMULATE_DONE:
break;
case EMULATE_DO_MMIO:
kvm_report_emulation_failure(vcpu, "mmio");
/* TODO: Handle MMIO */
return;
default:
kvm_report_emulation_failure(vcpu, "emulation failure");
return;
if (err == EMULATE_DO_MMIO)
break;

if (err != EMULATE_DONE) {
kvm_report_emulation_failure(vcpu, "emulation failure");
return;
}

if (signal_pending(current))
Expand All @@ -3073,8 +3069,10 @@ static void handle_invalid_guest_state(struct kvm_vcpu *vcpu,
local_irq_disable();
preempt_disable();

/* Guest state should be valid now, no more emulation should be needed */
vmx->emulation_required = 0;
/* Guest state should be valid now except if we need to
* emulate an MMIO */
if (guest_state_valid(vcpu))
vmx->emulation_required = 0;
}

/*
Expand Down Expand Up @@ -3121,6 +3119,11 @@ static int kvm_handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
KVMTRACE_3D(VMEXIT, vcpu, exit_reason, (u32)kvm_rip_read(vcpu),
(u32)((u64)kvm_rip_read(vcpu) >> 32), entryexit);

/* If we need to emulate an MMIO from handle_invalid_guest_state
* we just return 0 */
if (vmx->emulation_required && emulate_invalid_guest_state)
return 0;

/* Access CR3 don't cause VMExit in paging mode, so we need
* to sync with guest real CR3. */
if (vm_need_ept() && is_paging(vcpu)) {
Expand Down

0 comments on commit 1d5a4d9

Please sign in to comment.