diff options
-rw-r--r-- | include/linux/kvm_host.h | 2 | ||||
-rw-r--r-- | virt/kvm/kvm_main.c | 33 |
2 files changed, 27 insertions, 8 deletions
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 3c44687b3425..f1f78deece10 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h | |||
@@ -273,6 +273,8 @@ void kvm_set_page_dirty(struct page *page); | |||
273 | void kvm_set_page_accessed(struct page *page); | 273 | void kvm_set_page_accessed(struct page *page); |
274 | 274 | ||
275 | pfn_t gfn_to_pfn(struct kvm *kvm, gfn_t gfn); | 275 | pfn_t gfn_to_pfn(struct kvm *kvm, gfn_t gfn); |
276 | pfn_t gfn_to_pfn_memslot(struct kvm *kvm, | ||
277 | struct kvm_memory_slot *slot, gfn_t gfn); | ||
276 | void kvm_release_pfn_dirty(pfn_t); | 278 | void kvm_release_pfn_dirty(pfn_t); |
277 | void kvm_release_pfn_clean(pfn_t pfn); | 279 | void kvm_release_pfn_clean(pfn_t pfn); |
278 | void kvm_set_pfn_dirty(pfn_t pfn); | 280 | void kvm_set_pfn_dirty(pfn_t pfn); |
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; |