aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/kvm/kvm_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/kvm/kvm_main.c')
-rw-r--r--drivers/kvm/kvm_main.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 68e121eeccbc..047f6f6ed3f6 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -877,6 +877,27 @@ static int emulator_read_emulated(unsigned long addr,
877 } 877 }
878} 878}
879 879
880static int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa,
881 unsigned long val, int bytes)
882{
883 struct kvm_memory_slot *m;
884 struct page *page;
885 void *virt;
886
887 if (((gpa + bytes - 1) >> PAGE_SHIFT) != (gpa >> PAGE_SHIFT))
888 return 0;
889 m = gfn_to_memslot(vcpu->kvm, gpa >> PAGE_SHIFT);
890 if (!m)
891 return 0;
892 page = gfn_to_page(m, gpa >> PAGE_SHIFT);
893 kvm_mmu_pre_write(vcpu, gpa, bytes);
894 virt = kmap_atomic(page, KM_USER0);
895 memcpy(virt + offset_in_page(gpa), &val, bytes);
896 kunmap_atomic(virt, KM_USER0);
897 kvm_mmu_post_write(vcpu, gpa, bytes);
898 return 1;
899}
900
880static int emulator_write_emulated(unsigned long addr, 901static int emulator_write_emulated(unsigned long addr,
881 unsigned long val, 902 unsigned long val,
882 unsigned int bytes, 903 unsigned int bytes,
@@ -888,6 +909,9 @@ static int emulator_write_emulated(unsigned long addr,
888 if (gpa == UNMAPPED_GVA) 909 if (gpa == UNMAPPED_GVA)
889 return X86EMUL_PROPAGATE_FAULT; 910 return X86EMUL_PROPAGATE_FAULT;
890 911
912 if (emulator_write_phys(vcpu, gpa, val, bytes))
913 return X86EMUL_CONTINUE;
914
891 vcpu->mmio_needed = 1; 915 vcpu->mmio_needed = 1;
892 vcpu->mmio_phys_addr = gpa; 916 vcpu->mmio_phys_addr = gpa;
893 vcpu->mmio_size = bytes; 917 vcpu->mmio_size = bytes;