return vm;
 }
 
+#define DIRTY_MEM_BITS 30 /* 1G */
+#define PAGE_SHIFT_4K  12
+
 static void run_test(enum vm_guest_mode mode, unsigned long iterations,
                     unsigned long interval, uint64_t phys_offset)
 {
        uint64_t max_gfn;
        unsigned long *bmap;
 
+       /*
+        * We reserve page table for 2 times of extra dirty mem which
+        * will definitely cover the original (1G+) test range.  Here
+        * we do the calculation with 4K page size which is the
+        * smallest so the page number will be enough for all archs
+        * (e.g., 64K page size guest will need even less memory for
+        * page tables).
+        */
+       vm = create_vm(mode, VCPU_ID,
+                      2ul << (DIRTY_MEM_BITS - PAGE_SHIFT_4K),
+                      guest_code);
+
        switch (mode) {
        case VM_MODE_P52V48_4K:
                guest_pa_bits = 52;
         * A little more than 1G of guest page sized pages.  Cover the
         * case where the size is not aligned to 64 pages.
         */
-       guest_num_pages = (1ul << (30 - guest_page_shift)) + 16;
+       guest_num_pages = (1ul << (DIRTY_MEM_BITS - guest_page_shift)) + 16;
 #ifdef __s390x__
        /* Round up to multiple of 1M (segment size) */
        guest_num_pages = (guest_num_pages + 0xff) & ~0xffUL;
        bmap = bitmap_alloc(host_num_pages);
        host_bmap_track = bitmap_alloc(host_num_pages);
 
-       vm = create_vm(mode, VCPU_ID, guest_num_pages, guest_code);
-
 #ifdef USE_CLEAR_DIRTY_LOG
        struct kvm_enable_cap cap = {};