#define KVMPPC_GOT_PAGE                0x80
 
 struct kvm_arch_memory_slot {
+       unsigned long *rmap;
 };
 
 struct kvm_arch {
 
                goto out_unlock;
        hpte[0] = (hpte[0] & ~HPTE_V_ABSENT) | HPTE_V_VALID;
 
-       rmap = &memslot->rmap[gfn - memslot->base_gfn];
+       rmap = &memslot->arch.rmap[gfn - memslot->base_gfn];
        lock_rmap(rmap);
 
        /* Check if we might have been invalidated; let the guest retry if so */
                for (; gfn < gfn_end; ++gfn) {
                        gfn_t gfn_offset = gfn - memslot->base_gfn;
 
-                       ret = handler(kvm, &memslot->rmap[gfn_offset], gfn);
+                       ret = handler(kvm, &memslot->arch.rmap[gfn_offset], gfn);
                        retval |= ret;
                }
        }
        unsigned long *rmapp, *map;
 
        preempt_disable();
-       rmapp = memslot->rmap;
+       rmapp = memslot->arch.rmap;
        map = memslot->dirty_bitmap;
        for (i = 0; i < memslot->npages; ++i) {
                if (kvm_test_clear_dirty(kvm, rmapp))
 
        if (!memslot || (memslot->flags & KVM_MEMSLOT_INVALID))
                return;
 
-       rmap = real_vmalloc_addr(&memslot->rmap[gfn - memslot->base_gfn]);
+       rmap = real_vmalloc_addr(&memslot->arch.rmap[gfn - memslot->base_gfn]);
        lock_rmap(rmap);
 
        head = *rmap & KVMPPC_RMAP_INDEX;
        if (!slot_is_aligned(memslot, psize))
                return H_PARAMETER;
        slot_fn = gfn - memslot->base_gfn;
-       rmap = &memslot->rmap[slot_fn];
+       rmap = &memslot->arch.rmap[slot_fn];
 
        if (!kvm->arch.using_mmu_notifiers) {
                physp = kvm->arch.slot_phys[memslot->id];
 
 void kvm_arch_free_memslot(struct kvm_memory_slot *free,
                           struct kvm_memory_slot *dont)
 {
+       if (!dont || free->arch.rmap != dont->arch.rmap) {
+               vfree(free->arch.rmap);
+               free->arch.rmap = NULL;
+       }
 }
 
 int kvm_arch_create_memslot(struct kvm_memory_slot *slot, unsigned long npages)
 {
+       slot->arch.rmap = vzalloc(npages * sizeof(*slot->arch.rmap));
+       if (!slot->arch.rmap)
+               return -ENOMEM;
+
        return 0;
 }
 
 
 };
 
 struct kvm_arch_memory_slot {
-       unsigned long *rmap_pde[KVM_NR_PAGE_SIZES - 1];
+       unsigned long *rmap[KVM_NR_PAGE_SIZES];
        struct kvm_lpage_info *lpage_info[KVM_NR_PAGE_SIZES - 1];
 };
 
 
 {
        unsigned long idx;
 
-       if (likely(level == PT_PAGE_TABLE_LEVEL))
-               return &slot->rmap[gfn - slot->base_gfn];
-
        idx = gfn_to_index(gfn, slot->base_gfn, level);
-       return &slot->arch.rmap_pde[level - PT_DIRECTORY_LEVEL][idx];
+       return &slot->arch.rmap[level - PT_PAGE_TABLE_LEVEL][idx];
 }
 
 /*
 
 {
        int i;
 
-       for (i = 0; i < KVM_NR_PAGE_SIZES - 1; ++i) {
-               if (!dont || free->arch.rmap_pde[i] != dont->arch.rmap_pde[i]) {
-                       kvm_kvfree(free->arch.rmap_pde[i]);
-                       free->arch.rmap_pde[i] = NULL;
+       for (i = 0; i < KVM_NR_PAGE_SIZES; ++i) {
+               if (!dont || free->arch.rmap[i] != dont->arch.rmap[i]) {
+                       kvm_kvfree(free->arch.rmap[i]);
+                       free->arch.rmap[i] = NULL;
                }
-               if (!dont || free->arch.lpage_info[i] != dont->arch.lpage_info[i]) {
-                       kvm_kvfree(free->arch.lpage_info[i]);
-                       free->arch.lpage_info[i] = NULL;
+               if (i == 0)
+                       continue;
+
+               if (!dont || free->arch.lpage_info[i - 1] !=
+                            dont->arch.lpage_info[i - 1]) {
+                       kvm_kvfree(free->arch.lpage_info[i - 1]);
+                       free->arch.lpage_info[i - 1] = NULL;
                }
        }
 }
 {
        int i;
 
-       for (i = 0; i < KVM_NR_PAGE_SIZES - 1; ++i) {
+       for (i = 0; i < KVM_NR_PAGE_SIZES; ++i) {
                unsigned long ugfn;
                int lpages;
-               int level = i + 2;
+               int level = i + 1;
 
                lpages = gfn_to_index(slot->base_gfn + npages - 1,
                                      slot->base_gfn, level) + 1;
 
-               slot->arch.rmap_pde[i] =
-                       kvm_kvzalloc(lpages * sizeof(*slot->arch.rmap_pde[i]));
-               if (!slot->arch.rmap_pde[i])
+               slot->arch.rmap[i] =
+                       kvm_kvzalloc(lpages * sizeof(*slot->arch.rmap[i]));
+               if (!slot->arch.rmap[i])
                        goto out_free;
+               if (i == 0)
+                       continue;
 
-               slot->arch.lpage_info[i] =
-                       kvm_kvzalloc(lpages * sizeof(*slot->arch.lpage_info[i]));
-               if (!slot->arch.lpage_info[i])
+               slot->arch.lpage_info[i - 1] = kvm_kvzalloc(lpages *
+                                       sizeof(*slot->arch.lpage_info[i - 1]));
+               if (!slot->arch.lpage_info[i - 1])
                        goto out_free;
 
                if (slot->base_gfn & (KVM_PAGES_PER_HPAGE(level) - 1))
-                       slot->arch.lpage_info[i][0].write_count = 1;
+                       slot->arch.lpage_info[i - 1][0].write_count = 1;
                if ((slot->base_gfn + npages) & (KVM_PAGES_PER_HPAGE(level) - 1))
-                       slot->arch.lpage_info[i][lpages - 1].write_count = 1;
+                       slot->arch.lpage_info[i - 1][lpages - 1].write_count = 1;
                ugfn = slot->userspace_addr >> PAGE_SHIFT;
                /*
                 * If the gfn and userspace address are not aligned wrt each
                        unsigned long j;
 
                        for (j = 0; j < lpages; ++j)
-                               slot->arch.lpage_info[i][j].write_count = 1;
+                               slot->arch.lpage_info[i - 1][j].write_count = 1;
                }
        }
 
        return 0;
 
 out_free:
-       for (i = 0; i < KVM_NR_PAGE_SIZES - 1; ++i) {
-               kvm_kvfree(slot->arch.rmap_pde[i]);
-               kvm_kvfree(slot->arch.lpage_info[i]);
-               slot->arch.rmap_pde[i] = NULL;
-               slot->arch.lpage_info[i] = NULL;
+       for (i = 0; i < KVM_NR_PAGE_SIZES; ++i) {
+               kvm_kvfree(slot->arch.rmap[i]);
+               slot->arch.rmap[i] = NULL;
+               if (i == 0)
+                       continue;
+
+               kvm_kvfree(slot->arch.lpage_info[i - 1]);
+               slot->arch.lpage_info[i - 1] = NULL;
        }
        return -ENOMEM;
 }
 
        gfn_t base_gfn;
        unsigned long npages;
        unsigned long flags;
-       unsigned long *rmap;
        unsigned long *dirty_bitmap;
        struct kvm_arch_memory_slot arch;
        unsigned long userspace_addr;
 
 static void kvm_free_physmem_slot(struct kvm_memory_slot *free,
                                  struct kvm_memory_slot *dont)
 {
-       if (!dont || free->rmap != dont->rmap)
-               vfree(free->rmap);
-
        if (!dont || free->dirty_bitmap != dont->dirty_bitmap)
                kvm_destroy_dirty_bitmap(free);
 
        kvm_arch_free_memslot(free, dont);
 
        free->npages = 0;
-       free->rmap = NULL;
 }
 
 void kvm_free_physmem(struct kvm *kvm)
        if (npages && !old.npages) {
                new.user_alloc = user_alloc;
                new.userspace_addr = mem->userspace_addr;
-#ifndef CONFIG_S390
-               new.rmap = vzalloc(npages * sizeof(*new.rmap));
-               if (!new.rmap)
-                       goto out_free;
-#endif /* not defined CONFIG_S390 */
+
                if (kvm_arch_create_memslot(&new, npages))
                        goto out_free;
        }
 
        /* actual memory is freed via old in kvm_free_physmem_slot below */
        if (!npages) {
-               new.rmap = NULL;
                new.dirty_bitmap = NULL;
                memset(&new.arch, 0, sizeof(new.arch));
        }