diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/kvm/kvm_main.c | 25 |
1 files changed, 17 insertions, 8 deletions
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c index dfb65e2f87ee..04544aecf22f 100644 --- a/drivers/kvm/kvm_main.c +++ b/drivers/kvm/kvm_main.c | |||
@@ -559,28 +559,37 @@ int kvm_is_visible_gfn(struct kvm *kvm, gfn_t gfn) | |||
559 | } | 559 | } |
560 | EXPORT_SYMBOL_GPL(kvm_is_visible_gfn); | 560 | EXPORT_SYMBOL_GPL(kvm_is_visible_gfn); |
561 | 561 | ||
562 | static unsigned long gfn_to_hva(struct kvm *kvm, gfn_t gfn) | ||
563 | { | ||
564 | struct kvm_memory_slot *slot; | ||
565 | |||
566 | gfn = unalias_gfn(kvm, gfn); | ||
567 | slot = __gfn_to_memslot(kvm, gfn); | ||
568 | if (!slot) | ||
569 | return bad_hva(); | ||
570 | return (slot->userspace_addr + (gfn - slot->base_gfn) * PAGE_SIZE); | ||
571 | } | ||
572 | |||
562 | /* | 573 | /* |
563 | * Requires current->mm->mmap_sem to be held | 574 | * Requires current->mm->mmap_sem to be held |
564 | */ | 575 | */ |
565 | static struct page *__gfn_to_page(struct kvm *kvm, gfn_t gfn) | 576 | static struct page *__gfn_to_page(struct kvm *kvm, gfn_t gfn) |
566 | { | 577 | { |
567 | struct kvm_memory_slot *slot; | ||
568 | struct page *page[1]; | 578 | struct page *page[1]; |
579 | unsigned long addr; | ||
569 | int npages; | 580 | int npages; |
570 | 581 | ||
571 | might_sleep(); | 582 | might_sleep(); |
572 | 583 | ||
573 | gfn = unalias_gfn(kvm, gfn); | 584 | addr = gfn_to_hva(kvm, gfn); |
574 | slot = __gfn_to_memslot(kvm, gfn); | 585 | if (kvm_is_error_hva(addr)) { |
575 | if (!slot) { | ||
576 | get_page(bad_page); | 586 | get_page(bad_page); |
577 | return bad_page; | 587 | return bad_page; |
578 | } | 588 | } |
579 | 589 | ||
580 | npages = get_user_pages(current, current->mm, | 590 | npages = get_user_pages(current, current->mm, addr, 1, 1, 1, page, |
581 | slot->userspace_addr | 591 | NULL); |
582 | + (gfn - slot->base_gfn) * PAGE_SIZE, 1, | 592 | |
583 | 1, 1, page, NULL); | ||
584 | if (npages != 1) { | 593 | if (npages != 1) { |
585 | get_page(bad_page); | 594 | get_page(bad_page); |
586 | return bad_page; | 595 | return bad_page; |