Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1d5a4d9b authored by Guillaume Thouvenin's avatar Guillaume Thouvenin Committed by Avi Kivity
Browse files

KVM: VMX: Handle mmio emulation when guest state is invalid



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: default avatarGuillaume Thouvenin <guillaume.thouvenin@ext.bull.net>
Signed-off-by: default avatarAvi Kivity <avi@redhat.com>
parent e93f36bc
Loading
Loading
Loading
Loading
+15 −12
Original line number Diff line number Diff line
@@ -3052,14 +3052,10 @@ 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:
		if (err == EMULATE_DO_MMIO)
			break;
			case EMULATE_DO_MMIO:
				kvm_report_emulation_failure(vcpu, "mmio");
				/* TODO: Handle MMIO */
				return;
			default:

		if (err != EMULATE_DONE) {
			kvm_report_emulation_failure(vcpu, "emulation failure");
			return;
		}
@@ -3073,7 +3069,9 @@ 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 */
	/* Guest state should be valid now except if we need to
	 * emulate an MMIO */
	if (guest_state_valid(vcpu))
		vmx->emulation_required = 0;
}

@@ -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)) {