aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--virt/kvm/kvm_main.c30
1 files changed, 17 insertions, 13 deletions
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 228f00f87966..475a100f3a22 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -952,6 +952,12 @@ unsigned long gfn_to_hva(struct kvm *kvm, gfn_t gfn)
952} 952}
953EXPORT_SYMBOL_GPL(gfn_to_hva); 953EXPORT_SYMBOL_GPL(gfn_to_hva);
954 954
955static pfn_t get_fault_pfn(void)
956{
957 get_page(fault_page);
958 return fault_pfn;
959}
960
955static pfn_t hva_to_pfn(struct kvm *kvm, unsigned long addr, bool atomic, 961static pfn_t hva_to_pfn(struct kvm *kvm, unsigned long addr, bool atomic,
956 bool *async) 962 bool *async)
957{ 963{
@@ -974,7 +980,7 @@ static pfn_t hva_to_pfn(struct kvm *kvm, unsigned long addr, bool atomic,
974 struct vm_area_struct *vma; 980 struct vm_area_struct *vma;
975 981
976 if (atomic) 982 if (atomic)
977 goto return_fault_page; 983 return get_fault_pfn();
978 984
979 down_read(&current->mm->mmap_sem); 985 down_read(&current->mm->mmap_sem);
980 if (is_hwpoison_address(addr)) { 986 if (is_hwpoison_address(addr)) {
@@ -983,22 +989,20 @@ static pfn_t hva_to_pfn(struct kvm *kvm, unsigned long addr, bool atomic,
983 return page_to_pfn(hwpoison_page); 989 return page_to_pfn(hwpoison_page);
984 } 990 }
985 991
986 vma = find_vma(current->mm, addr); 992 vma = find_vma_intersection(current->mm, addr, addr+1);
987 993
988 if (vma == NULL || addr < vma->vm_start || 994 if (vma == NULL)
989 !(vma->vm_flags & VM_PFNMAP)) { 995 pfn = get_fault_pfn();
990 if (async && !(vma->vm_flags & VM_PFNMAP) && 996 else if ((vma->vm_flags & VM_PFNMAP)) {
991 (vma->vm_flags & VM_WRITE)) 997 pfn = ((addr - vma->vm_start) >> PAGE_SHIFT) +
998 vma->vm_pgoff;
999 BUG_ON(!kvm_is_mmio_pfn(pfn));
1000 } else {
1001 if (async && (vma->vm_flags & VM_WRITE))
992 *async = true; 1002 *async = true;
993 up_read(&current->mm->mmap_sem); 1003 pfn = get_fault_pfn();
994return_fault_page:
995 get_page(fault_page);
996 return page_to_pfn(fault_page);
997 } 1004 }
998
999 pfn = ((addr - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff;
1000 up_read(&current->mm->mmap_sem); 1005 up_read(&current->mm->mmap_sem);
1001 BUG_ON(!kvm_is_mmio_pfn(pfn));
1002 } else 1006 } else
1003 pfn = page_to_pfn(page[0]); 1007 pfn = page_to_pfn(page[0]);
1004 1008