diff options
author | Avi Kivity <avi@redhat.com> | 2012-07-26 04:54:21 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2012-07-26 04:54:21 -0400 |
commit | e9bda6f6f902e6b55d9baceb5523468a048cbe56 (patch) | |
tree | bf09cc165da1197cd34967da0593d08b9a37c0f3 /arch/powerpc | |
parent | bdc0077af574800d24318b6945cf2344e8dbb050 (diff) | |
parent | 06e48c510aa37f6e791602e6420422ea7071fe94 (diff) |
Merge branch 'queue' into next
Merge patches queued during the run-up to the merge window.
* queue: (25 commits)
KVM: Choose better candidate for directed yield
KVM: Note down when cpu relax intercepted or pause loop exited
KVM: Add config to support ple or cpu relax optimzation
KVM: switch to symbolic name for irq_states size
KVM: x86: Fix typos in pmu.c
KVM: x86: Fix typos in lapic.c
KVM: x86: Fix typos in cpuid.c
KVM: x86: Fix typos in emulate.c
KVM: x86: Fix typos in x86.c
KVM: SVM: Fix typos
KVM: VMX: Fix typos
KVM: remove the unused parameter of gfn_to_pfn_memslot
KVM: remove is_error_hpa
KVM: make bad_pfn static to kvm_main.c
KVM: using get_fault_pfn to get the fault pfn
KVM: MMU: track the refcount when unmap the page
KVM: x86: remove unnecessary mark_page_dirty
KVM: MMU: Avoid handling same rmap_pde in kvm_handle_hva_range()
KVM: MMU: Push trace_kvm_age_page() into kvm_age_rmapp()
KVM: MMU: Add memslot parameter to hva handlers
...
Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/powerpc')
-rw-r--r-- | arch/powerpc/include/asm/kvm_host.h | 2 | ||||
-rw-r--r-- | arch/powerpc/kvm/book3s_64_mmu_hv.c | 47 | ||||
-rw-r--r-- | arch/powerpc/kvm/e500_tlb.c | 2 |
3 files changed, 40 insertions, 11 deletions
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index 50ea12fd7bf..572ad014126 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h | |||
@@ -52,6 +52,8 @@ | |||
52 | 52 | ||
53 | struct kvm; | 53 | struct kvm; |
54 | extern int kvm_unmap_hva(struct kvm *kvm, unsigned long hva); | 54 | extern int kvm_unmap_hva(struct kvm *kvm, unsigned long hva); |
55 | extern int kvm_unmap_hva_range(struct kvm *kvm, | ||
56 | unsigned long start, unsigned long end); | ||
55 | extern int kvm_age_hva(struct kvm *kvm, unsigned long hva); | 57 | extern int kvm_age_hva(struct kvm *kvm, unsigned long hva); |
56 | extern int kvm_test_age_hva(struct kvm *kvm, unsigned long hva); | 58 | extern int kvm_test_age_hva(struct kvm *kvm, unsigned long hva); |
57 | extern void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte); | 59 | extern void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte); |
diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c index d03eb6f7b05..3c635c0616b 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_hv.c +++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c | |||
@@ -756,9 +756,12 @@ int kvmppc_book3s_hv_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
756 | goto out_put; | 756 | goto out_put; |
757 | } | 757 | } |
758 | 758 | ||
759 | static int kvm_handle_hva(struct kvm *kvm, unsigned long hva, | 759 | static int kvm_handle_hva_range(struct kvm *kvm, |
760 | int (*handler)(struct kvm *kvm, unsigned long *rmapp, | 760 | unsigned long start, |
761 | unsigned long gfn)) | 761 | unsigned long end, |
762 | int (*handler)(struct kvm *kvm, | ||
763 | unsigned long *rmapp, | ||
764 | unsigned long gfn)) | ||
762 | { | 765 | { |
763 | int ret; | 766 | int ret; |
764 | int retval = 0; | 767 | int retval = 0; |
@@ -767,15 +770,25 @@ static int kvm_handle_hva(struct kvm *kvm, unsigned long hva, | |||
767 | 770 | ||
768 | slots = kvm_memslots(kvm); | 771 | slots = kvm_memslots(kvm); |
769 | kvm_for_each_memslot(memslot, slots) { | 772 | kvm_for_each_memslot(memslot, slots) { |
770 | unsigned long start = memslot->userspace_addr; | 773 | unsigned long hva_start, hva_end; |
771 | unsigned long end; | 774 | gfn_t gfn, gfn_end; |
772 | 775 | ||
773 | end = start + (memslot->npages << PAGE_SHIFT); | 776 | hva_start = max(start, memslot->userspace_addr); |
774 | if (hva >= start && hva < end) { | 777 | hva_end = min(end, memslot->userspace_addr + |
775 | gfn_t gfn_offset = (hva - start) >> PAGE_SHIFT; | 778 | (memslot->npages << PAGE_SHIFT)); |
779 | if (hva_start >= hva_end) | ||
780 | continue; | ||
781 | /* | ||
782 | * {gfn(page) | page intersects with [hva_start, hva_end)} = | ||
783 | * {gfn, gfn+1, ..., gfn_end-1}. | ||
784 | */ | ||
785 | gfn = hva_to_gfn_memslot(hva_start, memslot); | ||
786 | gfn_end = hva_to_gfn_memslot(hva_end + PAGE_SIZE - 1, memslot); | ||
787 | |||
788 | for (; gfn < gfn_end; ++gfn) { | ||
789 | gfn_t gfn_offset = gfn - memslot->base_gfn; | ||
776 | 790 | ||
777 | ret = handler(kvm, &memslot->rmap[gfn_offset], | 791 | ret = handler(kvm, &memslot->rmap[gfn_offset], gfn); |
778 | memslot->base_gfn + gfn_offset); | ||
779 | retval |= ret; | 792 | retval |= ret; |
780 | } | 793 | } |
781 | } | 794 | } |
@@ -783,6 +796,13 @@ static int kvm_handle_hva(struct kvm *kvm, unsigned long hva, | |||
783 | return retval; | 796 | return retval; |
784 | } | 797 | } |
785 | 798 | ||
799 | static int kvm_handle_hva(struct kvm *kvm, unsigned long hva, | ||
800 | int (*handler)(struct kvm *kvm, unsigned long *rmapp, | ||
801 | unsigned long gfn)) | ||
802 | { | ||
803 | return kvm_handle_hva_range(kvm, hva, hva + 1, handler); | ||
804 | } | ||
805 | |||
786 | static int kvm_unmap_rmapp(struct kvm *kvm, unsigned long *rmapp, | 806 | static int kvm_unmap_rmapp(struct kvm *kvm, unsigned long *rmapp, |
787 | unsigned long gfn) | 807 | unsigned long gfn) |
788 | { | 808 | { |
@@ -850,6 +870,13 @@ int kvm_unmap_hva(struct kvm *kvm, unsigned long hva) | |||
850 | return 0; | 870 | return 0; |
851 | } | 871 | } |
852 | 872 | ||
873 | int kvm_unmap_hva_range(struct kvm *kvm, unsigned long start, unsigned long end) | ||
874 | { | ||
875 | if (kvm->arch.using_mmu_notifiers) | ||
876 | kvm_handle_hva_range(kvm, start, end, kvm_unmap_rmapp); | ||
877 | return 0; | ||
878 | } | ||
879 | |||
853 | static int kvm_age_rmapp(struct kvm *kvm, unsigned long *rmapp, | 880 | static int kvm_age_rmapp(struct kvm *kvm, unsigned long *rmapp, |
854 | unsigned long gfn) | 881 | unsigned long gfn) |
855 | { | 882 | { |
diff --git a/arch/powerpc/kvm/e500_tlb.c b/arch/powerpc/kvm/e500_tlb.c index c510fc96130..c8f6c582674 100644 --- a/arch/powerpc/kvm/e500_tlb.c +++ b/arch/powerpc/kvm/e500_tlb.c | |||
@@ -520,7 +520,7 @@ static inline void kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500, | |||
520 | 520 | ||
521 | if (likely(!pfnmap)) { | 521 | if (likely(!pfnmap)) { |
522 | unsigned long tsize_pages = 1 << (tsize + 10 - PAGE_SHIFT); | 522 | unsigned long tsize_pages = 1 << (tsize + 10 - PAGE_SHIFT); |
523 | pfn = gfn_to_pfn_memslot(vcpu_e500->vcpu.kvm, slot, gfn); | 523 | pfn = gfn_to_pfn_memslot(slot, gfn); |
524 | if (is_error_pfn(pfn)) { | 524 | if (is_error_pfn(pfn)) { |
525 | printk(KERN_ERR "Couldn't get real page for gfn %lx!\n", | 525 | printk(KERN_ERR "Couldn't get real page for gfn %lx!\n", |
526 | (long)gfn); | 526 | (long)gfn); |