KVM: Separate rmap_pde from kvm_lpage_info->write_count
Takuya Yoshikawa [Mon, 2 Jul 2012 08:57:17 +0000 (17:57 +0900)]
This makes it possible to loop over rmap_pde arrays in the same way as
we do over rmap so that we can optimize kvm_handle_hva_range() easily in
the following patch.

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

arch/x86/include/asm/kvm_host.h
arch/x86/kvm/mmu.c
arch/x86/kvm/x86.c

index d4aab86..4f98da9 100644 (file)
@@ -500,11 +500,11 @@ struct kvm_vcpu_arch {
 };
 
 struct kvm_lpage_info {
-       unsigned long rmap_pde;
        int write_count;
 };
 
 struct kvm_arch_memory_slot {
+       unsigned long *rmap_pde[KVM_NR_PAGE_SIZES - 1];
        struct kvm_lpage_info *lpage_info[KVM_NR_PAGE_SIZES - 1];
 };
 
index d2855f8..3b3f5ae 100644 (file)
@@ -960,13 +960,13 @@ static void pte_list_walk(unsigned long *pte_list, pte_list_walk_fn fn)
 static unsigned long *__gfn_to_rmap(gfn_t gfn, int level,
                                    struct kvm_memory_slot *slot)
 {
-       struct kvm_lpage_info *linfo;
+       unsigned long idx;
 
        if (likely(level == PT_PAGE_TABLE_LEVEL))
                return &slot->rmap[gfn - slot->base_gfn];
 
-       linfo = lpage_info_slot(gfn, slot, level);
-       return &linfo->rmap_pde;
+       idx = gfn_to_index(gfn, slot->base_gfn, level);
+       return &slot->arch.rmap_pde[level - PT_DIRECTORY_LEVEL][idx];
 }
 
 /*
index 59b5950..829b4e9 100644 (file)
@@ -6314,6 +6314,10 @@ void kvm_arch_free_memslot(struct kvm_memory_slot *free,
        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;
+               }
                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;
@@ -6333,6 +6337,11 @@ int kvm_arch_create_memslot(struct kvm_memory_slot *slot, unsigned long npages)
                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])
+                       goto out_free;
+
                slot->arch.lpage_info[i] =
                        kvm_kvzalloc(lpages * sizeof(*slot->arch.lpage_info[i]));
                if (!slot->arch.lpage_info[i])
@@ -6361,7 +6370,9 @@ int kvm_arch_create_memslot(struct kvm_memory_slot *slot, unsigned long npages)
 
 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;
        }
        return -ENOMEM;