diff options
Diffstat (limited to 'drivers/kvm/mmu.c')
| -rw-r--r-- | drivers/kvm/mmu.c | 154 |
1 files changed, 112 insertions, 42 deletions
diff --git a/drivers/kvm/mmu.c b/drivers/kvm/mmu.c index cab26f301eab..e8e228118de9 100644 --- a/drivers/kvm/mmu.c +++ b/drivers/kvm/mmu.c | |||
| @@ -52,11 +52,15 @@ static void kvm_mmu_audit(struct kvm_vcpu *vcpu, const char *msg) {} | |||
| 52 | static int dbg = 1; | 52 | static int dbg = 1; |
| 53 | #endif | 53 | #endif |
| 54 | 54 | ||
| 55 | #ifndef MMU_DEBUG | ||
| 56 | #define ASSERT(x) do { } while (0) | ||
| 57 | #else | ||
| 55 | #define ASSERT(x) \ | 58 | #define ASSERT(x) \ |
| 56 | if (!(x)) { \ | 59 | if (!(x)) { \ |
| 57 | printk(KERN_WARNING "assertion failed %s:%d: %s\n", \ | 60 | printk(KERN_WARNING "assertion failed %s:%d: %s\n", \ |
| 58 | __FILE__, __LINE__, #x); \ | 61 | __FILE__, __LINE__, #x); \ |
| 59 | } | 62 | } |
| 63 | #endif | ||
| 60 | 64 | ||
| 61 | #define PT64_PT_BITS 9 | 65 | #define PT64_PT_BITS 9 |
| 62 | #define PT64_ENT_PER_PAGE (1 << PT64_PT_BITS) | 66 | #define PT64_ENT_PER_PAGE (1 << PT64_PT_BITS) |
| @@ -159,6 +163,9 @@ struct kvm_rmap_desc { | |||
| 159 | struct kvm_rmap_desc *more; | 163 | struct kvm_rmap_desc *more; |
| 160 | }; | 164 | }; |
| 161 | 165 | ||
| 166 | static struct kmem_cache *pte_chain_cache; | ||
| 167 | static struct kmem_cache *rmap_desc_cache; | ||
| 168 | |||
| 162 | static int is_write_protection(struct kvm_vcpu *vcpu) | 169 | static int is_write_protection(struct kvm_vcpu *vcpu) |
| 163 | { | 170 | { |
| 164 | return vcpu->cr0 & CR0_WP_MASK; | 171 | return vcpu->cr0 & CR0_WP_MASK; |
| @@ -196,14 +203,15 @@ static int is_rmap_pte(u64 pte) | |||
| 196 | } | 203 | } |
| 197 | 204 | ||
| 198 | static int mmu_topup_memory_cache(struct kvm_mmu_memory_cache *cache, | 205 | static int mmu_topup_memory_cache(struct kvm_mmu_memory_cache *cache, |
| 199 | size_t objsize, int min) | 206 | struct kmem_cache *base_cache, int min, |
| 207 | gfp_t gfp_flags) | ||
| 200 | { | 208 | { |
| 201 | void *obj; | 209 | void *obj; |
| 202 | 210 | ||
| 203 | if (cache->nobjs >= min) | 211 | if (cache->nobjs >= min) |
| 204 | return 0; | 212 | return 0; |
| 205 | while (cache->nobjs < ARRAY_SIZE(cache->objects)) { | 213 | while (cache->nobjs < ARRAY_SIZE(cache->objects)) { |
| 206 | obj = kzalloc(objsize, GFP_NOWAIT); | 214 | obj = kmem_cache_zalloc(base_cache, gfp_flags); |
| 207 | if (!obj) | 215 | if (!obj) |
| 208 | return -ENOMEM; | 216 | return -ENOMEM; |
| 209 | cache->objects[cache->nobjs++] = obj; | 217 | cache->objects[cache->nobjs++] = obj; |
| @@ -217,20 +225,35 @@ static void mmu_free_memory_cache(struct kvm_mmu_memory_cache *mc) | |||
| 217 | kfree(mc->objects[--mc->nobjs]); | 225 | kfree(mc->objects[--mc->nobjs]); |
| 218 | } | 226 | } |
| 219 | 227 | ||
| 220 | static int mmu_topup_memory_caches(struct kvm_vcpu *vcpu) | 228 | static int __mmu_topup_memory_caches(struct kvm_vcpu *vcpu, gfp_t gfp_flags) |
| 221 | { | 229 | { |
| 222 | int r; | 230 | int r; |
| 223 | 231 | ||
| 224 | r = mmu_topup_memory_cache(&vcpu->mmu_pte_chain_cache, | 232 | r = mmu_topup_memory_cache(&vcpu->mmu_pte_chain_cache, |
| 225 | sizeof(struct kvm_pte_chain), 4); | 233 | pte_chain_cache, 4, gfp_flags); |
| 226 | if (r) | 234 | if (r) |
| 227 | goto out; | 235 | goto out; |
| 228 | r = mmu_topup_memory_cache(&vcpu->mmu_rmap_desc_cache, | 236 | r = mmu_topup_memory_cache(&vcpu->mmu_rmap_desc_cache, |
| 229 | sizeof(struct kvm_rmap_desc), 1); | 237 | rmap_desc_cache, 1, gfp_flags); |
| 230 | out: | 238 | out: |
| 231 | return r; | 239 | return r; |
| 232 | } | 240 | } |
| 233 | 241 | ||
| 242 | static int mmu_topup_memory_caches(struct kvm_vcpu *vcpu) | ||
| 243 | { | ||
| 244 | int r; | ||
| 245 | |||
| 246 | r = __mmu_topup_memory_caches(vcpu, GFP_NOWAIT); | ||
| 247 | if (r < 0) { | ||
| 248 | spin_unlock(&vcpu->kvm->lock); | ||
| 249 | kvm_arch_ops->vcpu_put(vcpu); | ||
| 250 | r = __mmu_topup_memory_caches(vcpu, GFP_KERNEL); | ||
| 251 | kvm_arch_ops->vcpu_load(vcpu); | ||
| 252 | spin_lock(&vcpu->kvm->lock); | ||
| 253 | } | ||
| 254 | return r; | ||
| 255 | } | ||
| 256 | |||
| 234 | static void mmu_free_memory_caches(struct kvm_vcpu *vcpu) | 257 | static void mmu_free_memory_caches(struct kvm_vcpu *vcpu) |
| 235 | { | 258 | { |
| 236 | mmu_free_memory_cache(&vcpu->mmu_pte_chain_cache); | 259 | mmu_free_memory_cache(&vcpu->mmu_pte_chain_cache); |
| @@ -390,13 +413,11 @@ static void rmap_write_protect(struct kvm_vcpu *vcpu, u64 gfn) | |||
| 390 | { | 413 | { |
| 391 | struct kvm *kvm = vcpu->kvm; | 414 | struct kvm *kvm = vcpu->kvm; |
| 392 | struct page *page; | 415 | struct page *page; |
| 393 | struct kvm_memory_slot *slot; | ||
| 394 | struct kvm_rmap_desc *desc; | 416 | struct kvm_rmap_desc *desc; |
| 395 | u64 *spte; | 417 | u64 *spte; |
| 396 | 418 | ||
| 397 | slot = gfn_to_memslot(kvm, gfn); | 419 | page = gfn_to_page(kvm, gfn); |
| 398 | BUG_ON(!slot); | 420 | BUG_ON(!page); |
| 399 | page = gfn_to_page(slot, gfn); | ||
| 400 | 421 | ||
| 401 | while (page_private(page)) { | 422 | while (page_private(page)) { |
| 402 | if (!(page_private(page) & 1)) | 423 | if (!(page_private(page) & 1)) |
| @@ -417,6 +438,7 @@ static void rmap_write_protect(struct kvm_vcpu *vcpu, u64 gfn) | |||
| 417 | } | 438 | } |
| 418 | } | 439 | } |
| 419 | 440 | ||
| 441 | #ifdef MMU_DEBUG | ||
| 420 | static int is_empty_shadow_page(hpa_t page_hpa) | 442 | static int is_empty_shadow_page(hpa_t page_hpa) |
| 421 | { | 443 | { |
| 422 | u64 *pos; | 444 | u64 *pos; |
| @@ -431,15 +453,15 @@ static int is_empty_shadow_page(hpa_t page_hpa) | |||
| 431 | } | 453 | } |
| 432 | return 1; | 454 | return 1; |
| 433 | } | 455 | } |
| 456 | #endif | ||
| 434 | 457 | ||
| 435 | static void kvm_mmu_free_page(struct kvm_vcpu *vcpu, hpa_t page_hpa) | 458 | static void kvm_mmu_free_page(struct kvm_vcpu *vcpu, hpa_t page_hpa) |
| 436 | { | 459 | { |
| 437 | struct kvm_mmu_page *page_head = page_header(page_hpa); | 460 | struct kvm_mmu_page *page_head = page_header(page_hpa); |
| 438 | 461 | ||
| 439 | ASSERT(is_empty_shadow_page(page_hpa)); | 462 | ASSERT(is_empty_shadow_page(page_hpa)); |
| 440 | list_del(&page_head->link); | ||
| 441 | page_head->page_hpa = page_hpa; | 463 | page_head->page_hpa = page_hpa; |
| 442 | list_add(&page_head->link, &vcpu->free_pages); | 464 | list_move(&page_head->link, &vcpu->free_pages); |
| 443 | ++vcpu->kvm->n_free_mmu_pages; | 465 | ++vcpu->kvm->n_free_mmu_pages; |
| 444 | } | 466 | } |
| 445 | 467 | ||
| @@ -457,11 +479,9 @@ static struct kvm_mmu_page *kvm_mmu_alloc_page(struct kvm_vcpu *vcpu, | |||
| 457 | return NULL; | 479 | return NULL; |
| 458 | 480 | ||
| 459 | page = list_entry(vcpu->free_pages.next, struct kvm_mmu_page, link); | 481 | page = list_entry(vcpu->free_pages.next, struct kvm_mmu_page, link); |
| 460 | list_del(&page->link); | 482 | list_move(&page->link, &vcpu->kvm->active_mmu_pages); |
| 461 | list_add(&page->link, &vcpu->kvm->active_mmu_pages); | ||
| 462 | ASSERT(is_empty_shadow_page(page->page_hpa)); | 483 | ASSERT(is_empty_shadow_page(page->page_hpa)); |
| 463 | page->slot_bitmap = 0; | 484 | page->slot_bitmap = 0; |
| 464 | page->global = 1; | ||
| 465 | page->multimapped = 0; | 485 | page->multimapped = 0; |
| 466 | page->parent_pte = parent_pte; | 486 | page->parent_pte = parent_pte; |
| 467 | --vcpu->kvm->n_free_mmu_pages; | 487 | --vcpu->kvm->n_free_mmu_pages; |
| @@ -569,6 +589,7 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu, | |||
| 569 | gva_t gaddr, | 589 | gva_t gaddr, |
| 570 | unsigned level, | 590 | unsigned level, |
| 571 | int metaphysical, | 591 | int metaphysical, |
| 592 | unsigned hugepage_access, | ||
| 572 | u64 *parent_pte) | 593 | u64 *parent_pte) |
| 573 | { | 594 | { |
| 574 | union kvm_mmu_page_role role; | 595 | union kvm_mmu_page_role role; |
| @@ -582,6 +603,7 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu, | |||
| 582 | role.glevels = vcpu->mmu.root_level; | 603 | role.glevels = vcpu->mmu.root_level; |
| 583 | role.level = level; | 604 | role.level = level; |
| 584 | role.metaphysical = metaphysical; | 605 | role.metaphysical = metaphysical; |
| 606 | role.hugepage_access = hugepage_access; | ||
| 585 | if (vcpu->mmu.root_level <= PT32_ROOT_LEVEL) { | 607 | if (vcpu->mmu.root_level <= PT32_ROOT_LEVEL) { |
| 586 | quadrant = gaddr >> (PAGE_SHIFT + (PT64_PT_BITS * level)); | 608 | quadrant = gaddr >> (PAGE_SHIFT + (PT64_PT_BITS * level)); |
| 587 | quadrant &= (1 << ((PT32_PT_BITS - PT64_PT_BITS) * level)) - 1; | 609 | quadrant &= (1 << ((PT32_PT_BITS - PT64_PT_BITS) * level)) - 1; |
| @@ -669,10 +691,8 @@ static void kvm_mmu_zap_page(struct kvm_vcpu *vcpu, | |||
| 669 | if (!page->root_count) { | 691 | if (!page->root_count) { |
| 670 | hlist_del(&page->hash_link); | 692 | hlist_del(&page->hash_link); |
| 671 | kvm_mmu_free_page(vcpu, page->page_hpa); | 693 | kvm_mmu_free_page(vcpu, page->page_hpa); |
| 672 | } else { | 694 | } else |
| 673 | list_del(&page->link); | 695 | list_move(&page->link, &vcpu->kvm->active_mmu_pages); |
| 674 | list_add(&page->link, &vcpu->kvm->active_mmu_pages); | ||
| 675 | } | ||
| 676 | } | 696 | } |
| 677 | 697 | ||
| 678 | static int kvm_mmu_unprotect_page(struct kvm_vcpu *vcpu, gfn_t gfn) | 698 | static int kvm_mmu_unprotect_page(struct kvm_vcpu *vcpu, gfn_t gfn) |
| @@ -714,14 +734,12 @@ hpa_t safe_gpa_to_hpa(struct kvm_vcpu *vcpu, gpa_t gpa) | |||
| 714 | 734 | ||
| 715 | hpa_t gpa_to_hpa(struct kvm_vcpu *vcpu, gpa_t gpa) | 735 | hpa_t gpa_to_hpa(struct kvm_vcpu *vcpu, gpa_t gpa) |
| 716 | { | 736 | { |
| 717 | struct kvm_memory_slot *slot; | ||
| 718 | struct page *page; | 737 | struct page *page; |
| 719 | 738 | ||
| 720 | ASSERT((gpa & HPA_ERR_MASK) == 0); | 739 | ASSERT((gpa & HPA_ERR_MASK) == 0); |
| 721 | slot = gfn_to_memslot(vcpu->kvm, gpa >> PAGE_SHIFT); | 740 | page = gfn_to_page(vcpu->kvm, gpa >> PAGE_SHIFT); |
| 722 | if (!slot) | 741 | if (!page) |
| 723 | return gpa | HPA_ERR_MASK; | 742 | return gpa | HPA_ERR_MASK; |
| 724 | page = gfn_to_page(slot, gpa >> PAGE_SHIFT); | ||
| 725 | return ((hpa_t)page_to_pfn(page) << PAGE_SHIFT) | 743 | return ((hpa_t)page_to_pfn(page) << PAGE_SHIFT) |
| 726 | | (gpa & (PAGE_SIZE-1)); | 744 | | (gpa & (PAGE_SIZE-1)); |
| 727 | } | 745 | } |
| @@ -735,6 +753,15 @@ hpa_t gva_to_hpa(struct kvm_vcpu *vcpu, gva_t gva) | |||
| 735 | return gpa_to_hpa(vcpu, gpa); | 753 | return gpa_to_hpa(vcpu, gpa); |
| 736 | } | 754 | } |
| 737 | 755 | ||
| 756 | struct page *gva_to_page(struct kvm_vcpu *vcpu, gva_t gva) | ||
| 757 | { | ||
| 758 | gpa_t gpa = vcpu->mmu.gva_to_gpa(vcpu, gva); | ||
| 759 | |||
| 760 | if (gpa == UNMAPPED_GVA) | ||
| 761 | return NULL; | ||
| 762 | return pfn_to_page(gpa_to_hpa(vcpu, gpa) >> PAGE_SHIFT); | ||
| 763 | } | ||
| 764 | |||
| 738 | static void nonpaging_new_cr3(struct kvm_vcpu *vcpu) | 765 | static void nonpaging_new_cr3(struct kvm_vcpu *vcpu) |
| 739 | { | 766 | { |
| 740 | } | 767 | } |
| @@ -772,7 +799,7 @@ static int nonpaging_map(struct kvm_vcpu *vcpu, gva_t v, hpa_t p) | |||
| 772 | >> PAGE_SHIFT; | 799 | >> PAGE_SHIFT; |
| 773 | new_table = kvm_mmu_get_page(vcpu, pseudo_gfn, | 800 | new_table = kvm_mmu_get_page(vcpu, pseudo_gfn, |
| 774 | v, level - 1, | 801 | v, level - 1, |
| 775 | 1, &table[index]); | 802 | 1, 0, &table[index]); |
| 776 | if (!new_table) { | 803 | if (!new_table) { |
| 777 | pgprintk("nonpaging_map: ENOMEM\n"); | 804 | pgprintk("nonpaging_map: ENOMEM\n"); |
| 778 | return -ENOMEM; | 805 | return -ENOMEM; |
| @@ -804,10 +831,12 @@ static void mmu_free_roots(struct kvm_vcpu *vcpu) | |||
| 804 | for (i = 0; i < 4; ++i) { | 831 | for (i = 0; i < 4; ++i) { |
| 805 | hpa_t root = vcpu->mmu.pae_root[i]; | 832 | hpa_t root = vcpu->mmu.pae_root[i]; |
| 806 | 833 | ||
| 807 | ASSERT(VALID_PAGE(root)); | 834 | if (root) { |
| 808 | root &= PT64_BASE_ADDR_MASK; | 835 | ASSERT(VALID_PAGE(root)); |
| 809 | page = page_header(root); | 836 | root &= PT64_BASE_ADDR_MASK; |
| 810 | --page->root_count; | 837 | page = page_header(root); |
| 838 | --page->root_count; | ||
| 839 | } | ||
| 811 | vcpu->mmu.pae_root[i] = INVALID_PAGE; | 840 | vcpu->mmu.pae_root[i] = INVALID_PAGE; |
| 812 | } | 841 | } |
| 813 | vcpu->mmu.root_hpa = INVALID_PAGE; | 842 | vcpu->mmu.root_hpa = INVALID_PAGE; |
| @@ -827,7 +856,7 @@ static void mmu_alloc_roots(struct kvm_vcpu *vcpu) | |||
| 827 | 856 | ||
| 828 | ASSERT(!VALID_PAGE(root)); | 857 | ASSERT(!VALID_PAGE(root)); |
| 829 | page = kvm_mmu_get_page(vcpu, root_gfn, 0, | 858 | page = kvm_mmu_get_page(vcpu, root_gfn, 0, |
| 830 | PT64_ROOT_LEVEL, 0, NULL); | 859 | PT64_ROOT_LEVEL, 0, 0, NULL); |
| 831 | root = page->page_hpa; | 860 | root = page->page_hpa; |
| 832 | ++page->root_count; | 861 | ++page->root_count; |
| 833 | vcpu->mmu.root_hpa = root; | 862 | vcpu->mmu.root_hpa = root; |
| @@ -838,13 +867,17 @@ static void mmu_alloc_roots(struct kvm_vcpu *vcpu) | |||
| 838 | hpa_t root = vcpu->mmu.pae_root[i]; | 867 | hpa_t root = vcpu->mmu.pae_root[i]; |
| 839 | 868 | ||
| 840 | ASSERT(!VALID_PAGE(root)); | 869 | ASSERT(!VALID_PAGE(root)); |
| 841 | if (vcpu->mmu.root_level == PT32E_ROOT_LEVEL) | 870 | if (vcpu->mmu.root_level == PT32E_ROOT_LEVEL) { |
| 871 | if (!is_present_pte(vcpu->pdptrs[i])) { | ||
| 872 | vcpu->mmu.pae_root[i] = 0; | ||
| 873 | continue; | ||
| 874 | } | ||
| 842 | root_gfn = vcpu->pdptrs[i] >> PAGE_SHIFT; | 875 | root_gfn = vcpu->pdptrs[i] >> PAGE_SHIFT; |
| 843 | else if (vcpu->mmu.root_level == 0) | 876 | } else if (vcpu->mmu.root_level == 0) |
| 844 | root_gfn = 0; | 877 | root_gfn = 0; |
| 845 | page = kvm_mmu_get_page(vcpu, root_gfn, i << 30, | 878 | page = kvm_mmu_get_page(vcpu, root_gfn, i << 30, |
| 846 | PT32_ROOT_LEVEL, !is_paging(vcpu), | 879 | PT32_ROOT_LEVEL, !is_paging(vcpu), |
| 847 | NULL); | 880 | 0, NULL); |
| 848 | root = page->page_hpa; | 881 | root = page->page_hpa; |
| 849 | ++page->root_count; | 882 | ++page->root_count; |
| 850 | vcpu->mmu.pae_root[i] = root | PT_PRESENT_MASK; | 883 | vcpu->mmu.pae_root[i] = root | PT_PRESENT_MASK; |
| @@ -903,7 +936,7 @@ static int nonpaging_init_context(struct kvm_vcpu *vcpu) | |||
| 903 | 936 | ||
| 904 | static void kvm_mmu_flush_tlb(struct kvm_vcpu *vcpu) | 937 | static void kvm_mmu_flush_tlb(struct kvm_vcpu *vcpu) |
| 905 | { | 938 | { |
| 906 | ++kvm_stat.tlb_flush; | 939 | ++vcpu->stat.tlb_flush; |
| 907 | kvm_arch_ops->tlb_flush(vcpu); | 940 | kvm_arch_ops->tlb_flush(vcpu); |
| 908 | } | 941 | } |
| 909 | 942 | ||
| @@ -918,11 +951,6 @@ static void paging_new_cr3(struct kvm_vcpu *vcpu) | |||
| 918 | kvm_arch_ops->set_cr3(vcpu, vcpu->mmu.root_hpa); | 951 | kvm_arch_ops->set_cr3(vcpu, vcpu->mmu.root_hpa); |
| 919 | } | 952 | } |
| 920 | 953 | ||
| 921 | static void mark_pagetable_nonglobal(void *shadow_pte) | ||
| 922 | { | ||
| 923 | page_header(__pa(shadow_pte))->global = 0; | ||
| 924 | } | ||
| 925 | |||
| 926 | static inline void set_pte_common(struct kvm_vcpu *vcpu, | 954 | static inline void set_pte_common(struct kvm_vcpu *vcpu, |
| 927 | u64 *shadow_pte, | 955 | u64 *shadow_pte, |
| 928 | gpa_t gaddr, | 956 | gpa_t gaddr, |
| @@ -940,9 +968,6 @@ static inline void set_pte_common(struct kvm_vcpu *vcpu, | |||
| 940 | 968 | ||
| 941 | *shadow_pte |= access_bits; | 969 | *shadow_pte |= access_bits; |
| 942 | 970 | ||
| 943 | if (!(*shadow_pte & PT_GLOBAL_MASK)) | ||
| 944 | mark_pagetable_nonglobal(shadow_pte); | ||
| 945 | |||
| 946 | if (is_error_hpa(paddr)) { | 971 | if (is_error_hpa(paddr)) { |
| 947 | *shadow_pte |= gaddr; | 972 | *shadow_pte |= gaddr; |
| 948 | *shadow_pte |= PT_SHADOW_IO_MARK; | 973 | *shadow_pte |= PT_SHADOW_IO_MARK; |
| @@ -1316,6 +1341,51 @@ void kvm_mmu_slot_remove_write_access(struct kvm_vcpu *vcpu, int slot) | |||
| 1316 | } | 1341 | } |
| 1317 | } | 1342 | } |
| 1318 | 1343 | ||
| 1344 | void kvm_mmu_zap_all(struct kvm_vcpu *vcpu) | ||
| 1345 | { | ||
| 1346 | destroy_kvm_mmu(vcpu); | ||
| 1347 | |||
| 1348 | while (!list_empty(&vcpu->kvm->active_mmu_pages)) { | ||
| 1349 | struct kvm_mmu_page *page; | ||
| 1350 | |||
| 1351 | page = container_of(vcpu->kvm->active_mmu_pages.next, | ||
| 1352 | struct kvm_mmu_page, link); | ||
| 1353 | kvm_mmu_zap_page(vcpu, page); | ||
| 1354 | } | ||
| 1355 | |||
| 1356 | mmu_free_memory_caches(vcpu); | ||
| 1357 | kvm_arch_ops->tlb_flush(vcpu); | ||
| 1358 | init_kvm_mmu(vcpu); | ||
| 1359 | } | ||
| 1360 | |||
| 1361 | void kvm_mmu_module_exit(void) | ||
| 1362 | { | ||
| 1363 | if (pte_chain_cache) | ||
| 1364 | kmem_cache_destroy(pte_chain_cache); | ||
| 1365 | if (rmap_desc_cache) | ||
| 1366 | kmem_cache_destroy(rmap_desc_cache); | ||
| 1367 | } | ||
| 1368 | |||
| 1369 | int kvm_mmu_module_init(void) | ||
| 1370 | { | ||
| 1371 | pte_chain_cache = kmem_cache_create("kvm_pte_chain", | ||
| 1372 | sizeof(struct kvm_pte_chain), | ||
| 1373 | 0, 0, NULL, NULL); | ||
| 1374 | if (!pte_chain_cache) | ||
| 1375 | goto nomem; | ||
| 1376 | rmap_desc_cache = kmem_cache_create("kvm_rmap_desc", | ||
| 1377 | sizeof(struct kvm_rmap_desc), | ||
| 1378 | 0, 0, NULL, NULL); | ||
| 1379 | if (!rmap_desc_cache) | ||
| 1380 | goto nomem; | ||
| 1381 | |||
| 1382 | return 0; | ||
| 1383 | |||
| 1384 | nomem: | ||
| 1385 | kvm_mmu_module_exit(); | ||
| 1386 | return -ENOMEM; | ||
| 1387 | } | ||
| 1388 | |||
| 1319 | #ifdef AUDIT | 1389 | #ifdef AUDIT |
| 1320 | 1390 | ||
| 1321 | static const char *audit_msg; | 1391 | static const char *audit_msg; |
| @@ -1338,7 +1408,7 @@ static void audit_mappings_page(struct kvm_vcpu *vcpu, u64 page_pte, | |||
| 1338 | for (i = 0; i < PT64_ENT_PER_PAGE; ++i, va += va_delta) { | 1408 | for (i = 0; i < PT64_ENT_PER_PAGE; ++i, va += va_delta) { |
| 1339 | u64 ent = pt[i]; | 1409 | u64 ent = pt[i]; |
| 1340 | 1410 | ||
| 1341 | if (!ent & PT_PRESENT_MASK) | 1411 | if (!(ent & PT_PRESENT_MASK)) |
| 1342 | continue; | 1412 | continue; |
| 1343 | 1413 | ||
| 1344 | va = canonicalize(va); | 1414 | va = canonicalize(va); |
| @@ -1360,7 +1430,7 @@ static void audit_mappings_page(struct kvm_vcpu *vcpu, u64 page_pte, | |||
| 1360 | 1430 | ||
| 1361 | static void audit_mappings(struct kvm_vcpu *vcpu) | 1431 | static void audit_mappings(struct kvm_vcpu *vcpu) |
| 1362 | { | 1432 | { |
| 1363 | int i; | 1433 | unsigned i; |
| 1364 | 1434 | ||
| 1365 | if (vcpu->mmu.root_level == 4) | 1435 | if (vcpu->mmu.root_level == 4) |
| 1366 | audit_mappings_page(vcpu, vcpu->mmu.root_hpa, 0, 4); | 1436 | audit_mappings_page(vcpu, vcpu->mmu.root_hpa, 0, 4); |
