aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/kvm/kvm.h3
-rw-r--r--drivers/kvm/kvm_main.c24
-rw-r--r--drivers/kvm/mmu.c9
3 files changed, 36 insertions, 0 deletions
diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index 58b9deb0bc0e..b7068ecd7765 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -448,6 +448,9 @@ int kvm_write_guest(struct kvm_vcpu *vcpu,
448 448
449unsigned long segment_base(u16 selector); 449unsigned long segment_base(u16 selector);
450 450
451void kvm_mmu_pre_write(struct kvm_vcpu *vcpu, gpa_t gpa, int bytes);
452void kvm_mmu_post_write(struct kvm_vcpu *vcpu, gpa_t gpa, int bytes);
453
451static inline struct page *_gfn_to_page(struct kvm *kvm, gfn_t gfn) 454static inline struct page *_gfn_to_page(struct kvm *kvm, gfn_t gfn)
452{ 455{
453 struct kvm_memory_slot *slot = gfn_to_memslot(kvm, gfn); 456 struct kvm_memory_slot *slot = gfn_to_memslot(kvm, gfn);
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;
diff --git a/drivers/kvm/mmu.c b/drivers/kvm/mmu.c
index ceae25bfd4b5..bce7eb21f739 100644
--- a/drivers/kvm/mmu.c
+++ b/drivers/kvm/mmu.c
@@ -956,6 +956,15 @@ int kvm_mmu_reset_context(struct kvm_vcpu *vcpu)
956 return init_kvm_mmu(vcpu); 956 return init_kvm_mmu(vcpu);
957} 957}
958 958
959void kvm_mmu_pre_write(struct kvm_vcpu *vcpu, gpa_t gpa, int bytes)
960{
961 pgprintk("%s: gpa %llx bytes %d\n", __FUNCTION__, gpa, bytes);
962}
963
964void kvm_mmu_post_write(struct kvm_vcpu *vcpu, gpa_t gpa, int bytes)
965{
966}
967
959static void free_mmu_pages(struct kvm_vcpu *vcpu) 968static void free_mmu_pages(struct kvm_vcpu *vcpu)
960{ 969{
961 while (!list_empty(&vcpu->free_pages)) { 970 while (!list_empty(&vcpu->free_pages)) {