summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorZhang Xiantao2007-11-20 06:11:38 +0100
committerAvi Kivity2008-01-30 16:53:09 +0100
commit3ad82a7e874c5d6c4045090cc01d7794dd9eb21c (patch)
tree94aabdff667daa7de80b61dd7d0233af21a54fa4 /drivers
parentKVM: x86 emulator: prefetch up to 15 bytes of the instruction executed (diff)
downloadkernel-qcow2-linux-3ad82a7e874c5d6c4045090cc01d7794dd9eb21c.tar.gz
kernel-qcow2-linux-3ad82a7e874c5d6c4045090cc01d7794dd9eb21c.tar.xz
kernel-qcow2-linux-3ad82a7e874c5d6c4045090cc01d7794dd9eb21c.zip
KVM: Recalculate mmu pages needed for every memory region change
Instead of incrementally changing the mmu cache size for every memory slot operation, recalculate it from scratch. This is simpler and safer. Signed-off-by: Zhang Xiantao <xiantao.zhang@intel.com> Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/kvm/kvm_main.c21
-rw-r--r--drivers/kvm/mmu.c19
-rw-r--r--drivers/kvm/x86.h1
3 files changed, 24 insertions, 17 deletions
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 729573b844e5..93ecafbfb1b6 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -333,26 +333,13 @@ int __kvm_set_memory_region(struct kvm *kvm,
if (mem->slot >= kvm->nmemslots)
kvm->nmemslots = mem->slot + 1;
+ *memslot = new;
+
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);
- }
+ unsigned int nr_mmu_pages = kvm_mmu_calculate_mmu_pages(kvm);
+ 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);
diff --git a/drivers/kvm/mmu.c b/drivers/kvm/mmu.c
index 4624f3789b9a..101cd5377a89 100644
--- a/drivers/kvm/mmu.c
+++ b/drivers/kvm/mmu.c
@@ -1535,6 +1535,25 @@ nomem:
return -ENOMEM;
}
+/*
+ * Caculate mmu pages needed for kvm.
+ */
+unsigned int kvm_mmu_calculate_mmu_pages(struct kvm *kvm)
+{
+ int i;
+ unsigned int nr_mmu_pages;
+ unsigned int nr_pages = 0;
+
+ for (i = 0; i < kvm->nmemslots; i++)
+ nr_pages += kvm->memslots[i].npages;
+
+ nr_mmu_pages = nr_pages * KVM_PERMILLE_MMU_PAGES / 1000;
+ nr_mmu_pages = max(nr_mmu_pages,
+ (unsigned int) KVM_MIN_ALLOC_MMU_PAGES);
+
+ return nr_mmu_pages;
+}
+
#ifdef AUDIT
static const char *audit_msg;
diff --git a/drivers/kvm/x86.h b/drivers/kvm/x86.h
index 90b791bf6287..71f2477d03fd 100644
--- a/drivers/kvm/x86.h
+++ b/drivers/kvm/x86.h
@@ -236,6 +236,7 @@ void kvm_mmu_set_nonpresent_ptes(u64 trap_pte, u64 notrap_pte);
int kvm_mmu_reset_context(struct kvm_vcpu *vcpu);
void kvm_mmu_slot_remove_write_access(struct kvm *kvm, int slot);
void kvm_mmu_zap_all(struct kvm *kvm);
+unsigned int kvm_mmu_calculate_mmu_pages(struct kvm *kvm);
void kvm_mmu_change_mmu_pages(struct kvm *kvm, unsigned int kvm_nr_mmu_pages);
enum emulation_result {