On 22.11.2012, at 10:28, Paul Mackerras wrote: > Currently, if the guest does an H_PROTECT hcall requesting that the > permissions on a HPT entry be changed to allow writing, we make the > requested change even if the page is marked read-only in the host > Linux page tables. This is a problem since it would for instance > allow a guest to modify a page that KSM has decided can be shared > between multiple guests. > > To fix this, if the new permissions for the page allow writing, we need > to look up the memslot for the page, work out the host virtual address, > and look up the Linux page tables to get the PTE for the page. If that > PTE is read-only, we reduce the HPTE permissions to read-only. How does KSM handle this usually? If you reduce the permissions to R/O, how do you ever get a R/W page from a deduplicated one? Alex > > Signed-off-by: Paul Mackerras <paulus@xxxxxxxxx> > --- > arch/powerpc/kvm/book3s_hv_rm_mmu.c | 22 ++++++++++++++++++++++ > 1 file changed, 22 insertions(+) > > diff --git a/arch/powerpc/kvm/book3s_hv_rm_mmu.c b/arch/powerpc/kvm/book3s_hv_rm_mmu.c > index 7e1f7e2..19c93ba 100644 > --- a/arch/powerpc/kvm/book3s_hv_rm_mmu.c > +++ b/arch/powerpc/kvm/book3s_hv_rm_mmu.c > @@ -629,6 +629,28 @@ long kvmppc_h_protect(struct kvm_vcpu *vcpu, unsigned long flags, > asm volatile("tlbiel %0" : : "r" (rb)); > asm volatile("ptesync" : : : "memory"); > } > + /* > + * If the host has this page as readonly but the guest > + * wants to make it read/write, reduce the permissions. > + * Checking the host permissions involves finding the > + * memslot and then the Linux PTE for the page. > + */ > + if (hpte_is_writable(r) && kvm->arch.using_mmu_notifiers) { > + unsigned long psize, gfn, hva; > + struct kvm_memory_slot *memslot; > + pgd_t *pgdir = vcpu->arch.pgdir; > + pte_t pte; > + > + psize = hpte_page_size(v, r); > + gfn = ((r & HPTE_R_RPN) & ~(psize - 1)) >> PAGE_SHIFT; > + memslot = __gfn_to_memslot(kvm_memslots(kvm), gfn); > + if (memslot) { > + hva = __gfn_to_hva_memslot(memslot, gfn); > + pte = lookup_linux_pte(pgdir, hva, 1, &psize); > + if (pte_present(pte) && !pte_write(pte)) > + r = hpte_make_readonly(r); > + } > + } > } > hpte[1] = r; > eieio(); > -- > 1.7.10.rc3.219.g53414 > > -- > To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html