]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
KVM: MMU: Fix off-by-one calculating large page count
authorAvi Kivity <avi@redhat.com>
Fri, 24 Apr 2009 16:05:14 +0000 (16:05 +0000)
committerGreg Kroah-Hartman <gregkh@suse.de>
Fri, 8 May 2009 22:44:59 +0000 (15:44 -0700)
upstream commit: 99894a799f09cf9e28296bb16e75bd5830fd2c4e

The large page initialization code concludes there are two large pages spanned
by a slot covering 1 (small) page starting at gfn 1.  This is incorrect, and
also results in incorrect write_count initialization in some cases (base = 1,
npages = 513 for example).

Cc: stable@kernel.org
Signed-off-by: Avi Kivity <avi@redhat.com>
Signed-off-by: Chris Wright <chrisw@sous-sol.org>
virt/kvm/kvm_main.c

index 6723411ead55002379143abcfc1f80ad391d126a..e02c48ba2224166e7f2160d5a5d487e18a9ececa 100644 (file)
@@ -964,6 +964,7 @@ int __kvm_set_memory_region(struct kvm *kvm,
        int r;
        gfn_t base_gfn;
        unsigned long npages;
+       int largepages;
        unsigned long i;
        struct kvm_memory_slot *memslot;
        struct kvm_memory_slot old, new;
@@ -1039,11 +1040,8 @@ int __kvm_set_memory_region(struct kvm *kvm,
                        new.userspace_addr = 0;
        }
        if (npages && !new.lpage_info) {
-               int largepages = npages / KVM_PAGES_PER_HPAGE;
-               if (npages % KVM_PAGES_PER_HPAGE)
-                       largepages++;
-               if (base_gfn % KVM_PAGES_PER_HPAGE)
-                       largepages++;
+               largepages = 1 + (base_gfn + npages - 1) / KVM_PAGES_PER_HPAGE;
+               largepages -= base_gfn / KVM_PAGES_PER_HPAGE;
 
                new.lpage_info = vmalloc(largepages * sizeof(*new.lpage_info));