|
@@ -6303,14 +6303,18 @@ 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;
|
|
|
+ for (i = 0; i < KVM_NR_PAGE_SIZES; ++i) {
|
|
|
+ if (!dont || free->arch.rmap[i] != dont->arch.rmap[i]) {
|
|
|
+ kvm_kvfree(free->arch.rmap[i]);
|
|
|
+ free->arch.rmap[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;
|
|
|
+ if (i == 0)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ if (!dont || free->arch.lpage_info[i - 1] !=
|
|
|
+ dont->arch.lpage_info[i - 1]) {
|
|
|
+ kvm_kvfree(free->arch.lpage_info[i - 1]);
|
|
|
+ free->arch.lpage_info[i - 1] = NULL;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -6319,28 +6323,30 @@ int kvm_arch_create_memslot(struct kvm_memory_slot *slot, unsigned long npages)
|
|
|
{
|
|
|
int i;
|
|
|
|
|
|
- for (i = 0; i < KVM_NR_PAGE_SIZES - 1; ++i) {
|
|
|
+ for (i = 0; i < KVM_NR_PAGE_SIZES; ++i) {
|
|
|
unsigned long ugfn;
|
|
|
int lpages;
|
|
|
- int level = i + 2;
|
|
|
+ int level = i + 1;
|
|
|
|
|
|
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])
|
|
|
+ slot->arch.rmap[i] =
|
|
|
+ kvm_kvzalloc(lpages * sizeof(*slot->arch.rmap[i]));
|
|
|
+ if (!slot->arch.rmap[i])
|
|
|
goto out_free;
|
|
|
+ if (i == 0)
|
|
|
+ continue;
|
|
|
|
|
|
- slot->arch.lpage_info[i] =
|
|
|
- kvm_kvzalloc(lpages * sizeof(*slot->arch.lpage_info[i]));
|
|
|
- if (!slot->arch.lpage_info[i])
|
|
|
+ slot->arch.lpage_info[i - 1] = kvm_kvzalloc(lpages *
|
|
|
+ sizeof(*slot->arch.lpage_info[i - 1]));
|
|
|
+ if (!slot->arch.lpage_info[i - 1])
|
|
|
goto out_free;
|
|
|
|
|
|
if (slot->base_gfn & (KVM_PAGES_PER_HPAGE(level) - 1))
|
|
|
- slot->arch.lpage_info[i][0].write_count = 1;
|
|
|
+ slot->arch.lpage_info[i - 1][0].write_count = 1;
|
|
|
if ((slot->base_gfn + npages) & (KVM_PAGES_PER_HPAGE(level) - 1))
|
|
|
- slot->arch.lpage_info[i][lpages - 1].write_count = 1;
|
|
|
+ slot->arch.lpage_info[i - 1][lpages - 1].write_count = 1;
|
|
|
ugfn = slot->userspace_addr >> PAGE_SHIFT;
|
|
|
/*
|
|
|
* If the gfn and userspace address are not aligned wrt each
|
|
@@ -6352,18 +6358,21 @@ int kvm_arch_create_memslot(struct kvm_memory_slot *slot, unsigned long npages)
|
|
|
unsigned long j;
|
|
|
|
|
|
for (j = 0; j < lpages; ++j)
|
|
|
- slot->arch.lpage_info[i][j].write_count = 1;
|
|
|
+ slot->arch.lpage_info[i - 1][j].write_count = 1;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
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;
|
|
|
+ for (i = 0; i < KVM_NR_PAGE_SIZES; ++i) {
|
|
|
+ kvm_kvfree(slot->arch.rmap[i]);
|
|
|
+ slot->arch.rmap[i] = NULL;
|
|
|
+ if (i == 0)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ kvm_kvfree(slot->arch.lpage_info[i - 1]);
|
|
|
+ slot->arch.lpage_info[i - 1] = NULL;
|
|
|
}
|
|
|
return -ENOMEM;
|
|
|
}
|