diff options
author | Marcelo Tosatti <mtosatti@redhat.com> | 2008-09-16 19:54:46 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2008-10-15 08:25:05 -0400 |
commit | 777b3f49d297e387866604093b635e5bc9b9d2a6 (patch) | |
tree | d3df6d34bceb9905b033bb2e9e7e9bc6e0992542 /virt | |
parent | bfadaded0dc323a1cf3f08b5068f12955b54cbaa (diff) |
KVM: opencode gfn_to_page in kvm_vm_fault
kvm_vm_fault is invoked with mmap_sem held in read mode. Since gfn_to_page
will be converted to get_user_pages_fast, which requires this lock NOT
to be held, switch to opencoded get_user_pages.
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'virt')
-rw-r--r-- | virt/kvm/kvm_main.c | 19 |
1 files changed, 12 insertions, 7 deletions
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index f42d5c2a396d..2907d05cfcc3 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c | |||
@@ -1394,17 +1394,22 @@ out: | |||
1394 | 1394 | ||
1395 | static int kvm_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | 1395 | static int kvm_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) |
1396 | { | 1396 | { |
1397 | struct page *page[1]; | ||
1398 | unsigned long addr; | ||
1399 | int npages; | ||
1400 | gfn_t gfn = vmf->pgoff; | ||
1397 | struct kvm *kvm = vma->vm_file->private_data; | 1401 | struct kvm *kvm = vma->vm_file->private_data; |
1398 | struct page *page; | ||
1399 | 1402 | ||
1400 | if (!kvm_is_visible_gfn(kvm, vmf->pgoff)) | 1403 | addr = gfn_to_hva(kvm, gfn); |
1404 | if (kvm_is_error_hva(addr)) | ||
1401 | return VM_FAULT_SIGBUS; | 1405 | return VM_FAULT_SIGBUS; |
1402 | page = gfn_to_page(kvm, vmf->pgoff); | 1406 | |
1403 | if (is_error_page(page)) { | 1407 | npages = get_user_pages(current, current->mm, addr, 1, 1, 0, page, |
1404 | kvm_release_page_clean(page); | 1408 | NULL); |
1409 | if (unlikely(npages != 1)) | ||
1405 | return VM_FAULT_SIGBUS; | 1410 | return VM_FAULT_SIGBUS; |
1406 | } | 1411 | |
1407 | vmf->page = page; | 1412 | vmf->page = page[0]; |
1408 | return 0; | 1413 | return 0; |
1409 | } | 1414 | } |
1410 | 1415 | ||