Re: [PATCH 4/5] KVM: PPC: Book3S HV: Don't give the guest RW access to RO pages

Alexander Graf
2012-11-23T15:47:45Z

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@samba.org>
> ---
> 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@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html