summaryrefslogtreecommitdiff
path: root/virt/kvm
diff options
context:
space:
mode:
authorAvi Kivity <avi@redhat.com>2009-06-08 12:52:39 (GMT)
committerAvi Kivity <avi@redhat.com>2009-06-10 12:17:58 (GMT)
commitac04527f7947020c5890090b2ac87af4e98d977e (patch)
tree679e5c4773386d4543ef990c108d950594c20862 /virt/kvm
parenta0861c02a981c943573478ea13b29b1fb958ee5b (diff)
downloadlinux-ac04527f7947020c5890090b2ac87af4e98d977e.tar.xz
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>
Diffstat (limited to 'virt/kvm')
-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 5fed9bf..5f865ed 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,
{
int r;
gfn_t base_gfn;
- unsigned long npages;
+ unsigned long npages, ugfn;
int largepages;
unsigned long i;
struct kvm_memory_slot *memslot;
@@ -1177,6 +1177,14 @@ int __kvm_set_memory_region(struct kvm *kvm,
new.lpage_info[0].write_count = 1;
if ((base_gfn+npages) % KVM_PAGES_PER_HPAGE)
new.lpage_info[largepages-1].write_count = 1;
+ ugfn = new.userspace_addr >> PAGE_SHIFT;
+ /*
+ * If the gfn and userspace address are not aligned wrt each
+ * other, disable large page support for this slot
+ */
+ if ((base_gfn ^ ugfn) & (KVM_PAGES_PER_HPAGE - 1))
+ for (i = 0; i < largepages; ++i)
+ new.lpage_info[i].write_count = 1;
}
/* Allocate page dirty bitmap if needed */