aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/kvm/kvm_main.c
diff options
context:
space:
mode:
authorAvi Kivity <avi@qumranet.com>2007-01-05 19:36:44 -0500
committerLinus Torvalds <torvalds@woody.osdl.org>2007-01-06 02:55:25 -0500
commitda4a00f002239f72b0d7d0eeaa3b60100e2b1438 (patch)
tree7c7e72ea1fd48025c029429b413e127a3a580c10 /drivers/kvm/kvm_main.c
parent815af8d42ee3f844c0ceaf2104bd9c6a0bb1e26c (diff)
[PATCH] KVM: MMU: Support emulated writes into RAM
As the mmu write protects guest page table, we emulate those writes. Since they are not mmio, there is no need to go to userspace to perform them. So, perform the writes in the kernel if possible, and notify the mmu about them so it can take the approriate action. Signed-off-by: Avi Kivity <avi@qumranet.com> Acked-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
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;