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>
This commit is contained in:

committed by
Avi Kivity

parent
189a2f7b24
commit
db3fe4eb45
@@ -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;
|
||||
|
Reference in New Issue
Block a user