aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/x86.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kvm/x86.c')
-rw-r--r--arch/x86/kvm/x86.c55
1 files changed, 32 insertions, 23 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index abc039d78428..ebf2109318e0 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -6303,14 +6303,18 @@ void kvm_arch_free_memslot(struct kvm_memory_slot *free,
6303{ 6303{
6304 int i; 6304 int i;
6305 6305
6306 for (i = 0; i < KVM_NR_PAGE_SIZES - 1; ++i) { 6306 for (i = 0; i < KVM_NR_PAGE_SIZES; ++i) {
6307 if (!dont || free->arch.rmap_pde[i] != dont->arch.rmap_pde[i]) { 6307 if (!dont || free->arch.rmap[i] != dont->arch.rmap[i]) {
6308 kvm_kvfree(free->arch.rmap_pde[i]); 6308 kvm_kvfree(free->arch.rmap[i]);
6309 free->arch.rmap_pde[i] = NULL; 6309 free->arch.rmap[i] = NULL;
6310 } 6310 }
6311 if (!dont || free->arch.lpage_info[i] != dont->arch.lpage_info[i]) { 6311 if (i == 0)
6312 kvm_kvfree(free->arch.lpage_info[i]); 6312 continue;
6313 free->arch.lpage_info[i] = NULL; 6313
6314 if (!dont || free->arch.lpage_info[i - 1] !=
6315 dont->arch.lpage_info[i - 1]) {
6316 kvm_kvfree(free->arch.lpage_info[i - 1]);
6317 free->arch.lpage_info[i - 1] = NULL;
6314 } 6318 }
6315 } 6319 }
6316} 6320}
@@ -6319,28 +6323,30 @@ int kvm_arch_create_memslot(struct kvm_memory_slot *slot, unsigned long npages)
6319{ 6323{
6320 int i; 6324 int i;
6321 6325
6322 for (i = 0; i < KVM_NR_PAGE_SIZES - 1; ++i) { 6326 for (i = 0; i < KVM_NR_PAGE_SIZES; ++i) {
6323 unsigned long ugfn; 6327 unsigned long ugfn;
6324 int lpages; 6328 int lpages;
6325 int level = i + 2; 6329 int level = i + 1;
6326 6330
6327 lpages = gfn_to_index(slot->base_gfn + npages - 1, 6331 lpages = gfn_to_index(slot->base_gfn + npages - 1,
6328 slot->base_gfn, level) + 1; 6332 slot->base_gfn, level) + 1;
6329 6333
6330 slot->arch.rmap_pde[i] = 6334 slot->arch.rmap[i] =
6331 kvm_kvzalloc(lpages * sizeof(*slot->arch.rmap_pde[i])); 6335 kvm_kvzalloc(lpages * sizeof(*slot->arch.rmap[i]));
6332 if (!slot->arch.rmap_pde[i]) 6336 if (!slot->arch.rmap[i])
6333 goto out_free; 6337 goto out_free;
6338 if (i == 0)
6339 continue;
6334 6340
6335 slot->arch.lpage_info[i] = 6341 slot->arch.lpage_info[i - 1] = kvm_kvzalloc(lpages *
6336 kvm_kvzalloc(lpages * sizeof(*slot->arch.lpage_info[i])); 6342 sizeof(*slot->arch.lpage_info[i - 1]));
6337 if (!slot->arch.lpage_info[i]) 6343 if (!slot->arch.lpage_info[i - 1])
6338 goto out_free; 6344 goto out_free;
6339 6345
6340 if (slot->base_gfn & (KVM_PAGES_PER_HPAGE(level) - 1)) 6346 if (slot->base_gfn & (KVM_PAGES_PER_HPAGE(level) - 1))
6341 slot->arch.lpage_info[i][0].write_count = 1; 6347 slot->arch.lpage_info[i - 1][0].write_count = 1;
6342 if ((slot->base_gfn + npages) & (KVM_PAGES_PER_HPAGE(level) - 1)) 6348 if ((slot->base_gfn + npages) & (KVM_PAGES_PER_HPAGE(level) - 1))
6343 slot->arch.lpage_info[i][lpages - 1].write_count = 1; 6349 slot->arch.lpage_info[i - 1][lpages - 1].write_count = 1;
6344 ugfn = slot->userspace_addr >> PAGE_SHIFT; 6350 ugfn = slot->userspace_addr >> PAGE_SHIFT;
6345 /* 6351 /*
6346 * If the gfn and userspace address are not aligned wrt each 6352 * 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)
6352 unsigned long j; 6358 unsigned long j;
6353 6359
6354 for (j = 0; j < lpages; ++j) 6360 for (j = 0; j < lpages; ++j)
6355 slot->arch.lpage_info[i][j].write_count = 1; 6361 slot->arch.lpage_info[i - 1][j].write_count = 1;
6356 } 6362 }
6357 } 6363 }
6358 6364
6359 return 0; 6365 return 0;
6360 6366
6361out_free: 6367out_free:
6362 for (i = 0; i < KVM_NR_PAGE_SIZES - 1; ++i) { 6368 for (i = 0; i < KVM_NR_PAGE_SIZES; ++i) {
6363 kvm_kvfree(slot->arch.rmap_pde[i]); 6369 kvm_kvfree(slot->arch.rmap[i]);
6364 kvm_kvfree(slot->arch.lpage_info[i]); 6370 slot->arch.rmap[i] = NULL;
6365 slot->arch.rmap_pde[i] = NULL; 6371 if (i == 0)
6366 slot->arch.lpage_info[i] = NULL; 6372 continue;
6373
6374 kvm_kvfree(slot->arch.lpage_info[i - 1]);
6375 slot->arch.lpage_info[i - 1] = NULL;
6367 } 6376 }
6368 return -ENOMEM; 6377 return -ENOMEM;
6369} 6378}