diff options
Diffstat (limited to 'virt')
-rw-r--r-- | virt/kvm/kvm_main.c | 33 |
1 files changed, 25 insertions, 8 deletions
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index c9f6cfe83120..4e2321c733f7 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c | |||
@@ -835,21 +835,14 @@ unsigned long gfn_to_hva(struct kvm *kvm, gfn_t gfn) | |||
835 | } | 835 | } |
836 | EXPORT_SYMBOL_GPL(gfn_to_hva); | 836 | EXPORT_SYMBOL_GPL(gfn_to_hva); |
837 | 837 | ||
838 | pfn_t gfn_to_pfn(struct kvm *kvm, gfn_t gfn) | 838 | static pfn_t hva_to_pfn(struct kvm *kvm, unsigned long addr) |
839 | { | 839 | { |
840 | struct page *page[1]; | 840 | struct page *page[1]; |
841 | unsigned long addr; | ||
842 | int npages; | 841 | int npages; |
843 | pfn_t pfn; | 842 | pfn_t pfn; |
844 | 843 | ||
845 | might_sleep(); | 844 | might_sleep(); |
846 | 845 | ||
847 | addr = gfn_to_hva(kvm, gfn); | ||
848 | if (kvm_is_error_hva(addr)) { | ||
849 | get_page(bad_page); | ||
850 | return page_to_pfn(bad_page); | ||
851 | } | ||
852 | |||
853 | npages = get_user_pages_fast(addr, 1, 1, page); | 846 | npages = get_user_pages_fast(addr, 1, 1, page); |
854 | 847 | ||
855 | if (unlikely(npages != 1)) { | 848 | if (unlikely(npages != 1)) { |
@@ -874,8 +867,32 @@ pfn_t gfn_to_pfn(struct kvm *kvm, gfn_t gfn) | |||
874 | return pfn; | 867 | return pfn; |
875 | } | 868 | } |
876 | 869 | ||
870 | pfn_t gfn_to_pfn(struct kvm *kvm, gfn_t gfn) | ||
871 | { | ||
872 | unsigned long addr; | ||
873 | |||
874 | addr = gfn_to_hva(kvm, gfn); | ||
875 | if (kvm_is_error_hva(addr)) { | ||
876 | get_page(bad_page); | ||
877 | return page_to_pfn(bad_page); | ||
878 | } | ||
879 | |||
880 | return hva_to_pfn(kvm, addr); | ||
881 | } | ||
877 | EXPORT_SYMBOL_GPL(gfn_to_pfn); | 882 | EXPORT_SYMBOL_GPL(gfn_to_pfn); |
878 | 883 | ||
884 | static unsigned long gfn_to_hva_memslot(struct kvm_memory_slot *slot, gfn_t gfn) | ||
885 | { | ||
886 | return (slot->userspace_addr + (gfn - slot->base_gfn) * PAGE_SIZE); | ||
887 | } | ||
888 | |||
889 | pfn_t gfn_to_pfn_memslot(struct kvm *kvm, | ||
890 | struct kvm_memory_slot *slot, gfn_t gfn) | ||
891 | { | ||
892 | unsigned long addr = gfn_to_hva_memslot(slot, gfn); | ||
893 | return hva_to_pfn(kvm, addr); | ||
894 | } | ||
895 | |||
879 | struct page *gfn_to_page(struct kvm *kvm, gfn_t gfn) | 896 | struct page *gfn_to_page(struct kvm *kvm, gfn_t gfn) |
880 | { | 897 | { |
881 | pfn_t pfn; | 898 | pfn_t pfn; |