diff options
Diffstat (limited to 'arch/x86/kvm/x86.c')
-rw-r--r-- | arch/x86/kvm/x86.c | 55 |
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 | ||
6361 | out_free: | 6367 | out_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 | } |