aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kvm/book3s_64_mmu_hv.c
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2011-12-12 07:28:55 -0500
committerAvi Kivity <avi@redhat.com>2012-03-05 07:52:36 -0500
commit93e602490c1da83162a8b6ba86b4b48a7a0f0c9e (patch)
tree7dd0407af03944cffcfdb7798d0ea6155156700e /arch/powerpc/kvm/book3s_64_mmu_hv.c
parentb2b2f16508de10bb1863bdd4ec1fa212111df5b4 (diff)
KVM: PPC: Add an interface for pinning guest pages in Book3s HV guests
This adds two new functions, kvmppc_pin_guest_page() and kvmppc_unpin_guest_page(), and uses them to pin the guest pages where the guest has registered areas of memory for the hypervisor to update, (i.e. the per-cpu virtual processor areas, SLB shadow buffers and dispatch trace logs) and then unpin them when they are no longer required. Although it is not strictly necessary to pin the pages at this point, since all guest pages are already pinned, later commits in this series will mean that guest pages aren't all pinned. Signed-off-by: Paul Mackerras <paulus@samba.org> Signed-off-by: Alexander Graf <agraf@suse.de> Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/powerpc/kvm/book3s_64_mmu_hv.c')
-rw-r--r--arch/powerpc/kvm/book3s_64_mmu_hv.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c
index e4c60698f41a..dcd39dc64f07 100644
--- a/arch/powerpc/kvm/book3s_64_mmu_hv.c
+++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c
@@ -184,6 +184,44 @@ static int kvmppc_mmu_book3s_64_hv_xlate(struct kvm_vcpu *vcpu, gva_t eaddr,
184 return -ENOENT; 184 return -ENOENT;
185} 185}
186 186
187void *kvmppc_pin_guest_page(struct kvm *kvm, unsigned long gpa,
188 unsigned long *nb_ret)
189{
190 struct kvm_memory_slot *memslot;
191 unsigned long gfn = gpa >> PAGE_SHIFT;
192 struct page *page;
193 unsigned long offset;
194 unsigned long pfn, pa;
195 unsigned long *physp;
196
197 memslot = gfn_to_memslot(kvm, gfn);
198 if (!memslot || (memslot->flags & KVM_MEMSLOT_INVALID))
199 return NULL;
200 physp = kvm->arch.slot_phys[memslot->id];
201 if (!physp)
202 return NULL;
203 physp += (gfn - memslot->base_gfn) >>
204 (kvm->arch.ram_porder - PAGE_SHIFT);
205 pa = *physp;
206 if (!pa)
207 return NULL;
208 pfn = pa >> PAGE_SHIFT;
209 page = pfn_to_page(pfn);
210 get_page(page);
211 offset = gpa & (kvm->arch.ram_psize - 1);
212 if (nb_ret)
213 *nb_ret = kvm->arch.ram_psize - offset;
214 return page_address(page) + offset;
215}
216
217void kvmppc_unpin_guest_page(struct kvm *kvm, void *va)
218{
219 struct page *page = virt_to_page(va);
220
221 page = compound_head(page);
222 put_page(page);
223}
224
187void kvmppc_mmu_book3s_hv_init(struct kvm_vcpu *vcpu) 225void kvmppc_mmu_book3s_hv_init(struct kvm_vcpu *vcpu)
188{ 226{
189 struct kvmppc_mmu *mmu = &vcpu->arch.mmu; 227 struct kvmppc_mmu *mmu = &vcpu->arch.mmu;