diff options
-rw-r--r-- | drivers/kvm/kvm_main.c | 42 |
1 files changed, 15 insertions, 27 deletions
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c index 70664f020849..1a03b67eb921 100644 --- a/drivers/kvm/kvm_main.c +++ b/drivers/kvm/kvm_main.c | |||
@@ -662,30 +662,24 @@ void kvm_resched(struct kvm_vcpu *vcpu) | |||
662 | } | 662 | } |
663 | EXPORT_SYMBOL_GPL(kvm_resched); | 663 | EXPORT_SYMBOL_GPL(kvm_resched); |
664 | 664 | ||
665 | static struct page *kvm_vcpu_nopage(struct vm_area_struct *vma, | 665 | static int kvm_vcpu_fault(struct vm_area_struct *vma, struct vm_fault *vmf) |
666 | unsigned long address, | ||
667 | int *type) | ||
668 | { | 666 | { |
669 | struct kvm_vcpu *vcpu = vma->vm_file->private_data; | 667 | struct kvm_vcpu *vcpu = vma->vm_file->private_data; |
670 | unsigned long pgoff; | ||
671 | struct page *page; | 668 | struct page *page; |
672 | 669 | ||
673 | pgoff = ((address - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff; | 670 | if (vmf->pgoff == 0) |
674 | if (pgoff == 0) | ||
675 | page = virt_to_page(vcpu->run); | 671 | page = virt_to_page(vcpu->run); |
676 | else if (pgoff == KVM_PIO_PAGE_OFFSET) | 672 | else if (vmf->pgoff == KVM_PIO_PAGE_OFFSET) |
677 | page = virt_to_page(vcpu->pio_data); | 673 | page = virt_to_page(vcpu->pio_data); |
678 | else | 674 | else |
679 | return NOPAGE_SIGBUS; | 675 | return VM_FAULT_SIGBUS; |
680 | get_page(page); | 676 | get_page(page); |
681 | if (type != NULL) | 677 | vmf->page = page; |
682 | *type = VM_FAULT_MINOR; | 678 | return 0; |
683 | |||
684 | return page; | ||
685 | } | 679 | } |
686 | 680 | ||
687 | static struct vm_operations_struct kvm_vcpu_vm_ops = { | 681 | static struct vm_operations_struct kvm_vcpu_vm_ops = { |
688 | .nopage = kvm_vcpu_nopage, | 682 | .fault = kvm_vcpu_fault, |
689 | }; | 683 | }; |
690 | 684 | ||
691 | static int kvm_vcpu_mmap(struct file *file, struct vm_area_struct *vma) | 685 | static int kvm_vcpu_mmap(struct file *file, struct vm_area_struct *vma) |
@@ -976,31 +970,25 @@ out: | |||
976 | return r; | 970 | return r; |
977 | } | 971 | } |
978 | 972 | ||
979 | static struct page *kvm_vm_nopage(struct vm_area_struct *vma, | 973 | static int kvm_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) |
980 | unsigned long address, | ||
981 | int *type) | ||
982 | { | 974 | { |
983 | struct kvm *kvm = vma->vm_file->private_data; | 975 | struct kvm *kvm = vma->vm_file->private_data; |
984 | unsigned long pgoff; | ||
985 | struct page *page; | 976 | struct page *page; |
986 | 977 | ||
987 | pgoff = ((address - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff; | 978 | if (!kvm_is_visible_gfn(kvm, vmf->pgoff)) |
988 | if (!kvm_is_visible_gfn(kvm, pgoff)) | 979 | return VM_FAULT_SIGBUS; |
989 | return NOPAGE_SIGBUS; | ||
990 | /* current->mm->mmap_sem is already held so call lockless version */ | 980 | /* current->mm->mmap_sem is already held so call lockless version */ |
991 | page = __gfn_to_page(kvm, pgoff); | 981 | page = __gfn_to_page(kvm, vmf->pgoff); |
992 | if (is_error_page(page)) { | 982 | if (is_error_page(page)) { |
993 | kvm_release_page_clean(page); | 983 | kvm_release_page_clean(page); |
994 | return NOPAGE_SIGBUS; | 984 | return VM_FAULT_SIGBUS; |
995 | } | 985 | } |
996 | if (type != NULL) | 986 | vmf->page = page; |
997 | *type = VM_FAULT_MINOR; | 987 | return 0; |
998 | |||
999 | return page; | ||
1000 | } | 988 | } |
1001 | 989 | ||
1002 | static struct vm_operations_struct kvm_vm_vm_ops = { | 990 | static struct vm_operations_struct kvm_vm_vm_ops = { |
1003 | .nopage = kvm_vm_nopage, | 991 | .fault = kvm_vm_fault, |
1004 | }; | 992 | }; |
1005 | 993 | ||
1006 | static int kvm_vm_mmap(struct file *file, struct vm_area_struct *vma) | 994 | static int kvm_vm_mmap(struct file *file, struct vm_area_struct *vma) |