|
@@ -87,11 +87,10 @@ static unsigned long mmio_read_buf(char *buf, unsigned int len)
|
|
|
|
|
|
/**
|
|
|
* kvm_handle_mmio_return -- Handle MMIO loads after user space emulation
|
|
|
+ * or in-kernel IO emulation
|
|
|
+ *
|
|
|
* @vcpu: The VCPU pointer
|
|
|
* @run: The VCPU run struct containing the mmio data
|
|
|
- *
|
|
|
- * This should only be called after returning from userspace for MMIO load
|
|
|
- * emulation.
|
|
|
*/
|
|
|
int kvm_handle_mmio_return(struct kvm_vcpu *vcpu, struct kvm_run *run)
|
|
|
{
|
|
@@ -206,18 +205,19 @@ int io_mem_abort(struct kvm_vcpu *vcpu, struct kvm_run *run,
|
|
|
run->mmio.is_write = is_write;
|
|
|
run->mmio.phys_addr = fault_ipa;
|
|
|
run->mmio.len = len;
|
|
|
- if (is_write)
|
|
|
- memcpy(run->mmio.data, data_buf, len);
|
|
|
|
|
|
if (!ret) {
|
|
|
/* We handled the access successfully in the kernel. */
|
|
|
+ if (!is_write)
|
|
|
+ memcpy(run->mmio.data, data_buf, len);
|
|
|
vcpu->stat.mmio_exit_kernel++;
|
|
|
kvm_handle_mmio_return(vcpu, run);
|
|
|
return 1;
|
|
|
- } else {
|
|
|
- vcpu->stat.mmio_exit_user++;
|
|
|
}
|
|
|
|
|
|
+ if (is_write)
|
|
|
+ memcpy(run->mmio.data, data_buf, len);
|
|
|
+ vcpu->stat.mmio_exit_user++;
|
|
|
run->exit_reason = KVM_EXIT_MMIO;
|
|
|
return 0;
|
|
|
}
|