From aa48a37f3cb7d2d30e573674808e7665f8d541bc Mon Sep 17 00:00:00 2001 From: Marcelo Tosatti <mtosatti@redhat.com> Date: Wed, 22 Jul 2009 13:40:27 -0300 Subject: [PATCH] KVM: MMU: handle n_free_mmu_pages > n_alloc_mmu_pages in kvm_mmu_change_mmu_pages kvm_mmu_change_mmu_pages mishandles the case where n_alloc_mmu_pages is smaller then n_free_mmu_pages, by not checking if the result of the subtraction is negative. Its a valid condition which can happen if a large number of pages has been recently freed. Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com> (cherry picked from 45657f28e00e412439ae52c0bbe051c312734f50) Bugzilla: 487857 Message-ID: <20090722164027.GA20383@amt.cnet> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> RH-Upstream-status: backport-from-upstream Acked-by: Juan Quintela <quintela@redhat.com> Acked-by: Andrea Arcangeli <aarcange@redhat.com> Acked-by: Avi Kivity <avi@redhat.com> --- arch/x86/kvm/mmu.c | 15 ++++++++------- 1 files changed, 8 insertions(+), 7 deletions(-) diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index c58076d..29bbf8c 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -1503,24 +1503,25 @@ static int kvm_mmu_zap_page(struct kvm *kvm, struct kvm_mmu_page *sp) */ void kvm_mmu_change_mmu_pages(struct kvm *kvm, unsigned int kvm_nr_mmu_pages) { + int used_pages; + + used_pages = kvm->arch.n_alloc_mmu_pages - kvm->arch.n_free_mmu_pages; + used_pages = max(0, used_pages); + /* * If we set the number of mmu pages to be smaller be than the * number of actived pages , we must to free some mmu pages before we * change the value */ - if ((kvm->arch.n_alloc_mmu_pages - kvm->arch.n_free_mmu_pages) > - kvm_nr_mmu_pages) { - int n_used_mmu_pages = kvm->arch.n_alloc_mmu_pages - - kvm->arch.n_free_mmu_pages; - - while (n_used_mmu_pages > kvm_nr_mmu_pages) { + if (used_pages > kvm_nr_mmu_pages) { + while (used_pages > kvm_nr_mmu_pages) { struct kvm_mmu_page *page; page = container_of(kvm->arch.active_mmu_pages.prev, struct kvm_mmu_page, link); kvm_mmu_zap_page(kvm, page); - n_used_mmu_pages--; + used_pages--; } kvm->arch.n_free_mmu_pages = 0; } -- 1.6.3.rc4.29.g8146