From aa6f9fe44f7407715ce301ff0ce6a5809e43c2b2 Mon Sep 17 00:00:00 2001 From: Takuya Yoshikawa Date: Tue, 13 Apr 2010 22:47:24 +0900 Subject: [PATCH] --- yaml --- r: 197744 b: refs/heads/master c: 660c22c425cbe14badfb3b0a0206862577701ab7 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/include/linux/kvm_host.h | 6 ++++++ trunk/virt/kvm/kvm_main.c | 11 ++++++----- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/[refs] b/[refs] index 938baa50e2aa..8b76b2472d43 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 020df0794f5764e742feaa718be88b8f1b4ce04f +refs/heads/master: 660c22c425cbe14badfb3b0a0206862577701ab7 diff --git a/trunk/include/linux/kvm_host.h b/trunk/include/linux/kvm_host.h index 169d07758ee5..55830638aeb1 100644 --- a/trunk/include/linux/kvm_host.h +++ b/trunk/include/linux/kvm_host.h @@ -105,6 +105,12 @@ struct kvm_vcpu { struct kvm_vcpu_arch arch; }; +/* + * Some of the bitops functions do not support too long bitmaps. + * This number must be determined not to exceed such limits. + */ +#define KVM_MEM_MAX_NR_PAGES ((1UL << 31) - 1) + struct kvm_memory_slot { gfn_t base_gfn; unsigned long npages; diff --git a/trunk/virt/kvm/kvm_main.c b/trunk/virt/kvm/kvm_main.c index 55a5d4804499..d6351a34b297 100644 --- a/trunk/virt/kvm/kvm_main.c +++ b/trunk/virt/kvm/kvm_main.c @@ -557,6 +557,10 @@ int __kvm_set_memory_region(struct kvm *kvm, base_gfn = mem->guest_phys_addr >> PAGE_SHIFT; npages = mem->memory_size >> PAGE_SHIFT; + r = -EINVAL; + if (npages > KVM_MEM_MAX_NR_PAGES) + goto out; + if (!npages) mem->flags &= ~KVM_MEM_LOG_DIRTY_PAGES; @@ -1187,13 +1191,10 @@ void mark_page_dirty(struct kvm *kvm, gfn_t gfn) memslot = gfn_to_memslot_unaliased(kvm, gfn); if (memslot && memslot->dirty_bitmap) { unsigned long rel_gfn = gfn - memslot->base_gfn; - unsigned long *p = memslot->dirty_bitmap + - rel_gfn / BITS_PER_LONG; - int offset = rel_gfn % BITS_PER_LONG; /* avoid RMW */ - if (!generic_test_le_bit(offset, p)) - generic___set_le_bit(offset, p); + if (!generic_test_le_bit(rel_gfn, memslot->dirty_bitmap)) + generic___set_le_bit(rel_gfn, memslot->dirty_bitmap); } }