diff options
| author | Xiao Guangrong <xiaoguangrong@cn.fujitsu.com> | 2010-08-22 07:11:43 -0400 |
|---|---|---|
| committer | Avi Kivity <avi@redhat.com> | 2010-10-24 04:51:26 -0400 |
| commit | 48987781eb1d1e8ded41f55cd5806615fda92c6e (patch) | |
| tree | fa6db806ffec34588fbcaa434c33afac51f661e6 /virt | |
| parent | 887c08ac191efb103e33e589aacbc2ce1a3f131e (diff) | |
KVM: MMU: introduce gfn_to_page_many_atomic() function
Introduce this function to get consecutive gfn's pages, it can reduce
gup's overload, used by later patch
Signed-off-by: Xiao Guangrong <xiaoguangrong@cn.fujitsu.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Diffstat (limited to 'virt')
| -rw-r--r-- | virt/kvm/kvm_main.c | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 08bd304f8bc7..2eb0b7500a2a 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c | |||
| @@ -927,15 +927,25 @@ int memslot_id(struct kvm *kvm, gfn_t gfn) | |||
| 927 | return memslot - slots->memslots; | 927 | return memslot - slots->memslots; |
| 928 | } | 928 | } |
| 929 | 929 | ||
| 930 | unsigned long gfn_to_hva(struct kvm *kvm, gfn_t gfn) | 930 | static unsigned long gfn_to_hva_many(struct kvm *kvm, gfn_t gfn, |
| 931 | gfn_t *nr_pages) | ||
| 931 | { | 932 | { |
| 932 | struct kvm_memory_slot *slot; | 933 | struct kvm_memory_slot *slot; |
| 933 | 934 | ||
| 934 | slot = gfn_to_memslot(kvm, gfn); | 935 | slot = gfn_to_memslot(kvm, gfn); |
| 935 | if (!slot || slot->flags & KVM_MEMSLOT_INVALID) | 936 | if (!slot || slot->flags & KVM_MEMSLOT_INVALID) |
| 936 | return bad_hva(); | 937 | return bad_hva(); |
| 938 | |||
| 939 | if (nr_pages) | ||
| 940 | *nr_pages = slot->npages - (gfn - slot->base_gfn); | ||
| 941 | |||
| 937 | return gfn_to_hva_memslot(slot, gfn); | 942 | return gfn_to_hva_memslot(slot, gfn); |
| 938 | } | 943 | } |
| 944 | |||
| 945 | unsigned long gfn_to_hva(struct kvm *kvm, gfn_t gfn) | ||
| 946 | { | ||
| 947 | return gfn_to_hva_many(kvm, gfn, NULL); | ||
| 948 | } | ||
| 939 | EXPORT_SYMBOL_GPL(gfn_to_hva); | 949 | EXPORT_SYMBOL_GPL(gfn_to_hva); |
| 940 | 950 | ||
| 941 | static pfn_t hva_to_pfn(struct kvm *kvm, unsigned long addr, bool atomic) | 951 | static pfn_t hva_to_pfn(struct kvm *kvm, unsigned long addr, bool atomic) |
| @@ -1010,6 +1020,23 @@ pfn_t gfn_to_pfn_memslot(struct kvm *kvm, | |||
| 1010 | return hva_to_pfn(kvm, addr, false); | 1020 | return hva_to_pfn(kvm, addr, false); |
| 1011 | } | 1021 | } |
| 1012 | 1022 | ||
| 1023 | int gfn_to_page_many_atomic(struct kvm *kvm, gfn_t gfn, struct page **pages, | ||
| 1024 | int nr_pages) | ||
| 1025 | { | ||
| 1026 | unsigned long addr; | ||
| 1027 | gfn_t entry; | ||
| 1028 | |||
| 1029 | addr = gfn_to_hva_many(kvm, gfn, &entry); | ||
| 1030 | if (kvm_is_error_hva(addr)) | ||
| 1031 | return -1; | ||
| 1032 | |||
| 1033 | if (entry < nr_pages) | ||
| 1034 | return 0; | ||
| 1035 | |||
| 1036 | return __get_user_pages_fast(addr, nr_pages, 1, pages); | ||
| 1037 | } | ||
| 1038 | EXPORT_SYMBOL_GPL(gfn_to_page_many_atomic); | ||
| 1039 | |||
| 1013 | struct page *gfn_to_page(struct kvm *kvm, gfn_t gfn) | 1040 | struct page *gfn_to_page(struct kvm *kvm, gfn_t gfn) |
| 1014 | { | 1041 | { |
| 1015 | pfn_t pfn; | 1042 | pfn_t pfn; |
