aboutsummaryrefslogtreecommitdiffstats
path: root/virt
diff options
context:
space:
mode:
Diffstat (limited to 'virt')
-rw-r--r--virt/kvm/kvm_main.c29
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
930unsigned long gfn_to_hva(struct kvm *kvm, gfn_t gfn) 930static 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
945unsigned long gfn_to_hva(struct kvm *kvm, gfn_t gfn)
946{
947 return gfn_to_hva_many(kvm, gfn, NULL);
948}
939EXPORT_SYMBOL_GPL(gfn_to_hva); 949EXPORT_SYMBOL_GPL(gfn_to_hva);
940 950
941static pfn_t hva_to_pfn(struct kvm *kvm, unsigned long addr, bool atomic) 951static 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
1023int 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}
1038EXPORT_SYMBOL_GPL(gfn_to_page_many_atomic);
1039
1013struct page *gfn_to_page(struct kvm *kvm, gfn_t gfn) 1040struct page *gfn_to_page(struct kvm *kvm, gfn_t gfn)
1014{ 1041{
1015 pfn_t pfn; 1042 pfn_t pfn;