aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/kvm/book3s_hv_rm_mmu.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/arch/powerpc/kvm/book3s_hv_rm_mmu.c b/arch/powerpc/kvm/book3s_hv_rm_mmu.c
index fc3da3208fda..7a57ea49172d 100644
--- a/arch/powerpc/kvm/book3s_hv_rm_mmu.c
+++ b/arch/powerpc/kvm/book3s_hv_rm_mmu.c
@@ -600,6 +600,28 @@ long kvmppc_h_protect(struct kvm_vcpu *vcpu, unsigned long flags,
600 asm volatile("tlbiel %0" : : "r" (rb)); 600 asm volatile("tlbiel %0" : : "r" (rb));
601 asm volatile("ptesync" : : : "memory"); 601 asm volatile("ptesync" : : : "memory");
602 } 602 }
603 /*
604 * If the host has this page as readonly but the guest
605 * wants to make it read/write, reduce the permissions.
606 * Checking the host permissions involves finding the
607 * memslot and then the Linux PTE for the page.
608 */
609 if (hpte_is_writable(r) && kvm->arch.using_mmu_notifiers) {
610 unsigned long psize, gfn, hva;
611 struct kvm_memory_slot *memslot;
612 pgd_t *pgdir = vcpu->arch.pgdir;
613 pte_t pte;
614
615 psize = hpte_page_size(v, r);
616 gfn = ((r & HPTE_R_RPN) & ~(psize - 1)) >> PAGE_SHIFT;
617 memslot = __gfn_to_memslot(kvm_memslots(kvm), gfn);
618 if (memslot) {
619 hva = __gfn_to_hva_memslot(memslot, gfn);
620 pte = lookup_linux_pte(pgdir, hva, 1, &psize);
621 if (pte_present(pte) && !pte_write(pte))
622 r = hpte_make_readonly(r);
623 }
624 }
603 } 625 }
604 hpte[1] = r; 626 hpte[1] = r;
605 eieio(); 627 eieio();