KVM: limit the number of pages per memory slot
authorTakuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
Tue, 13 Apr 2010 13:47:24 +0000 (22:47 +0900)
committerAvi Kivity <avi@redhat.com>
Mon, 17 May 2010 09:17:41 +0000 (12:17 +0300)
This patch limits the number of pages per memory slot to make
us free from extra care about type issues.

Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>

include/linux/kvm_host.h
virt/kvm/kvm_main.c

index 169d077..5583063 100644 (file)
@@ -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;
index 55a5d48..d6351a3 100644 (file)
@@ -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);
        }
 }