aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAvi Kivity <avi@redhat.com>2009-06-08 08:52:39 -0400
committerAvi Kivity <avi@redhat.com>2009-06-10 08:17:58 -0400
commitac04527f7947020c5890090b2ac87af4e98d977e (patch)
tree679e5c4773386d4543ef990c108d950594c20862
parenta0861c02a981c943573478ea13b29b1fb958ee5b (diff)
KVM: Disable large pages on misaligned memory slots
If a slots guest physical address and host virtual address unequal (mod large page size), then we would erronously try to back guest large pages with host large pages. Detect this misalignment and diable large page support for the trouble slot. Cc: stable@kernel.org Signed-off-by: Avi Kivity <avi@redhat.com>
-rw-r--r--virt/kvm/kvm_main.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 5fed9bfc3cf5..5f865ed4c431 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -1086,7 +1086,7 @@ int __kvm_set_memory_region(struct kvm *kvm,
1086{ 1086{
1087 int r; 1087 int r;
1088 gfn_t base_gfn; 1088 gfn_t base_gfn;
1089 unsigned long npages; 1089 unsigned long npages, ugfn;
1090 int largepages; 1090 int largepages;
1091 unsigned long i; 1091 unsigned long i;
1092 struct kvm_memory_slot *memslot; 1092 struct kvm_memory_slot *memslot;
@@ -1177,6 +1177,14 @@ int __kvm_set_memory_region(struct kvm *kvm,
1177 new.lpage_info[0].write_count = 1; 1177 new.lpage_info[0].write_count = 1;
1178 if ((base_gfn+npages) % KVM_PAGES_PER_HPAGE) 1178 if ((base_gfn+npages) % KVM_PAGES_PER_HPAGE)
1179 new.lpage_info[largepages-1].write_count = 1; 1179 new.lpage_info[largepages-1].write_count = 1;
1180 ugfn = new.userspace_addr >> PAGE_SHIFT;
1181 /*
1182 * If the gfn and userspace address are not aligned wrt each
1183 * other, disable large page support for this slot
1184 */
1185 if ((base_gfn ^ ugfn) & (KVM_PAGES_PER_HPAGE - 1))
1186 for (i = 0; i < largepages; ++i)
1187 new.lpage_info[i].write_count = 1;
1180 } 1188 }
1181 1189
1182 /* Allocate page dirty bitmap if needed */ 1190 /* Allocate page dirty bitmap if needed */