diff options
Diffstat (limited to 'arch/x86/kvm/mmu.c')
-rw-r--r-- | arch/x86/kvm/mmu.c | 28 |
1 files changed, 12 insertions, 16 deletions
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 38c0c32926c9..24e800116ab4 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c | |||
@@ -1909,18 +1909,17 @@ static void kvm_mmu_commit_zap_page(struct kvm *kvm, | |||
1909 | * since it has been deleted from active_mmu_pages but still can be found | 1909 | * since it has been deleted from active_mmu_pages but still can be found |
1910 | * at hast list. | 1910 | * at hast list. |
1911 | * | 1911 | * |
1912 | * for_each_gfn_indirect_valid_sp has skipped that kind of page and | 1912 | * for_each_gfn_valid_sp() has skipped that kind of pages. |
1913 | * kvm_mmu_get_page(), the only user of for_each_gfn_sp(), has skipped | ||
1914 | * all the obsolete pages. | ||
1915 | */ | 1913 | */ |
1916 | #define for_each_gfn_sp(_kvm, _sp, _gfn) \ | 1914 | #define for_each_gfn_valid_sp(_kvm, _sp, _gfn) \ |
1917 | hlist_for_each_entry(_sp, \ | 1915 | hlist_for_each_entry(_sp, \ |
1918 | &(_kvm)->arch.mmu_page_hash[kvm_page_table_hashfn(_gfn)], hash_link) \ | 1916 | &(_kvm)->arch.mmu_page_hash[kvm_page_table_hashfn(_gfn)], hash_link) \ |
1919 | if ((_sp)->gfn != (_gfn)) {} else | 1917 | if ((_sp)->gfn != (_gfn) || is_obsolete_sp((_kvm), (_sp)) \ |
1918 | || (_sp)->role.invalid) {} else | ||
1920 | 1919 | ||
1921 | #define for_each_gfn_indirect_valid_sp(_kvm, _sp, _gfn) \ | 1920 | #define for_each_gfn_indirect_valid_sp(_kvm, _sp, _gfn) \ |
1922 | for_each_gfn_sp(_kvm, _sp, _gfn) \ | 1921 | for_each_gfn_valid_sp(_kvm, _sp, _gfn) \ |
1923 | if ((_sp)->role.direct || (_sp)->role.invalid) {} else | 1922 | if ((_sp)->role.direct) {} else |
1924 | 1923 | ||
1925 | /* @sp->gfn should be write-protected at the call site */ | 1924 | /* @sp->gfn should be write-protected at the call site */ |
1926 | static bool __kvm_sync_page(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp, | 1925 | static bool __kvm_sync_page(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp, |
@@ -1961,6 +1960,11 @@ static void kvm_mmu_audit(struct kvm_vcpu *vcpu, int point) { } | |||
1961 | static void mmu_audit_disable(void) { } | 1960 | static void mmu_audit_disable(void) { } |
1962 | #endif | 1961 | #endif |
1963 | 1962 | ||
1963 | static bool is_obsolete_sp(struct kvm *kvm, struct kvm_mmu_page *sp) | ||
1964 | { | ||
1965 | return unlikely(sp->mmu_valid_gen != kvm->arch.mmu_valid_gen); | ||
1966 | } | ||
1967 | |||
1964 | static bool kvm_sync_page(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp, | 1968 | static bool kvm_sync_page(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp, |
1965 | struct list_head *invalid_list) | 1969 | struct list_head *invalid_list) |
1966 | { | 1970 | { |
@@ -2105,11 +2109,6 @@ static void clear_sp_write_flooding_count(u64 *spte) | |||
2105 | __clear_sp_write_flooding_count(sp); | 2109 | __clear_sp_write_flooding_count(sp); |
2106 | } | 2110 | } |
2107 | 2111 | ||
2108 | static bool is_obsolete_sp(struct kvm *kvm, struct kvm_mmu_page *sp) | ||
2109 | { | ||
2110 | return unlikely(sp->mmu_valid_gen != kvm->arch.mmu_valid_gen); | ||
2111 | } | ||
2112 | |||
2113 | static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu, | 2112 | static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu, |
2114 | gfn_t gfn, | 2113 | gfn_t gfn, |
2115 | gva_t gaddr, | 2114 | gva_t gaddr, |
@@ -2136,10 +2135,7 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu, | |||
2136 | quadrant &= (1 << ((PT32_PT_BITS - PT64_PT_BITS) * level)) - 1; | 2135 | quadrant &= (1 << ((PT32_PT_BITS - PT64_PT_BITS) * level)) - 1; |
2137 | role.quadrant = quadrant; | 2136 | role.quadrant = quadrant; |
2138 | } | 2137 | } |
2139 | for_each_gfn_sp(vcpu->kvm, sp, gfn) { | 2138 | for_each_gfn_valid_sp(vcpu->kvm, sp, gfn) { |
2140 | if (is_obsolete_sp(vcpu->kvm, sp)) | ||
2141 | continue; | ||
2142 | |||
2143 | if (!need_sync && sp->unsync) | 2139 | if (!need_sync && sp->unsync) |
2144 | need_sync = true; | 2140 | need_sync = true; |
2145 | 2141 | ||