diff options
Diffstat (limited to 'arch/x86/kvm/mmu.c')
-rw-r--r-- | arch/x86/kvm/mmu.c | 62 |
1 files changed, 44 insertions, 18 deletions
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 7e7c3969f7a2..b0e4ddca6c18 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c | |||
@@ -66,7 +66,8 @@ static void kvm_mmu_audit(struct kvm_vcpu *vcpu, const char *msg) {} | |||
66 | #endif | 66 | #endif |
67 | 67 | ||
68 | #if defined(MMU_DEBUG) || defined(AUDIT) | 68 | #if defined(MMU_DEBUG) || defined(AUDIT) |
69 | static int dbg = 1; | 69 | static int dbg = 0; |
70 | module_param(dbg, bool, 0644); | ||
70 | #endif | 71 | #endif |
71 | 72 | ||
72 | #ifndef MMU_DEBUG | 73 | #ifndef MMU_DEBUG |
@@ -776,6 +777,15 @@ static void mmu_page_remove_parent_pte(struct kvm_mmu_page *sp, | |||
776 | BUG(); | 777 | BUG(); |
777 | } | 778 | } |
778 | 779 | ||
780 | static void nonpaging_prefetch_page(struct kvm_vcpu *vcpu, | ||
781 | struct kvm_mmu_page *sp) | ||
782 | { | ||
783 | int i; | ||
784 | |||
785 | for (i = 0; i < PT64_ENT_PER_PAGE; ++i) | ||
786 | sp->spt[i] = shadow_trap_nonpresent_pte; | ||
787 | } | ||
788 | |||
779 | static struct kvm_mmu_page *kvm_mmu_lookup_page(struct kvm *kvm, gfn_t gfn) | 789 | static struct kvm_mmu_page *kvm_mmu_lookup_page(struct kvm *kvm, gfn_t gfn) |
780 | { | 790 | { |
781 | unsigned index; | 791 | unsigned index; |
@@ -841,7 +851,10 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu, | |||
841 | hlist_add_head(&sp->hash_link, bucket); | 851 | hlist_add_head(&sp->hash_link, bucket); |
842 | if (!metaphysical) | 852 | if (!metaphysical) |
843 | rmap_write_protect(vcpu->kvm, gfn); | 853 | rmap_write_protect(vcpu->kvm, gfn); |
844 | vcpu->arch.mmu.prefetch_page(vcpu, sp); | 854 | if (shadow_trap_nonpresent_pte != shadow_notrap_nonpresent_pte) |
855 | vcpu->arch.mmu.prefetch_page(vcpu, sp); | ||
856 | else | ||
857 | nonpaging_prefetch_page(vcpu, sp); | ||
845 | return sp; | 858 | return sp; |
846 | } | 859 | } |
847 | 860 | ||
@@ -917,14 +930,17 @@ static void kvm_mmu_zap_page(struct kvm *kvm, struct kvm_mmu_page *sp) | |||
917 | } | 930 | } |
918 | kvm_mmu_page_unlink_children(kvm, sp); | 931 | kvm_mmu_page_unlink_children(kvm, sp); |
919 | if (!sp->root_count) { | 932 | if (!sp->root_count) { |
920 | if (!sp->role.metaphysical) | 933 | if (!sp->role.metaphysical && !sp->role.invalid) |
921 | unaccount_shadowed(kvm, sp->gfn); | 934 | unaccount_shadowed(kvm, sp->gfn); |
922 | hlist_del(&sp->hash_link); | 935 | hlist_del(&sp->hash_link); |
923 | kvm_mmu_free_page(kvm, sp); | 936 | kvm_mmu_free_page(kvm, sp); |
924 | } else { | 937 | } else { |
938 | int invalid = sp->role.invalid; | ||
925 | list_move(&sp->link, &kvm->arch.active_mmu_pages); | 939 | list_move(&sp->link, &kvm->arch.active_mmu_pages); |
926 | sp->role.invalid = 1; | 940 | sp->role.invalid = 1; |
927 | kvm_reload_remote_mmus(kvm); | 941 | kvm_reload_remote_mmus(kvm); |
942 | if (!sp->role.metaphysical && !invalid) | ||
943 | unaccount_shadowed(kvm, sp->gfn); | ||
928 | } | 944 | } |
929 | kvm_mmu_reset_last_pte_updated(kvm); | 945 | kvm_mmu_reset_last_pte_updated(kvm); |
930 | } | 946 | } |
@@ -1103,7 +1119,7 @@ static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte, | |||
1103 | mark_page_dirty(vcpu->kvm, gfn); | 1119 | mark_page_dirty(vcpu->kvm, gfn); |
1104 | 1120 | ||
1105 | pgprintk("%s: setting spte %llx\n", __func__, spte); | 1121 | pgprintk("%s: setting spte %llx\n", __func__, spte); |
1106 | pgprintk("instantiating %s PTE (%s) at %d (%llx) addr %llx\n", | 1122 | pgprintk("instantiating %s PTE (%s) at %ld (%llx) addr %p\n", |
1107 | (spte&PT_PAGE_SIZE_MASK)? "2MB" : "4kB", | 1123 | (spte&PT_PAGE_SIZE_MASK)? "2MB" : "4kB", |
1108 | (spte&PT_WRITABLE_MASK)?"RW":"R", gfn, spte, shadow_pte); | 1124 | (spte&PT_WRITABLE_MASK)?"RW":"R", gfn, spte, shadow_pte); |
1109 | set_shadow_pte(shadow_pte, spte); | 1125 | set_shadow_pte(shadow_pte, spte); |
@@ -1122,8 +1138,10 @@ static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte, | |||
1122 | else | 1138 | else |
1123 | kvm_release_pfn_clean(pfn); | 1139 | kvm_release_pfn_clean(pfn); |
1124 | } | 1140 | } |
1125 | if (!ptwrite || !*ptwrite) | 1141 | if (speculative) { |
1126 | vcpu->arch.last_pte_updated = shadow_pte; | 1142 | vcpu->arch.last_pte_updated = shadow_pte; |
1143 | vcpu->arch.last_pte_gfn = gfn; | ||
1144 | } | ||
1127 | } | 1145 | } |
1128 | 1146 | ||
1129 | static void nonpaging_new_cr3(struct kvm_vcpu *vcpu) | 1147 | static void nonpaging_new_cr3(struct kvm_vcpu *vcpu) |
@@ -1171,9 +1189,10 @@ static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, int write, | |||
1171 | return -ENOMEM; | 1189 | return -ENOMEM; |
1172 | } | 1190 | } |
1173 | 1191 | ||
1174 | table[index] = __pa(new_table->spt) | 1192 | set_shadow_pte(&table[index], |
1175 | | PT_PRESENT_MASK | PT_WRITABLE_MASK | 1193 | __pa(new_table->spt) |
1176 | | shadow_user_mask | shadow_x_mask; | 1194 | | PT_PRESENT_MASK | PT_WRITABLE_MASK |
1195 | | shadow_user_mask | shadow_x_mask); | ||
1177 | } | 1196 | } |
1178 | table_addr = table[index] & PT64_BASE_ADDR_MASK; | 1197 | table_addr = table[index] & PT64_BASE_ADDR_MASK; |
1179 | } | 1198 | } |
@@ -1211,15 +1230,6 @@ static int nonpaging_map(struct kvm_vcpu *vcpu, gva_t v, int write, gfn_t gfn) | |||
1211 | } | 1230 | } |
1212 | 1231 | ||
1213 | 1232 | ||
1214 | static void nonpaging_prefetch_page(struct kvm_vcpu *vcpu, | ||
1215 | struct kvm_mmu_page *sp) | ||
1216 | { | ||
1217 | int i; | ||
1218 | |||
1219 | for (i = 0; i < PT64_ENT_PER_PAGE; ++i) | ||
1220 | sp->spt[i] = shadow_trap_nonpresent_pte; | ||
1221 | } | ||
1222 | |||
1223 | static void mmu_free_roots(struct kvm_vcpu *vcpu) | 1233 | static void mmu_free_roots(struct kvm_vcpu *vcpu) |
1224 | { | 1234 | { |
1225 | int i; | 1235 | int i; |
@@ -1671,6 +1681,18 @@ static void mmu_guess_page_from_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa, | |||
1671 | vcpu->arch.update_pte.pfn = pfn; | 1681 | vcpu->arch.update_pte.pfn = pfn; |
1672 | } | 1682 | } |
1673 | 1683 | ||
1684 | static void kvm_mmu_access_page(struct kvm_vcpu *vcpu, gfn_t gfn) | ||
1685 | { | ||
1686 | u64 *spte = vcpu->arch.last_pte_updated; | ||
1687 | |||
1688 | if (spte | ||
1689 | && vcpu->arch.last_pte_gfn == gfn | ||
1690 | && shadow_accessed_mask | ||
1691 | && !(*spte & shadow_accessed_mask) | ||
1692 | && is_shadow_present_pte(*spte)) | ||
1693 | set_bit(PT_ACCESSED_SHIFT, (unsigned long *)spte); | ||
1694 | } | ||
1695 | |||
1674 | void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa, | 1696 | void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa, |
1675 | const u8 *new, int bytes) | 1697 | const u8 *new, int bytes) |
1676 | { | 1698 | { |
@@ -1694,6 +1716,7 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa, | |||
1694 | pgprintk("%s: gpa %llx bytes %d\n", __func__, gpa, bytes); | 1716 | pgprintk("%s: gpa %llx bytes %d\n", __func__, gpa, bytes); |
1695 | mmu_guess_page_from_pte_write(vcpu, gpa, new, bytes); | 1717 | mmu_guess_page_from_pte_write(vcpu, gpa, new, bytes); |
1696 | spin_lock(&vcpu->kvm->mmu_lock); | 1718 | spin_lock(&vcpu->kvm->mmu_lock); |
1719 | kvm_mmu_access_page(vcpu, gfn); | ||
1697 | kvm_mmu_free_some_pages(vcpu); | 1720 | kvm_mmu_free_some_pages(vcpu); |
1698 | ++vcpu->kvm->stat.mmu_pte_write; | 1721 | ++vcpu->kvm->stat.mmu_pte_write; |
1699 | kvm_mmu_audit(vcpu, "pre pte write"); | 1722 | kvm_mmu_audit(vcpu, "pre pte write"); |
@@ -1948,7 +1971,7 @@ void kvm_mmu_zap_all(struct kvm *kvm) | |||
1948 | kvm_flush_remote_tlbs(kvm); | 1971 | kvm_flush_remote_tlbs(kvm); |
1949 | } | 1972 | } |
1950 | 1973 | ||
1951 | void kvm_mmu_remove_one_alloc_mmu_page(struct kvm *kvm) | 1974 | static void kvm_mmu_remove_one_alloc_mmu_page(struct kvm *kvm) |
1952 | { | 1975 | { |
1953 | struct kvm_mmu_page *page; | 1976 | struct kvm_mmu_page *page; |
1954 | 1977 | ||
@@ -1968,6 +1991,8 @@ static int mmu_shrink(int nr_to_scan, gfp_t gfp_mask) | |||
1968 | list_for_each_entry(kvm, &vm_list, vm_list) { | 1991 | list_for_each_entry(kvm, &vm_list, vm_list) { |
1969 | int npages; | 1992 | int npages; |
1970 | 1993 | ||
1994 | if (!down_read_trylock(&kvm->slots_lock)) | ||
1995 | continue; | ||
1971 | spin_lock(&kvm->mmu_lock); | 1996 | spin_lock(&kvm->mmu_lock); |
1972 | npages = kvm->arch.n_alloc_mmu_pages - | 1997 | npages = kvm->arch.n_alloc_mmu_pages - |
1973 | kvm->arch.n_free_mmu_pages; | 1998 | kvm->arch.n_free_mmu_pages; |
@@ -1980,6 +2005,7 @@ static int mmu_shrink(int nr_to_scan, gfp_t gfp_mask) | |||
1980 | nr_to_scan--; | 2005 | nr_to_scan--; |
1981 | 2006 | ||
1982 | spin_unlock(&kvm->mmu_lock); | 2007 | spin_unlock(&kvm->mmu_lock); |
2008 | up_read(&kvm->slots_lock); | ||
1983 | } | 2009 | } |
1984 | if (kvm_freed) | 2010 | if (kvm_freed) |
1985 | list_move_tail(&kvm_freed->vm_list, &vm_list); | 2011 | list_move_tail(&kvm_freed->vm_list, &vm_list); |