diff options
-rw-r--r-- | arch/ia64/kvm/kvm-ia64.c | 10 | ||||
-rw-r--r-- | arch/powerpc/kvm/book3s.c | 2 | ||||
-rw-r--r-- | arch/x86/kvm/mmu.c | 11 | ||||
-rw-r--r-- | arch/x86/kvm/vmx.c | 4 | ||||
-rw-r--r-- | arch/x86/kvm/x86.c | 4 | ||||
-rw-r--r-- | include/linux/kvm_host.h | 12 | ||||
-rw-r--r-- | virt/kvm/iommu.c | 18 | ||||
-rw-r--r-- | virt/kvm/kvm_main.c | 36 |
8 files changed, 60 insertions, 37 deletions
diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c index 5fdeec5fddcf..1ca1dbf48117 100644 --- a/arch/ia64/kvm/kvm-ia64.c +++ b/arch/ia64/kvm/kvm-ia64.c | |||
@@ -1377,12 +1377,14 @@ static void free_kvm(struct kvm *kvm) | |||
1377 | 1377 | ||
1378 | static void kvm_release_vm_pages(struct kvm *kvm) | 1378 | static void kvm_release_vm_pages(struct kvm *kvm) |
1379 | { | 1379 | { |
1380 | struct kvm_memslots *slots; | ||
1380 | struct kvm_memory_slot *memslot; | 1381 | struct kvm_memory_slot *memslot; |
1381 | int i, j; | 1382 | int i, j; |
1382 | unsigned long base_gfn; | 1383 | unsigned long base_gfn; |
1383 | 1384 | ||
1384 | for (i = 0; i < kvm->nmemslots; i++) { | 1385 | slots = kvm->memslots; |
1385 | memslot = &kvm->memslots[i]; | 1386 | for (i = 0; i < slots->nmemslots; i++) { |
1387 | memslot = &slots->memslots[i]; | ||
1386 | base_gfn = memslot->base_gfn; | 1388 | base_gfn = memslot->base_gfn; |
1387 | 1389 | ||
1388 | for (j = 0; j < memslot->npages; j++) { | 1390 | for (j = 0; j < memslot->npages; j++) { |
@@ -1802,7 +1804,7 @@ static int kvm_ia64_sync_dirty_log(struct kvm *kvm, | |||
1802 | if (log->slot >= KVM_MEMORY_SLOTS) | 1804 | if (log->slot >= KVM_MEMORY_SLOTS) |
1803 | goto out; | 1805 | goto out; |
1804 | 1806 | ||
1805 | memslot = &kvm->memslots[log->slot]; | 1807 | memslot = &kvm->memslots->memslots[log->slot]; |
1806 | r = -ENOENT; | 1808 | r = -ENOENT; |
1807 | if (!memslot->dirty_bitmap) | 1809 | if (!memslot->dirty_bitmap) |
1808 | goto out; | 1810 | goto out; |
@@ -1840,7 +1842,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, | |||
1840 | /* If nothing is dirty, don't bother messing with page tables. */ | 1842 | /* If nothing is dirty, don't bother messing with page tables. */ |
1841 | if (is_dirty) { | 1843 | if (is_dirty) { |
1842 | kvm_flush_remote_tlbs(kvm); | 1844 | kvm_flush_remote_tlbs(kvm); |
1843 | memslot = &kvm->memslots[log->slot]; | 1845 | memslot = &kvm->memslots->memslots[log->slot]; |
1844 | n = ALIGN(memslot->npages, BITS_PER_LONG) / 8; | 1846 | n = ALIGN(memslot->npages, BITS_PER_LONG) / 8; |
1845 | memset(memslot->dirty_bitmap, 0, n); | 1847 | memset(memslot->dirty_bitmap, 0, n); |
1846 | } | 1848 | } |
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index 803505d3e455..bb8873dcb20f 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c | |||
@@ -865,7 +865,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, | |||
865 | 865 | ||
866 | /* If nothing is dirty, don't bother messing with page tables. */ | 866 | /* If nothing is dirty, don't bother messing with page tables. */ |
867 | if (is_dirty) { | 867 | if (is_dirty) { |
868 | memslot = &kvm->memslots[log->slot]; | 868 | memslot = &kvm->memslots->memslots[log->slot]; |
869 | 869 | ||
870 | ga = memslot->base_gfn << PAGE_SHIFT; | 870 | ga = memslot->base_gfn << PAGE_SHIFT; |
871 | ga_end = ga + (memslot->npages << PAGE_SHIFT); | 871 | ga_end = ga + (memslot->npages << PAGE_SHIFT); |
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 4f499d7f7106..81f84d326a84 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c | |||
@@ -807,13 +807,14 @@ static int kvm_handle_hva(struct kvm *kvm, unsigned long hva, | |||
807 | { | 807 | { |
808 | int i, j; | 808 | int i, j; |
809 | int retval = 0; | 809 | int retval = 0; |
810 | struct kvm_memslots *slots = kvm->memslots; | ||
810 | 811 | ||
811 | /* | 812 | /* |
812 | * If mmap_sem isn't taken, we can look the memslots with only | 813 | * If mmap_sem isn't taken, we can look the memslots with only |
813 | * the mmu_lock by skipping over the slots with userspace_addr == 0. | 814 | * the mmu_lock by skipping over the slots with userspace_addr == 0. |
814 | */ | 815 | */ |
815 | for (i = 0; i < kvm->nmemslots; i++) { | 816 | for (i = 0; i < slots->nmemslots; i++) { |
816 | struct kvm_memory_slot *memslot = &kvm->memslots[i]; | 817 | struct kvm_memory_slot *memslot = &slots->memslots[i]; |
817 | unsigned long start = memslot->userspace_addr; | 818 | unsigned long start = memslot->userspace_addr; |
818 | unsigned long end; | 819 | unsigned long end; |
819 | 820 | ||
@@ -3021,8 +3022,8 @@ unsigned int kvm_mmu_calculate_mmu_pages(struct kvm *kvm) | |||
3021 | unsigned int nr_mmu_pages; | 3022 | unsigned int nr_mmu_pages; |
3022 | unsigned int nr_pages = 0; | 3023 | unsigned int nr_pages = 0; |
3023 | 3024 | ||
3024 | for (i = 0; i < kvm->nmemslots; i++) | 3025 | for (i = 0; i < kvm->memslots->nmemslots; i++) |
3025 | nr_pages += kvm->memslots[i].npages; | 3026 | nr_pages += kvm->memslots->memslots[i].npages; |
3026 | 3027 | ||
3027 | nr_mmu_pages = nr_pages * KVM_PERMILLE_MMU_PAGES / 1000; | 3028 | nr_mmu_pages = nr_pages * KVM_PERMILLE_MMU_PAGES / 1000; |
3028 | nr_mmu_pages = max(nr_mmu_pages, | 3029 | nr_mmu_pages = max(nr_mmu_pages, |
@@ -3295,7 +3296,7 @@ static int count_rmaps(struct kvm_vcpu *vcpu) | |||
3295 | int i, j, k; | 3296 | int i, j, k; |
3296 | 3297 | ||
3297 | for (i = 0; i < KVM_MEMORY_SLOTS; ++i) { | 3298 | for (i = 0; i < KVM_MEMORY_SLOTS; ++i) { |
3298 | struct kvm_memory_slot *m = &vcpu->kvm->memslots[i]; | 3299 | struct kvm_memory_slot *m = &vcpu->kvm->memslots->memslots[i]; |
3299 | struct kvm_rmap_desc *d; | 3300 | struct kvm_rmap_desc *d; |
3300 | 3301 | ||
3301 | for (j = 0; j < m->npages; ++j) { | 3302 | for (j = 0; j < m->npages; ++j) { |
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 74a66f0c00b4..18698799e365 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -1503,8 +1503,8 @@ static void enter_pmode(struct kvm_vcpu *vcpu) | |||
1503 | static gva_t rmode_tss_base(struct kvm *kvm) | 1503 | static gva_t rmode_tss_base(struct kvm *kvm) |
1504 | { | 1504 | { |
1505 | if (!kvm->arch.tss_addr) { | 1505 | if (!kvm->arch.tss_addr) { |
1506 | gfn_t base_gfn = kvm->memslots[0].base_gfn + | 1506 | gfn_t base_gfn = kvm->memslots->memslots[0].base_gfn + |
1507 | kvm->memslots[0].npages - 3; | 1507 | kvm->memslots->memslots[0].npages - 3; |
1508 | return base_gfn << PAGE_SHIFT; | 1508 | return base_gfn << PAGE_SHIFT; |
1509 | } | 1509 | } |
1510 | return kvm->arch.tss_addr; | 1510 | return kvm->arch.tss_addr; |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 8798504ace11..3b81cb9da8b8 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -2427,7 +2427,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, | |||
2427 | spin_lock(&kvm->mmu_lock); | 2427 | spin_lock(&kvm->mmu_lock); |
2428 | kvm_mmu_slot_remove_write_access(kvm, log->slot); | 2428 | kvm_mmu_slot_remove_write_access(kvm, log->slot); |
2429 | spin_unlock(&kvm->mmu_lock); | 2429 | spin_unlock(&kvm->mmu_lock); |
2430 | memslot = &kvm->memslots[log->slot]; | 2430 | memslot = &kvm->memslots->memslots[log->slot]; |
2431 | n = ALIGN(memslot->npages, BITS_PER_LONG) / 8; | 2431 | n = ALIGN(memslot->npages, BITS_PER_LONG) / 8; |
2432 | memset(memslot->dirty_bitmap, 0, n); | 2432 | memset(memslot->dirty_bitmap, 0, n); |
2433 | } | 2433 | } |
@@ -5223,7 +5223,7 @@ int kvm_arch_set_memory_region(struct kvm *kvm, | |||
5223 | int user_alloc) | 5223 | int user_alloc) |
5224 | { | 5224 | { |
5225 | int npages = mem->memory_size >> PAGE_SHIFT; | 5225 | int npages = mem->memory_size >> PAGE_SHIFT; |
5226 | struct kvm_memory_slot *memslot = &kvm->memslots[mem->slot]; | 5226 | struct kvm_memory_slot *memslot = &kvm->memslots->memslots[mem->slot]; |
5227 | 5227 | ||
5228 | /*To keep backward compatibility with older userspace, | 5228 | /*To keep backward compatibility with older userspace, |
5229 | *x86 needs to hanlde !user_alloc case. | 5229 | *x86 needs to hanlde !user_alloc case. |
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index bd5a616d9373..782bfb185f8a 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h | |||
@@ -150,14 +150,18 @@ struct kvm_irq_routing_table {}; | |||
150 | 150 | ||
151 | #endif | 151 | #endif |
152 | 152 | ||
153 | struct kvm_memslots { | ||
154 | int nmemslots; | ||
155 | struct kvm_memory_slot memslots[KVM_MEMORY_SLOTS + | ||
156 | KVM_PRIVATE_MEM_SLOTS]; | ||
157 | }; | ||
158 | |||
153 | struct kvm { | 159 | struct kvm { |
154 | spinlock_t mmu_lock; | 160 | spinlock_t mmu_lock; |
155 | spinlock_t requests_lock; | 161 | spinlock_t requests_lock; |
156 | struct rw_semaphore slots_lock; | 162 | struct rw_semaphore slots_lock; |
157 | struct mm_struct *mm; /* userspace tied to this vm */ | 163 | struct mm_struct *mm; /* userspace tied to this vm */ |
158 | int nmemslots; | 164 | struct kvm_memslots *memslots; |
159 | struct kvm_memory_slot memslots[KVM_MEMORY_SLOTS + | ||
160 | KVM_PRIVATE_MEM_SLOTS]; | ||
161 | #ifdef CONFIG_KVM_APIC_ARCHITECTURE | 165 | #ifdef CONFIG_KVM_APIC_ARCHITECTURE |
162 | u32 bsp_vcpu_id; | 166 | u32 bsp_vcpu_id; |
163 | struct kvm_vcpu *bsp_vcpu; | 167 | struct kvm_vcpu *bsp_vcpu; |
@@ -482,7 +486,7 @@ static inline void kvm_guest_exit(void) | |||
482 | 486 | ||
483 | static inline int memslot_id(struct kvm *kvm, struct kvm_memory_slot *slot) | 487 | static inline int memslot_id(struct kvm *kvm, struct kvm_memory_slot *slot) |
484 | { | 488 | { |
485 | return slot - kvm->memslots; | 489 | return slot - kvm->memslots->memslots; |
486 | } | 490 | } |
487 | 491 | ||
488 | static inline gpa_t gfn_to_gpa(gfn_t gfn) | 492 | static inline gpa_t gfn_to_gpa(gfn_t gfn) |
diff --git a/virt/kvm/iommu.c b/virt/kvm/iommu.c index 15147583abd1..bc697a66a883 100644 --- a/virt/kvm/iommu.c +++ b/virt/kvm/iommu.c | |||
@@ -76,10 +76,13 @@ unmap_pages: | |||
76 | static int kvm_iommu_map_memslots(struct kvm *kvm) | 76 | static int kvm_iommu_map_memslots(struct kvm *kvm) |
77 | { | 77 | { |
78 | int i, r = 0; | 78 | int i, r = 0; |
79 | struct kvm_memslots *slots; | ||
79 | 80 | ||
80 | for (i = 0; i < kvm->nmemslots; i++) { | 81 | slots = kvm->memslots; |
81 | r = kvm_iommu_map_pages(kvm, kvm->memslots[i].base_gfn, | 82 | |
82 | kvm->memslots[i].npages); | 83 | for (i = 0; i < slots->nmemslots; i++) { |
84 | r = kvm_iommu_map_pages(kvm, slots->memslots[i].base_gfn, | ||
85 | slots->memslots[i].npages); | ||
83 | if (r) | 86 | if (r) |
84 | break; | 87 | break; |
85 | } | 88 | } |
@@ -210,10 +213,13 @@ static void kvm_iommu_put_pages(struct kvm *kvm, | |||
210 | static int kvm_iommu_unmap_memslots(struct kvm *kvm) | 213 | static int kvm_iommu_unmap_memslots(struct kvm *kvm) |
211 | { | 214 | { |
212 | int i; | 215 | int i; |
216 | struct kvm_memslots *slots; | ||
217 | |||
218 | slots = kvm->memslots; | ||
213 | 219 | ||
214 | for (i = 0; i < kvm->nmemslots; i++) { | 220 | for (i = 0; i < slots->nmemslots; i++) { |
215 | kvm_iommu_put_pages(kvm, kvm->memslots[i].base_gfn, | 221 | kvm_iommu_put_pages(kvm, slots->memslots[i].base_gfn, |
216 | kvm->memslots[i].npages); | 222 | slots->memslots[i].npages); |
217 | } | 223 | } |
218 | 224 | ||
219 | return 0; | 225 | return 0; |
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index bc23b8e0609b..86dd8f3d29c9 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c | |||
@@ -375,12 +375,16 @@ static struct kvm *kvm_create_vm(void) | |||
375 | INIT_HLIST_HEAD(&kvm->irq_ack_notifier_list); | 375 | INIT_HLIST_HEAD(&kvm->irq_ack_notifier_list); |
376 | #endif | 376 | #endif |
377 | 377 | ||
378 | r = -ENOMEM; | ||
379 | kvm->memslots = kzalloc(sizeof(struct kvm_memslots), GFP_KERNEL); | ||
380 | if (!kvm->memslots) | ||
381 | goto out_err; | ||
382 | |||
378 | #ifdef KVM_COALESCED_MMIO_PAGE_OFFSET | 383 | #ifdef KVM_COALESCED_MMIO_PAGE_OFFSET |
379 | page = alloc_page(GFP_KERNEL | __GFP_ZERO); | 384 | page = alloc_page(GFP_KERNEL | __GFP_ZERO); |
380 | if (!page) { | 385 | if (!page) |
381 | r = -ENOMEM; | ||
382 | goto out_err; | 386 | goto out_err; |
383 | } | 387 | |
384 | kvm->coalesced_mmio_ring = | 388 | kvm->coalesced_mmio_ring = |
385 | (struct kvm_coalesced_mmio_ring *)page_address(page); | 389 | (struct kvm_coalesced_mmio_ring *)page_address(page); |
386 | #endif | 390 | #endif |
@@ -416,6 +420,7 @@ out: | |||
416 | out_err: | 420 | out_err: |
417 | hardware_disable_all(); | 421 | hardware_disable_all(); |
418 | out_err_nodisable: | 422 | out_err_nodisable: |
423 | kfree(kvm->memslots); | ||
419 | kfree(kvm); | 424 | kfree(kvm); |
420 | return ERR_PTR(r); | 425 | return ERR_PTR(r); |
421 | } | 426 | } |
@@ -450,9 +455,12 @@ static void kvm_free_physmem_slot(struct kvm_memory_slot *free, | |||
450 | void kvm_free_physmem(struct kvm *kvm) | 455 | void kvm_free_physmem(struct kvm *kvm) |
451 | { | 456 | { |
452 | int i; | 457 | int i; |
458 | struct kvm_memslots *slots = kvm->memslots; | ||
459 | |||
460 | for (i = 0; i < slots->nmemslots; ++i) | ||
461 | kvm_free_physmem_slot(&slots->memslots[i], NULL); | ||
453 | 462 | ||
454 | for (i = 0; i < kvm->nmemslots; ++i) | 463 | kfree(kvm->memslots); |
455 | kvm_free_physmem_slot(&kvm->memslots[i], NULL); | ||
456 | } | 464 | } |
457 | 465 | ||
458 | static void kvm_destroy_vm(struct kvm *kvm) | 466 | static void kvm_destroy_vm(struct kvm *kvm) |
@@ -533,7 +541,7 @@ int __kvm_set_memory_region(struct kvm *kvm, | |||
533 | if (mem->guest_phys_addr + mem->memory_size < mem->guest_phys_addr) | 541 | if (mem->guest_phys_addr + mem->memory_size < mem->guest_phys_addr) |
534 | goto out; | 542 | goto out; |
535 | 543 | ||
536 | memslot = &kvm->memslots[mem->slot]; | 544 | memslot = &kvm->memslots->memslots[mem->slot]; |
537 | base_gfn = mem->guest_phys_addr >> PAGE_SHIFT; | 545 | base_gfn = mem->guest_phys_addr >> PAGE_SHIFT; |
538 | npages = mem->memory_size >> PAGE_SHIFT; | 546 | npages = mem->memory_size >> PAGE_SHIFT; |
539 | 547 | ||
@@ -554,7 +562,7 @@ int __kvm_set_memory_region(struct kvm *kvm, | |||
554 | /* Check for overlaps */ | 562 | /* Check for overlaps */ |
555 | r = -EEXIST; | 563 | r = -EEXIST; |
556 | for (i = 0; i < KVM_MEMORY_SLOTS; ++i) { | 564 | for (i = 0; i < KVM_MEMORY_SLOTS; ++i) { |
557 | struct kvm_memory_slot *s = &kvm->memslots[i]; | 565 | struct kvm_memory_slot *s = &kvm->memslots->memslots[i]; |
558 | 566 | ||
559 | if (s == memslot || !s->npages) | 567 | if (s == memslot || !s->npages) |
560 | continue; | 568 | continue; |
@@ -656,8 +664,8 @@ skip_lpage: | |||
656 | kvm_arch_flush_shadow(kvm); | 664 | kvm_arch_flush_shadow(kvm); |
657 | 665 | ||
658 | spin_lock(&kvm->mmu_lock); | 666 | spin_lock(&kvm->mmu_lock); |
659 | if (mem->slot >= kvm->nmemslots) | 667 | if (mem->slot >= kvm->memslots->nmemslots) |
660 | kvm->nmemslots = mem->slot + 1; | 668 | kvm->memslots->nmemslots = mem->slot + 1; |
661 | 669 | ||
662 | *memslot = new; | 670 | *memslot = new; |
663 | spin_unlock(&kvm->mmu_lock); | 671 | spin_unlock(&kvm->mmu_lock); |
@@ -727,7 +735,7 @@ int kvm_get_dirty_log(struct kvm *kvm, | |||
727 | if (log->slot >= KVM_MEMORY_SLOTS) | 735 | if (log->slot >= KVM_MEMORY_SLOTS) |
728 | goto out; | 736 | goto out; |
729 | 737 | ||
730 | memslot = &kvm->memslots[log->slot]; | 738 | memslot = &kvm->memslots->memslots[log->slot]; |
731 | r = -ENOENT; | 739 | r = -ENOENT; |
732 | if (!memslot->dirty_bitmap) | 740 | if (!memslot->dirty_bitmap) |
733 | goto out; | 741 | goto out; |
@@ -781,9 +789,10 @@ EXPORT_SYMBOL_GPL(kvm_is_error_hva); | |||
781 | struct kvm_memory_slot *gfn_to_memslot_unaliased(struct kvm *kvm, gfn_t gfn) | 789 | struct kvm_memory_slot *gfn_to_memslot_unaliased(struct kvm *kvm, gfn_t gfn) |
782 | { | 790 | { |
783 | int i; | 791 | int i; |
792 | struct kvm_memslots *slots = kvm->memslots; | ||
784 | 793 | ||
785 | for (i = 0; i < kvm->nmemslots; ++i) { | 794 | for (i = 0; i < slots->nmemslots; ++i) { |
786 | struct kvm_memory_slot *memslot = &kvm->memslots[i]; | 795 | struct kvm_memory_slot *memslot = &slots->memslots[i]; |
787 | 796 | ||
788 | if (gfn >= memslot->base_gfn | 797 | if (gfn >= memslot->base_gfn |
789 | && gfn < memslot->base_gfn + memslot->npages) | 798 | && gfn < memslot->base_gfn + memslot->npages) |
@@ -802,10 +811,11 @@ struct kvm_memory_slot *gfn_to_memslot(struct kvm *kvm, gfn_t gfn) | |||
802 | int kvm_is_visible_gfn(struct kvm *kvm, gfn_t gfn) | 811 | int kvm_is_visible_gfn(struct kvm *kvm, gfn_t gfn) |
803 | { | 812 | { |
804 | int i; | 813 | int i; |
814 | struct kvm_memslots *slots = kvm->memslots; | ||
805 | 815 | ||
806 | gfn = unalias_gfn(kvm, gfn); | 816 | gfn = unalias_gfn(kvm, gfn); |
807 | for (i = 0; i < KVM_MEMORY_SLOTS; ++i) { | 817 | for (i = 0; i < KVM_MEMORY_SLOTS; ++i) { |
808 | struct kvm_memory_slot *memslot = &kvm->memslots[i]; | 818 | struct kvm_memory_slot *memslot = &slots->memslots[i]; |
809 | 819 | ||
810 | if (gfn >= memslot->base_gfn | 820 | if (gfn >= memslot->base_gfn |
811 | && gfn < memslot->base_gfn + memslot->npages) | 821 | && gfn < memslot->base_gfn + memslot->npages) |