diff options
-rw-r--r-- | drivers/kvm/kvm.h | 3 | ||||
-rw-r--r-- | drivers/kvm/kvm_main.c | 24 | ||||
-rw-r--r-- | drivers/kvm/mmu.c | 9 |
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 | ||
449 | unsigned long segment_base(u16 selector); | 449 | unsigned long segment_base(u16 selector); |
450 | 450 | ||
451 | void kvm_mmu_pre_write(struct kvm_vcpu *vcpu, gpa_t gpa, int bytes); | ||
452 | void kvm_mmu_post_write(struct kvm_vcpu *vcpu, gpa_t gpa, int bytes); | ||
453 | |||
451 | static inline struct page *_gfn_to_page(struct kvm *kvm, gfn_t gfn) | 454 | static 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 | ||
880 | static 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 | |||
880 | static int emulator_write_emulated(unsigned long addr, | 901 | static 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 | ||
959 | void 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 | |||
964 | void kvm_mmu_post_write(struct kvm_vcpu *vcpu, gpa_t gpa, int bytes) | ||
965 | { | ||
966 | } | ||
967 | |||
959 | static void free_mmu_pages(struct kvm_vcpu *vcpu) | 968 | static void free_mmu_pages(struct kvm_vcpu *vcpu) |
960 | { | 969 | { |
961 | while (!list_empty(&vcpu->free_pages)) { | 970 | while (!list_empty(&vcpu->free_pages)) { |