diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index d04f0a0383f3..fa2eb4fdc4b4 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -8115,8 +8115,6 @@ struct read_write_emulator_ops { void *val, int bytes); int (*read_write_mmio)(struct kvm_vcpu *vcpu, gpa_t gpa, int bytes, void *val); - int (*read_write_exit_mmio)(struct kvm_vcpu *vcpu, gpa_t gpa, - void *val, int bytes); bool write; }; @@ -8138,31 +8136,14 @@ static int write_mmio(struct kvm_vcpu *vcpu, gpa_t gpa, int bytes, void *val) return vcpu_mmio_write(vcpu, gpa, bytes, val); } -static int read_exit_mmio(struct kvm_vcpu *vcpu, gpa_t gpa, - void *val, int bytes) -{ - return X86EMUL_IO_NEEDED; -} - -static int write_exit_mmio(struct kvm_vcpu *vcpu, gpa_t gpa, - void *val, int bytes) -{ - struct kvm_mmio_fragment *frag = &vcpu->mmio_fragments[0]; - - memcpy(vcpu->run->mmio.data, frag->data, min(8u, frag->len)); - return X86EMUL_CONTINUE; -} - static const struct read_write_emulator_ops read_emultor = { .read_write_emulate = read_emulate, .read_write_mmio = vcpu_mmio_read, - .read_write_exit_mmio = read_exit_mmio, }; static const struct read_write_emulator_ops write_emultor = { .read_write_emulate = write_emulate, .read_write_mmio = write_mmio, - .read_write_exit_mmio = write_exit_mmio, .write = true, }; @@ -8295,7 +8276,19 @@ static int emulator_read_write(struct x86_emulate_ctxt *ctxt, vcpu->run->exit_reason = KVM_EXIT_MMIO; vcpu->run->mmio.phys_addr = frag->gpa; - return ops->read_write_exit_mmio(vcpu, frag->gpa, val, bytes); + /* + * For MMIO reads, stop emulating and immediately exit to userspace, as + * KVM needs the value to correctly emulate the instruction. For MMIO + * writes, continue emulating as the write to MMIO is a side effect for + * all intents and purposes. KVM will still exit to userspace, but + * after completing emulation (see the check on vcpu->mmio_needed in + * x86_emulate_instruction()). + */ + if (!ops->write) + return X86EMUL_IO_NEEDED; + + memcpy(vcpu->run->mmio.data, frag->data, min(8u, frag->len)); + return X86EMUL_CONTINUE; } static int emulator_read_emulated(struct x86_emulate_ctxt *ctxt,