From a42fe5f79f3fe3a2f4ca72e746eb62613f6e811e Mon Sep 17 00:00:00 2001 From: Avi Kivity <avi@redhat.com> Date: Sun, 29 Mar 2009 16:31:25 +0300 Subject: [PATCH 5/6] KVM: MMU: Fix off-by-one calculating large page count 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). (cherry picked from commit 54d4f4cd1c334c8a1eece613895cb86370ca7107) Signed-off-by: Avi Kivity <avi@redhat.com> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> RH-Upstream-status: applied(kvm/queue) Bugzilla: 500263 Acked-by: Marcelo Tosatti <mtosatti@redhat.com> Acked-by: john cooper <john.cooper@redhat.com> Acked-by: Andrea Arcangeli <aarcange@redhat.com> Acked-by: Avi Kivity <avi@redhat.com> --- virt/kvm/kvm_main.c | 8 +++----- 1 files changed, 3 insertions(+), 5 deletions(-) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 19140f7..68e5b2d 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -956,6 +956,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; @@ -1031,11 +1032,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)); -- 1.6.3.rc4.29.g8146