aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/include/asm/kvm_host.h2
-rw-r--r--arch/x86/kvm/mmu.c5
-rw-r--r--arch/x86/kvm/x86.c55
3 files changed, 34 insertions, 28 deletions
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 48e713188469..1309e69b57fa 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -504,7 +504,7 @@ struct kvm_lpage_info {
504}; 504};
505 505
506struct kvm_arch_memory_slot { 506struct kvm_arch_memory_slot {
507 unsigned long *rmap_pde[KVM_NR_PAGE_SIZES - 1]; 507 unsigned long *rmap[KVM_NR_PAGE_SIZES];
508 struct kvm_lpage_info *lpage_info[KVM_NR_PAGE_SIZES - 1]; 508 struct kvm_lpage_info *lpage_info[KVM_NR_PAGE_SIZES - 1];
509}; 509};
510 510
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index ee768bb2367f..aa9a987ddefb 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -970,11 +970,8 @@ static unsigned long *__gfn_to_rmap(gfn_t gfn, int level,
970{ 970{
971 unsigned long idx; 971 unsigned long idx;
972 972
973 if (likely(level == PT_PAGE_TABLE_LEVEL))
974 return &slot->rmap[gfn - slot->base_gfn];
975
976 idx = gfn_to_index(gfn, slot->base_gfn, level); 973 idx = gfn_to_index(gfn, slot->base_gfn, level);
977 return &slot->arch.rmap_pde[level - PT_DIRECTORY_LEVEL][idx]; 974 return &slot->arch.rmap[level - PT_PAGE_TABLE_LEVEL][idx];
978} 975}
979 976
980/* 977/*
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}