public inbox for linuxppc-dev@ozlabs.org 
 help / color / mirror / Atom feed
From: Scott Wood <scottwood@freescale•com>
To: Bhushan Bharat-R65777 <R65777@freescale•com>
Cc: Wood Scott-B07421 <B07421@freescale•com>,
	"kvm@vger•kernel.org" <kvm@vger•kernel.org>,
	Alexander Graf <agraf@suse•de>,
	"kvm-ppc@vger•kernel.org" <kvm-ppc@vger•kernel.org>,
	"linuxppc-dev@lists•ozlabs.org" <linuxppc-dev@lists•ozlabs.org>
Subject: Re: [PATCH 4/4] kvm: powerpc: set cache coherency only for RAM pages
Date: Tue, 30 Jul 2013 13:49:26 -0500	[thread overview]
Message-ID: <1375210166.30721.77@snotra> (raw)
In-Reply-To: <6A3DF150A5B70D4F9B66A25E3F7C888D070EBC3F@039-SN2MPN1-013.039d.mgd.msft.net> (from R65777@freescale.com on Tue Jul 30 11:22:54 2013)

On 07/30/2013 11:22:54 AM, Bhushan Bharat-R65777 wrote:
> diff --git a/arch/powerpc/kvm/e500_mmu_host.c =20
> b/arch/powerpc/kvm/e500_mmu_host.c
> index 5cbdc8f..a48c13f 100644
> --- a/arch/powerpc/kvm/e500_mmu_host.c
> +++ b/arch/powerpc/kvm/e500_mmu_host.c
> @@ -40,6 +40,84 @@
>=20
>  static struct kvmppc_e500_tlb_params host_tlb_params[E500_TLB_NUM];
>=20
> +/*
> + * find_linux_pte returns the address of a linux pte for a given
> + * effective address and directory.  If not found, it returns zero.
> + */
> +static inline pte_t *find_linux_pte(pgd_t *pgdir, unsigned long ea)
> +{
> +        pgd_t *pg;
> +        pud_t *pu;
> +        pmd_t *pm;
> +        pte_t *pt =3D NULL;
> +
> +        pg =3D pgdir + pgd_index(ea);
> +        if (!pgd_none(*pg)) {
> +                pu =3D pud_offset(pg, ea);
> +                if (!pud_none(*pu)) {
> +                        pm =3D pmd_offset(pu, ea);
> +                        if (pmd_present(*pm))
> +                                pt =3D pte_offset_kernel(pm, ea);
> +                }
> +        }
> +        return pt;
> +}

How is this specific to KVM or e500?

> +#ifdef CONFIG_HUGETLB_PAGE
> +pte_t *find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea,
> +                                 unsigned *shift);
> +#else
> +static inline pte_t *find_linux_pte_or_hugepte(pgd_t *pgdir, =20
> unsigned long ea,
> +                                               unsigned *shift)
> +{
> +        if (shift)
> +                *shift =3D 0;
> +        return find_linux_pte(pgdir, ea);
> +}
> +#endif /* !CONFIG_HUGETLB_PAGE */

This is already declared in asm/pgtable.h.  If we need a non-hugepage =20
alternative, that should also go in asm/pgtable.h.

> +/*
> + * Lock and read a linux PTE.  If it's present and writable, =20
> atomically
> + * set dirty and referenced bits and return the PTE, otherwise =20
> return 0.
> + */
> +static inline pte_t kvmppc_read_update_linux_pte(pte_t *p, int =20
> writing)
> +{
> +       pte_t pte =3D pte_val(*p);
> +
> +       if (pte_present(pte)) {
> +               pte =3D pte_mkyoung(pte);
> +               if (writing && pte_write(pte))
> +                       pte =3D pte_mkdirty(pte);
> +       }
> +
> +       *p =3D pte;
> +
> +       return pte;
> +}
> +
> +static pte_t lookup_linux_pte(pgd_t *pgdir, unsigned long hva,
> +                             int writing, unsigned long *pte_sizep)
> +{
> +       pte_t *ptep;
> +       unsigned long ps =3D *pte_sizep;
> +       unsigned int shift;
> +
> +       ptep =3D find_linux_pte_or_hugepte(pgdir, hva, &shift);
> +       if (!ptep)
> +               return __pte(0);
> +       if (shift)
> +               *pte_sizep =3D 1ul << shift;
> +       else
> +               *pte_sizep =3D PAGE_SIZE;
> +
> +       if (ps > *pte_sizep)
> +               return __pte(0);
> +       if (!pte_present(*ptep))
> +               return __pte(0);
> +
> +       return kvmppc_read_update_linux_pte(ptep, writing);
> +}
> +

None of this belongs in this file either.

> @@ -326,8 +405,8 @@ static void kvmppc_e500_setup_stlbe(
>=20
>         /* Force IPROT=3D0 for all guest mappings. */
>         stlbe->mas1 =3D MAS1_TSIZE(tsize) | get_tlb_sts(gtlbe) | =20
> MAS1_VALID;
> -       stlbe->mas2 =3D (gvaddr & MAS2_EPN) |
> -                     e500_shadow_mas2_attrib(gtlbe->mas2, pfn);
> +       stlbe->mas2 =3D (gvaddr & MAS2_EPN) | (ref->flags & =20
> E500_TLB_WIMGE_MASK);
> +//                   e500_shadow_mas2_attrib(gtlbe->mas2, pfn);

MAS2_E and MAS2_G should be safe to come from the guest.

How does this work for TLB1?  One ref corresponds to one guest entry, =20
which may correspond to multiple host entries, potentially each with =20
different WIM settings.

>         stlbe->mas7_3 =3D ((u64)pfn << PAGE_SHIFT) |
>                         e500_shadow_mas3_attrib(gtlbe->mas7_3, pr);
>=20
> @@ -346,6 +425,8 @@ static inline int kvmppc_e500_shadow_map(struct =20
> kvmppc_vcpu_e500 *vcpu_e500,
>         unsigned long hva;
>         int pfnmap =3D 0;
>         int tsize =3D BOOK3E_PAGESZ_4K;
> +       pte_t pte;
> +       int wimg =3D 0;
>=20
>         /*
>          * Translate guest physical to true physical, acquiring
> @@ -451,6 +532,8 @@ static inline int kvmppc_e500_shadow_map(struct =20
> kvmppc_vcpu_e500 *vcpu_e500,
>=20
>         if (likely(!pfnmap)) {
>                 unsigned long tsize_pages =3D 1 << (tsize + 10 - =20
> PAGE_SHIFT);
> +               pgd_t *pgdir;
> +
>                 pfn =3D gfn_to_pfn_memslot(slot, gfn);
>                 if (is_error_noslot_pfn(pfn)) {
>                         printk(KERN_ERR "Couldn't get real page for =20
> gfn %lx!\n",
> @@ -461,9 +544,15 @@ static inline int kvmppc_e500_shadow_map(struct =20
> kvmppc_vcpu_e500 *vcpu_e500,
>                 /* Align guest and physical address to page map =20
> boundaries */
>                 pfn &=3D ~(tsize_pages - 1);
>                 gvaddr &=3D ~((tsize_pages << PAGE_SHIFT) - 1);
> +               pgdir =3D vcpu_e500->vcpu.arch.pgdir;
> +               pte =3D lookup_linux_pte(pgdir, hva, 1, &tsize_pages);
> +               if (pte_present(pte))
> +                       wimg =3D (pte >> PTE_WIMGE_SHIFT) & =20
> MAS2_WIMGE_MASK;
> +               else
> +                       wimg =3D MAS2_I | MAS2_G;

If the PTE is not present, then we can't map it, right?  So why I+G?

-Scott=

  reply	other threads:[~2013-07-30 18:49 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-07-26  5:46 [PATCH 1/4] powerpc: book3e: _PAGE_LENDIAN must be _PAGE_ENDIAN Bharat Bhushan
2013-07-26  5:46 ` [PATCH 2/4] kvm: powerpc: allow guest control "E" attribute in mas2 Bharat Bhushan
2013-07-26  5:46 ` [PATCH 3/4] kvm: powerpc: allow guest control "G" " Bharat Bhushan
2013-07-26  5:46 ` [PATCH 4/4] kvm: powerpc: set cache coherency only for RAM pages Bharat Bhushan
2013-07-26  8:26   ` Benjamin Herrenschmidt
2013-07-26  8:50     ` Alexander Graf
2013-07-26  8:52       ` Bhushan Bharat-R65777
2013-07-26 15:03       ` Bhushan Bharat-R65777
2013-07-26 22:26         ` Benjamin Herrenschmidt
2013-07-30 16:22           ` Bhushan Bharat-R65777
2013-07-30 18:49             ` Scott Wood [this message]
2013-07-31  5:23               ` Bhushan Bharat-R65777
2013-07-26  8:51     ` Bhushan Bharat-R65777

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1375210166.30721.77@snotra \
    --to=scottwood@freescale$(echo .)com \
    --cc=B07421@freescale$(echo .)com \
    --cc=R65777@freescale$(echo .)com \
    --cc=agraf@suse$(echo .)de \
    --cc=kvm-ppc@vger$(echo .)kernel.org \
    --cc=kvm@vger$(echo .)kernel.org \
    --cc=linuxppc-dev@lists$(echo .)ozlabs.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox