diff options
author | Takuya Yoshikawa <yoshikawa_takuya_b1@lab.ntt.co.jp> | 2015-10-16 04:08:03 -0400 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2015-10-16 04:34:02 -0400 |
commit | 5225fdf8c8bea4418f69875804584c89a27c170e (patch) | |
tree | ab26c260f44204563e5bd685cfb0686128b8eaf1 | |
parent | d8aacf5df86a961923a2c9c547d341d64a9d9f5d (diff) |
KVM: x86: MMU: Eliminate an extra memory slot search in mapping_level()
Calling kvm_vcpu_gfn_to_memslot() twice in mapping_level() should be
avoided since getting a slot by binary search may not be negligible,
especially for virtual machines with many memory slots.
Signed-off-by: Takuya Yoshikawa <yoshikawa_takuya_b1@lab.ntt.co.jp>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r-- | arch/x86/kvm/mmu.c | 17 |
1 files changed, 11 insertions, 6 deletions
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 09833b04fc97..dd2a7c6ec2ca 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c | |||
@@ -818,14 +818,11 @@ static void unaccount_shadowed(struct kvm *kvm, struct kvm_mmu_page *sp) | |||
818 | kvm->arch.indirect_shadow_pages--; | 818 | kvm->arch.indirect_shadow_pages--; |
819 | } | 819 | } |
820 | 820 | ||
821 | static int has_wrprotected_page(struct kvm_vcpu *vcpu, | 821 | static int __has_wrprotected_page(gfn_t gfn, int level, |
822 | gfn_t gfn, | 822 | struct kvm_memory_slot *slot) |
823 | int level) | ||
824 | { | 823 | { |
825 | struct kvm_memory_slot *slot; | ||
826 | struct kvm_lpage_info *linfo; | 824 | struct kvm_lpage_info *linfo; |
827 | 825 | ||
828 | slot = kvm_vcpu_gfn_to_memslot(vcpu, gfn); | ||
829 | if (slot) { | 826 | if (slot) { |
830 | linfo = lpage_info_slot(gfn, slot, level); | 827 | linfo = lpage_info_slot(gfn, slot, level); |
831 | return linfo->write_count; | 828 | return linfo->write_count; |
@@ -834,6 +831,14 @@ static int has_wrprotected_page(struct kvm_vcpu *vcpu, | |||
834 | return 1; | 831 | return 1; |
835 | } | 832 | } |
836 | 833 | ||
834 | static int has_wrprotected_page(struct kvm_vcpu *vcpu, gfn_t gfn, int level) | ||
835 | { | ||
836 | struct kvm_memory_slot *slot; | ||
837 | |||
838 | slot = kvm_vcpu_gfn_to_memslot(vcpu, gfn); | ||
839 | return __has_wrprotected_page(gfn, level, slot); | ||
840 | } | ||
841 | |||
837 | static int host_mapping_level(struct kvm *kvm, gfn_t gfn) | 842 | static int host_mapping_level(struct kvm *kvm, gfn_t gfn) |
838 | { | 843 | { |
839 | unsigned long page_size; | 844 | unsigned long page_size; |
@@ -896,7 +901,7 @@ static int mapping_level(struct kvm_vcpu *vcpu, gfn_t large_gfn, | |||
896 | max_level = min(kvm_x86_ops->get_lpage_level(), host_level); | 901 | max_level = min(kvm_x86_ops->get_lpage_level(), host_level); |
897 | 902 | ||
898 | for (level = PT_DIRECTORY_LEVEL; level <= max_level; ++level) | 903 | for (level = PT_DIRECTORY_LEVEL; level <= max_level; ++level) |
899 | if (has_wrprotected_page(vcpu, large_gfn, level)) | 904 | if (__has_wrprotected_page(large_gfn, level, slot)) |
900 | break; | 905 | break; |
901 | 906 | ||
902 | return level - 1; | 907 | return level - 1; |