summaryrefslogtreecommitdiff
path: root/virt/kvm/kvm_main.c
diff options
context:
space:
mode:
authorTakuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>2012-02-08 13:02:18 +0900
committerAvi Kivity <avi@redhat.com>2012-03-08 14:10:22 +0200
commitdb3fe4eb45f3555d91a7124e18cf3a2f2a30eb90 (patch)
tree5d294feef8f6281d4cd6c67180e0514c74e87079 /virt/kvm/kvm_main.c
parent189a2f7b24677deced3d2a9803969ba69f4b75f6 (diff)
downloadlwn-db3fe4eb45f3555d91a7124e18cf3a2f2a30eb90.tar.gz
lwn-db3fe4eb45f3555d91a7124e18cf3a2f2a30eb90.zip
KVM: Introduce kvm_memory_slot::arch and move lpage_info into it
Some members of kvm_memory_slot are not used by every architecture. This patch is the first step to make this difference clear by introducing kvm_memory_slot::arch; lpage_info is moved into it. Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com> Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'virt/kvm/kvm_main.c')
-rw-r--r--virt/kvm/kvm_main.c70
1 files changed, 9 insertions, 61 deletions
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index a30447c5eb4a..8340e0e62034 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -535,21 +535,13 @@ static void kvm_destroy_dirty_bitmap(struct kvm_memory_slot *memslot)
static void kvm_free_physmem_slot(struct kvm_memory_slot *free,
struct kvm_memory_slot *dont)
{
- int i;
-
if (!dont || free->rmap != dont->rmap)
vfree(free->rmap);
if (!dont || free->dirty_bitmap != dont->dirty_bitmap)
kvm_destroy_dirty_bitmap(free);
-
- for (i = 0; i < KVM_NR_PAGE_SIZES - 1; ++i) {
- if (!dont || free->lpage_info[i] != dont->lpage_info[i]) {
- vfree(free->lpage_info[i]);
- free->lpage_info[i] = NULL;
- }
- }
+ kvm_arch_free_memslot(free, dont);
free->npages = 0;
free->rmap = NULL;
@@ -685,53 +677,6 @@ void update_memslots(struct kvm_memslots *slots, struct kvm_memory_slot *new)
slots->generation++;
}
-#ifndef CONFIG_S390
-static int create_lpage_info(struct kvm_memory_slot *slot, unsigned long npages)
-{
- int i;
-
- for (i = 0; i < KVM_NR_PAGE_SIZES - 1; ++i) {
- unsigned long ugfn;
- int lpages;
- int level = i + 2;
-
- lpages = gfn_to_index(slot->base_gfn + npages - 1,
- slot->base_gfn, level) + 1;
-
- slot->lpage_info[i] = vzalloc(lpages * sizeof(*slot->lpage_info[i]));
- if (!slot->lpage_info[i])
- goto out_free;
-
- if (slot->base_gfn & (KVM_PAGES_PER_HPAGE(level) - 1))
- slot->lpage_info[i][0].write_count = 1;
- if ((slot->base_gfn + npages) & (KVM_PAGES_PER_HPAGE(level) - 1))
- slot->lpage_info[i][lpages - 1].write_count = 1;
- ugfn = slot->userspace_addr >> PAGE_SHIFT;
- /*
- * If the gfn and userspace address are not aligned wrt each
- * other, or if explicitly asked to, disable large page
- * support for this slot
- */
- if ((slot->base_gfn ^ ugfn) & (KVM_PAGES_PER_HPAGE(level) - 1) ||
- !largepages_enabled) {
- unsigned long j;
-
- for (j = 0; j < lpages; ++j)
- slot->lpage_info[i][j].write_count = 1;
- }
- }
-
- return 0;
-
-out_free:
- for (i = 0; i < KVM_NR_PAGE_SIZES - 1; ++i) {
- vfree(slot->lpage_info[i]);
- slot->lpage_info[i] = NULL;
- }
- return -ENOMEM;
-}
-#endif /* not defined CONFIG_S390 */
-
/*
* Allocate some memory and give it an address in the guest physical address
* space.
@@ -819,10 +764,9 @@ int __kvm_set_memory_region(struct kvm *kvm,
new.rmap = vzalloc(npages * sizeof(*new.rmap));
if (!new.rmap)
goto out_free;
-
- if (create_lpage_info(&new, npages))
- goto out_free;
#endif /* not defined CONFIG_S390 */
+ if (kvm_arch_create_memslot(&new, npages))
+ goto out_free;
}
/* Allocate page dirty bitmap if needed */
@@ -880,8 +824,7 @@ int __kvm_set_memory_region(struct kvm *kvm,
if (!npages) {
new.rmap = NULL;
new.dirty_bitmap = NULL;
- for (i = 0; i < KVM_NR_PAGE_SIZES - 1; ++i)
- new.lpage_info[i] = NULL;
+ memset(&new.arch, 0, sizeof(new.arch));
}
update_memslots(slots, &new);
@@ -968,6 +911,11 @@ out:
return r;
}
+bool kvm_largepages_enabled(void)
+{
+ return largepages_enabled;
+}
+
void kvm_disable_largepages(void)
{
largepages_enabled = false;