According to privious decisions, mmu code should be moved to arch.  

>From 43a629932b6babcbf2af75299192c1d77c2393d5 Mon Sep 17 00:00:00 2001
From: Zhang Xiantao <[EMAIL PROTECTED]>
Date: Fri, 16 Nov 2007 13:16:40 +0800
Subject: [PATCH] KVM: MMU split for portability.
Since mmu code is very arch-denpendent, move them to archs.
1. For kvm_vm_ioctl_get_dirty_log, this ioctl should be first transfered
to arch-specific code, and will 
call the common code implemtend in kvm_get_dirty_log to perform common
task. 
2. For set_memory_region,  I moved the mmu-speicific operations to an
arch-ops. 
Signed-off-by: Zhang Xiantao <[EMAIL PROTECTED]>
---
 drivers/kvm/kvm.h      |    8 ++++
 drivers/kvm/kvm_main.c |   49 +++------------------------
 drivers/kvm/x86.c      |   85
+++++++++++++++++++++++++++++++++++++++++++++---
 3 files changed, 94 insertions(+), 48 deletions(-)

diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index e34e246..2c1ee4b 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -526,6 +526,9 @@ int kvm_is_error_hva(unsigned long addr);
 int kvm_set_memory_region(struct kvm *kvm,
                          struct kvm_userspace_memory_region *mem,
                          int user_alloc);
+void kvm_arch_set_memory_region(struct kvm *kvm,
+                         struct kvm_userspace_memory_region *mem,
+                         int user_alloc);
 int __kvm_set_memory_region(struct kvm *kvm,
                            struct kvm_userspace_memory_region *mem,
                            int user_alloc);
@@ -631,6 +634,11 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu);
 
 int kvm_dev_ioctl_check_extension(long ext);
 
+int kvm_get_dirty_log(struct kvm *kvm,
+                       struct kvm_dirty_log *log, int *is_dirty);
+int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
+                               struct kvm_dirty_log *log);
+
 int kvm_vm_ioctl_set_memory_region(struct kvm *kvm,
                                   struct
                                   kvm_userspace_memory_region *mem,
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 0414e92..84eec47 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -362,29 +362,9 @@ int __kvm_set_memory_region(struct kvm *kvm,
        if (mem->slot >= kvm->nmemslots)
                kvm->nmemslots = mem->slot + 1;
 
-       if (!kvm->n_requested_mmu_pages) {
-               unsigned int n_pages;
-
-               if (npages) {
-                       n_pages = npages * KVM_PERMILLE_MMU_PAGES /
1000;
-                       kvm_mmu_change_mmu_pages(kvm,
kvm->n_alloc_mmu_pages +
-                                                n_pages);
-               } else {
-                       unsigned int nr_mmu_pages;
-
-                       n_pages = old.npages * KVM_PERMILLE_MMU_PAGES /
1000;
-                       nr_mmu_pages = kvm->n_alloc_mmu_pages - n_pages;
-                       nr_mmu_pages = max(nr_mmu_pages,
-                                       (unsigned int)
KVM_MIN_ALLOC_MMU_PAGES);
-                       kvm_mmu_change_mmu_pages(kvm, nr_mmu_pages);
-               }
-       }
 
        *memslot = new;
 
-       kvm_mmu_slot_remove_write_access(kvm, mem->slot);
-       kvm_flush_remote_tlbs(kvm);
-
        kvm_free_physmem_slot(&old, &new);
        return 0;
 
@@ -404,6 +384,8 @@ int kvm_set_memory_region(struct kvm *kvm,
 
        mutex_lock(&kvm->lock);
        r = __kvm_set_memory_region(kvm, mem, user_alloc);
+       if (r == 0)
+               kvm_arch_set_memory_region(kvm, mem, user_alloc);
        mutex_unlock(&kvm->lock);
        return r;
 }
@@ -419,19 +401,14 @@ int kvm_vm_ioctl_set_memory_region(struct kvm
*kvm,
        return kvm_set_memory_region(kvm, mem, user_alloc);
 }
 
-/*
- * Get (and clear) the dirty memory log for a memory slot.
- */
-static int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
-                                     struct kvm_dirty_log *log)
+int kvm_get_dirty_log(struct kvm *kvm,
+                       struct kvm_dirty_log *log, int *is_dirty)
 {
        struct kvm_memory_slot *memslot;
        int r, i;
        int n;
        unsigned long any = 0;
 
-       mutex_lock(&kvm->lock);
-
        r = -EINVAL;
        if (log->slot >= KVM_MEMORY_SLOTS)
                goto out;
@@ -450,17 +427,11 @@ static int kvm_vm_ioctl_get_dirty_log(struct kvm
*kvm,
        if (copy_to_user(log->dirty_bitmap, memslot->dirty_bitmap, n))
                goto out;
 
-       /* If nothing is dirty, don't bother messing with page tables.
*/
-       if (any) {
-               kvm_mmu_slot_remove_write_access(kvm, log->slot);
-               kvm_flush_remote_tlbs(kvm);
-               memset(memslot->dirty_bitmap, 0, n);
-       }
+       if (any)
+               *is_dirty = 1;
 
        r = 0;
-
 out:
-       mutex_unlock(&kvm->lock);
        return r;
 }
 
@@ -1404,10 +1375,6 @@ int kvm_init(void *opaque, unsigned int
vcpu_size,
        int r;
        int cpu;
 
-       r = kvm_mmu_module_init();
-       if (r)
-               goto out4;
-
        kvm_init_debug();
 
        r = kvm_arch_init(opaque);
@@ -1466,8 +1433,6 @@ int kvm_init(void *opaque, unsigned int vcpu_size,
        kvm_preempt_ops.sched_in = kvm_sched_in;
        kvm_preempt_ops.sched_out = kvm_sched_out;
 
-       kvm_mmu_set_nonpresent_ptes(0ull, 0ull);
-
        return 0;
 
 out_free:
@@ -1486,7 +1451,6 @@ out_free_0:
 out:
        kvm_arch_exit();
        kvm_exit_debug();
-       kvm_mmu_module_exit();
 out4:
        return r;
 }
@@ -1505,6 +1469,5 @@ void kvm_exit(void)
        kvm_arch_exit();
        kvm_exit_debug();
        __free_page(bad_page);
-       kvm_mmu_module_exit();
 }
 EXPORT_SYMBOL_GPL(kvm_exit);
diff --git a/drivers/kvm/x86.c b/drivers/kvm/x86.c
index 49cde46..375d36f 100644
--- a/drivers/kvm/x86.c
+++ b/drivers/kvm/x86.c
@@ -926,6 +926,37 @@ static int kvm_vm_ioctl_set_irqchip(struct kvm
*kvm, struct kvm_irqchip *chip)
        return r;
 }
 
+/*
+ * Get (and clear) the dirty memory log for a memory slot.
+ */
+int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
+                                     struct kvm_dirty_log *log)
+{
+       int r;
+       int n;
+       struct kvm_memory_slot *memslot;
+       int is_dirty = 0;
+
+       mutex_lock(&kvm->lock);
+
+       r = kvm_get_dirty_log(kvm, log, &is_dirty);
+       if (r)
+               goto out;
+
+       /* If nothing is dirty, don't bother messing with page tables.
*/
+       if (is_dirty) {
+               kvm_mmu_slot_remove_write_access(kvm, log->slot);
+               kvm_flush_remote_tlbs(kvm);
+               memslot = &kvm->memslots[log->slot];
+               n = ALIGN(memslot->npages, BITS_PER_LONG) / 8;
+               memset(memslot->dirty_bitmap, 0, n);
+       }
+       r = 0;
+out:
+       mutex_unlock(&kvm->lock);
+       return r;
+}
+
 long kvm_arch_vm_ioctl(struct file *filp,
                       unsigned int ioctl, unsigned long arg)
 {
@@ -1668,33 +1699,47 @@ EXPORT_SYMBOL_GPL(kvm_emulate_pio_string);
 
 int kvm_arch_init(void *opaque)
 {
+       int r;
        struct kvm_x86_ops *ops = (struct kvm_x86_ops *)opaque;
 
+       r = kvm_mmu_module_init();
+       if (r)
+               goto out_fail;
+
        kvm_init_msr_list();
 
        if (kvm_x86_ops) {
                printk(KERN_ERR "kvm: already loaded the other
module\n");
-               return -EEXIST;
+               r = -EEXIST;
+               goto out;
        }
 
        if (!ops->cpu_has_kvm_support()) {
                printk(KERN_ERR "kvm: no hardware support\n");
-               return -EOPNOTSUPP;
+               r = -EOPNOTSUPP;
+               goto out;
        }
        if (ops->disabled_by_bios()) {
                printk(KERN_ERR "kvm: disabled by bios\n");
-               return -EOPNOTSUPP;
+               r = -EOPNOTSUPP;
+               goto out;
        }
 
        kvm_x86_ops = ops;
-
+       kvm_mmu_set_nonpresent_ptes(0ull, 0ull);
        return 0;
+
+out:
+       kvm_mmu_module_exit();
+out_fail:
+       return r;
 }
 
 void kvm_arch_exit(void)
 {
        kvm_x86_ops = NULL;
- }
+       kvm_mmu_module_exit();
+}
 
 int kvm_emulate_halt(struct kvm_vcpu *vcpu)
 {
@@ -2544,3 +2589,33 @@ void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)
        kvm_mmu_destroy(vcpu);
        free_page((unsigned long)vcpu->pio_data);
 }
+
+void kvm_arch_set_memory_region(struct kvm *kvm,
+                         struct kvm_userspace_memory_region *mem,
+                         int user_alloc)
+{
+       unsigned long  npages = mem->memory_size >> PAGE_SHIFT;
+       struct kvm_memory_slot old = kvm->memslots[mem->slot];
+
+       if (!kvm->n_requested_mmu_pages) {
+               unsigned int n_pages;
+
+               if (npages) {
+                       n_pages = npages * KVM_PERMILLE_MMU_PAGES /
1000;
+                       kvm_mmu_change_mmu_pages(kvm,
kvm->n_alloc_mmu_pages +
+                                                n_pages);
+               } else {
+                       unsigned int nr_mmu_pages;
+
+                       n_pages = old.npages * KVM_PERMILLE_MMU_PAGES /
1000;
+                       nr_mmu_pages = kvm->n_alloc_mmu_pages - n_pages;
+                       nr_mmu_pages = max(nr_mmu_pages,
+                                       (unsigned int)
KVM_MIN_ALLOC_MMU_PAGES);
+                       kvm_mmu_change_mmu_pages(kvm, nr_mmu_pages);
+               }
+       }
+
+       kvm_mmu_slot_remove_write_access(kvm, mem->slot);
+       kvm_flush_remote_tlbs(kvm);
+}
+
-- 
1.5.0.5

Attachment: 0002-KVM-MMU-split-for-portability.patch
Description: 0002-KVM-MMU-split-for-portability.patch

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
kvm-devel mailing list
kvm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/kvm-devel

Reply via email to