diff options
| -rw-r--r-- | drivers/kvm/kvm.h | 1 | ||||
| -rw-r--r-- | drivers/kvm/kvm_main.c | 16 |
2 files changed, 14 insertions, 3 deletions
diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h index f99e89e185b2..41634fde8e13 100644 --- a/drivers/kvm/kvm.h +++ b/drivers/kvm/kvm.h | |||
| @@ -310,6 +310,7 @@ struct kvm_vcpu { | |||
| 310 | int mmio_size; | 310 | int mmio_size; |
| 311 | unsigned char mmio_data[8]; | 311 | unsigned char mmio_data[8]; |
| 312 | gpa_t mmio_phys_addr; | 312 | gpa_t mmio_phys_addr; |
| 313 | gva_t mmio_fault_cr2; | ||
| 313 | struct kvm_pio_request pio; | 314 | struct kvm_pio_request pio; |
| 314 | void *pio_data; | 315 | void *pio_data; |
| 315 | 316 | ||
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c index cdf0b176851d..f267dbb52845 100644 --- a/drivers/kvm/kvm_main.c +++ b/drivers/kvm/kvm_main.c | |||
| @@ -1186,6 +1186,7 @@ int emulate_instruction(struct kvm_vcpu *vcpu, | |||
| 1186 | int r; | 1186 | int r; |
| 1187 | int cs_db, cs_l; | 1187 | int cs_db, cs_l; |
| 1188 | 1188 | ||
| 1189 | vcpu->mmio_fault_cr2 = cr2; | ||
| 1189 | kvm_arch_ops->cache_regs(vcpu); | 1190 | kvm_arch_ops->cache_regs(vcpu); |
| 1190 | 1191 | ||
| 1191 | kvm_arch_ops->get_cs_db_l_bits(vcpu, &cs_db, &cs_l); | 1192 | kvm_arch_ops->get_cs_db_l_bits(vcpu, &cs_db, &cs_l); |
| @@ -1804,14 +1805,23 @@ static int kvm_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
| 1804 | r = complete_pio(vcpu); | 1805 | r = complete_pio(vcpu); |
| 1805 | if (r) | 1806 | if (r) |
| 1806 | goto out; | 1807 | goto out; |
| 1807 | } else { | 1808 | } else if (!vcpu->mmio_is_write) { |
| 1808 | memcpy(vcpu->mmio_data, kvm_run->mmio.data, 8); | 1809 | memcpy(vcpu->mmio_data, kvm_run->mmio.data, 8); |
| 1809 | vcpu->mmio_read_completed = 1; | 1810 | vcpu->mmio_read_completed = 1; |
| 1811 | vcpu->mmio_needed = 0; | ||
| 1812 | r = emulate_instruction(vcpu, kvm_run, | ||
| 1813 | vcpu->mmio_fault_cr2, 0); | ||
| 1814 | if (r == EMULATE_DO_MMIO) { | ||
| 1815 | /* | ||
| 1816 | * Read-modify-write. Back to userspace. | ||
| 1817 | */ | ||
| 1818 | kvm_run->exit_reason = KVM_EXIT_MMIO; | ||
| 1819 | r = 0; | ||
| 1820 | goto out; | ||
| 1821 | } | ||
| 1810 | } | 1822 | } |
| 1811 | } | 1823 | } |
| 1812 | 1824 | ||
| 1813 | vcpu->mmio_needed = 0; | ||
| 1814 | |||
| 1815 | if (kvm_run->exit_reason == KVM_EXIT_HYPERCALL) { | 1825 | if (kvm_run->exit_reason == KVM_EXIT_HYPERCALL) { |
| 1816 | kvm_arch_ops->cache_regs(vcpu); | 1826 | kvm_arch_ops->cache_regs(vcpu); |
| 1817 | vcpu->regs[VCPU_REGS_RAX] = kvm_run->hypercall.ret; | 1827 | vcpu->regs[VCPU_REGS_RAX] = kvm_run->hypercall.ret; |
