All of lore.kernel.org
 help / color / mirror / Atom feed
From: Julien Grall <julien.grall@linaro.org>
To: Tamas K Lengyel <tklengyel@sec.in.tum.de>, xen-devel@lists.xen.org
Cc: ian.campbell@citrix.com, tim@xen.org, ian.jackson@eu.citrix.com,
	stefano.stabellini@citrix.com, andres@lagarcavilla.org,
	jbeulich@suse.com, dgdegra@tycho.nsa.gov
Subject: Re: [PATCH v5 12/17] xen/arm: Data abort exception (R/W) mem_events.
Date: Thu, 11 Sep 2014 14:19:47 -0700	[thread overview]
Message-ID: <541211F3.4050103@linaro.org> (raw)
In-Reply-To: <1410355726-5599-13-git-send-email-tklengyel@sec.in.tum.de>

Hello Tamas,

You forgot to handle add the permission in the radix when the a table is 
shattered.

On 10/09/14 06:28, Tamas K Lengyel wrote:
>   #define P2M_ONE_DESCEND        0
>   #define P2M_ONE_PROGRESS_NOP   0x1
>   #define P2M_ONE_PROGRESS       0x10
> @@ -504,6 +570,10 @@ static int apply_one_level(struct domain *d,
>               page = alloc_domheap_pages(d, level_shift - PAGE_SHIFT, 0);
>               if ( page )
>               {
> +                rc = p2m_mem_access_radix_set(p2m, paddr_to_pfn(*addr), a);

It's possible to allocate a 2M/1G mapping here. In the case of memaccess 
you only want 4K mapping for granularity.

> +                if ( rc < 0 )

You should free the page via free_domheap_pages if Xen fail to adds the 
access type in the radix tree.

> +                    return rc;
> +
>                   pte = mfn_to_p2m_entry(page_to_mfn(page), mattr, t, a);
>                   if ( level < 3 )
>                       pte.p2m.table = 0;
> @@ -538,6 +608,10 @@ static int apply_one_level(struct domain *d,
>              /* We do not handle replacing an existing table with a superpage */
>                (level == 3 || !p2m_table(orig_pte)) )
>           {
> +            rc = p2m_mem_access_radix_set(p2m, paddr_to_pfn(*addr), a);
> +            if ( rc < 0 )
> +                return rc;
> +

Same remark here about the mapping.

>               /* New mapping is superpage aligned, make it */
>               pte = mfn_to_p2m_entry(*maddr >> PAGE_SHIFT, mattr, t, a);
>               if ( level < 3 )
> @@ -663,6 +737,7 @@ static int apply_one_level(struct domain *d,
>
>           memset(&pte, 0x00, sizeof(pte));
>           p2m_write_pte(entry, pte, flush_cache);
> +        radix_tree_delete(&p2m->mem_access_settings, paddr_to_pfn(*addr));
>
>           *addr += level_size;
>           *maddr += level_size;
> @@ -707,6 +782,53 @@ static int apply_one_level(struct domain *d,
>               *addr += PAGE_SIZE;
>               return P2M_ONE_PROGRESS_NOP;
>           }
> +
> +    case MEMACCESS:
> +        if ( level < 3 )
> +        {
> +            if ( !p2m_valid(orig_pte) )
> +            {
> +                (*addr)++;

Why increment by 1? You the PTE doesn't contain valid mapping you want 
to skip the whole level range. ie:

*addr += level_size;

> +                return P2M_ONE_PROGRESS_NOP;
> +            }
> +
> +            /* Shatter large pages as we descend */
> +            if ( p2m_mapping(orig_pte) )
> +            {
> +                rc = p2m_create_table(d, entry,
> +                                      level_shift - PAGE_SHIFT, flush_cache);
> +                if ( rc < 0 )
> +                    return rc;
> +
> +                p2m->stats.shattered[level]++;
> +                p2m->stats.mappings[level]--;
> +                p2m->stats.mappings[level+1] += LPAE_ENTRIES;
> +            } /* else: an existing table mapping -> descend */
> +

This piece of code is exactly the same in INSERT, REMOVE and now 
MEMACCESS. I would create an helper to shatter and update the stats.

> +            return P2M_ONE_DESCEND;
> +        }
> +        else
> +        {
> +            pte = orig_pte;
> +
> +            if ( !p2m_table(pte) )
> +                pte.bits = 0;
> +
> +            if ( p2m_valid(pte) )
> +            {
> +                ASSERT(pte.p2m.type != p2m_invalid);
> +
> +                rc = p2m_mem_access_radix_set(p2m, paddr_to_pfn(*addr), a);
> +                if ( rc < 0 )
> +                    return rc;
> +
> +                p2m_set_permission(&pte, pte.p2m.type, a);
> +                p2m_write_pte(entry, pte, flush_cache);
> +            }
> +
> +            (*addr)++;

*addr += PAGE_SIZE;

[..]

> +/* Set access type for a region of pfns.
> + * If start_pfn == -1ul, sets the default access type */
> +long p2m_set_mem_access(struct domain *d, unsigned long pfn, uint32_t nr,
> +                        uint32_t start, uint32_t mask, xenmem_access_t access)
> +{
> +    struct p2m_domain *p2m = p2m_get_hostp2m(d);
> +    p2m_access_t a;
> +    long rc = 0;
> +    paddr_t paddr;
> +
> +    static const p2m_access_t memaccess[] = {
> +#define ACCESS(ac) [XENMEM_access_##ac] = p2m_access_##ac
> +        ACCESS(n),
> +        ACCESS(r),
> +        ACCESS(w),
> +        ACCESS(rw),
> +        ACCESS(x),
> +        ACCESS(rx),
> +        ACCESS(wx),
> +        ACCESS(rwx),
> +#undef ACCESS
> +    };
> +
> +    switch ( access )
> +    {
> +    case 0 ... ARRAY_SIZE(memaccess) - 1:
> +        a = memaccess[access];
> +        break;
> +    case XENMEM_access_default:
> +        a = p2m->default_access;
> +        break;
> +    default:
> +        return -EINVAL;
> +    }
> +
> +    /* If request to set default access */
> +    if ( pfn == ~0ul )
> +    {
> +        p2m->default_access = a;
> +        return 0;
> +    }
> +
> +    for ( pfn += start; nr > start; ++pfn )
> +    {
> +        paddr = pfn_to_paddr(pfn);
> +        rc = apply_p2m_changes(d, MEMACCESS, paddr, paddr+1, 0, MATTR_MEM, 0, a);

Hmmm... why didn't you call directly apply_p2m_changes with the whole range?

[..]

> +int p2m_get_mem_access(struct domain *d, unsigned long gpfn,
> +                       xenmem_access_t *access)
> +{
> +    struct p2m_domain *p2m = p2m_get_hostp2m(d);
> +    void *i;
> +    unsigned int index;
> +
> +    static const xenmem_access_t memaccess[] = {
> +#define ACCESS(ac) [XENMEM_access_##ac] = XENMEM_access_##ac
> +            ACCESS(n),
> +            ACCESS(r),
> +            ACCESS(w),
> +            ACCESS(rw),
> +            ACCESS(x),
> +            ACCESS(rx),
> +            ACCESS(wx),
> +            ACCESS(rwx),
> +#undef ACCESS
> +    };
> +
> +    /* If request to get default access */
> +    if ( gpfn == ~0ull )
> +    {
> +        *access = memaccess[p2m->default_access];
> +        return 0;
> +    }
> +
> +    spin_lock(&p2m->lock);
> +
> +    i = radix_tree_lookup(&p2m->mem_access_settings, gpfn);
> +
> +    spin_unlock(&p2m->lock);
> +
> +    if ( !i )
> +        return -ESRCH;

If the gpfn is not in the radix tree, it means that either the mapping 
doesn't exists or the access type is p2m_access_rwx.

You handle the former case but not the latter.

Regards,

-- 
Julien Grall

  reply	other threads:[~2014-09-11 21:19 UTC|newest]

Thread overview: 48+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-09-10 13:28 [PATCH v5 00/17] Mem_event and mem_access for ARM Tamas K Lengyel
2014-09-10 13:28 ` [PATCH v5 01/17] xen: Relocate mem_access and mem_event into common Tamas K Lengyel
2014-09-10 13:28 ` [PATCH v5 02/17] xen: Relocate p2m_mem_access_resume to mem_access common Tamas K Lengyel
2014-09-11 20:16   ` Julien Grall
2014-09-12  8:56     ` Tamas K Lengyel
2014-09-10 13:28 ` [PATCH v5 03/17] xen: Relocate struct npfec definition into common Tamas K Lengyel
2014-09-10 13:28 ` [PATCH v5 04/17] xen: Relocate mem_event_op domctl and access_op memop " Tamas K Lengyel
2014-09-10 13:44   ` Jan Beulich
2014-09-10 13:28 ` [PATCH v5 05/17] xen/mem_event: Clean out superfluous white-spaces Tamas K Lengyel
2014-09-10 13:28 ` [PATCH v5 06/17] xen/mem_event: Relax error condition on debug builds Tamas K Lengyel
2014-09-10 13:28 ` [PATCH v5 07/17] xen/mem_event: Abstract architecture specific sanity checks Tamas K Lengyel
2014-09-10 13:28 ` [PATCH v5 08/17] xen/mem_access: Abstract architecture specific sanity check Tamas K Lengyel
2014-09-10 13:28 ` [PATCH v5 09/17] xen/arm: p2m type definitions and changes Tamas K Lengyel
2014-09-11 20:25   ` Julien Grall
2014-09-12  8:15     ` Tamas K Lengyel
2014-09-12 19:23       ` Julien Grall
2014-09-12 20:25         ` Tamas K Lengyel
2014-09-11 20:49   ` Julien Grall
2014-09-12  8:31     ` Tamas K Lengyel
2014-09-12 19:41       ` Julien Grall
2014-09-12 20:20         ` Tamas K Lengyel
2014-09-10 13:28 ` [PATCH v5 10/17] xen/arm: Add set access required domctl Tamas K Lengyel
2014-09-11 20:26   ` Julien Grall
2014-09-10 13:28 ` [PATCH v5 11/17] xen/arm: Implement domain_get_maximum_gpfn Tamas K Lengyel
2014-09-11 20:28   ` Julien Grall
2014-09-12  8:58     ` Tamas K Lengyel
2014-09-10 13:28 ` [PATCH v5 12/17] xen/arm: Data abort exception (R/W) mem_events Tamas K Lengyel
2014-09-11 21:19   ` Julien Grall [this message]
2014-09-12  8:46     ` Tamas K Lengyel
2014-09-12 20:35       ` Julien Grall
2014-09-12 20:48         ` Tamas K Lengyel
2014-09-12 21:04           ` Julien Grall
2014-09-10 13:28 ` [PATCH v5 13/17] xen/arm: Instruction prefetch abort (X) mem_event handling Tamas K Lengyel
2014-09-11 21:23   ` Julien Grall
2014-09-12  8:34     ` Tamas K Lengyel
2014-09-10 13:28 ` [PATCH v5 14/17] xen/arm: Enable the compilation of mem_access and mem_event on ARM Tamas K Lengyel
2014-09-10 13:28 ` [PATCH v5 15/17] xen: Extend getdomaininfo to return the domain's max_gpfn Tamas K Lengyel
2014-09-10 13:48   ` Jan Beulich
2014-09-10 13:55     ` Tamas K Lengyel
2014-09-10 13:28 ` [PATCH v5 16/17] tools/libxc: Allocate magic page for mem access on ARM Tamas K Lengyel
2014-09-10 13:28 ` [PATCH v5 17/17] tools/tests: Enable xen-access " Tamas K Lengyel
2014-09-11 21:29   ` Julien Grall
2014-09-12  8:50     ` Tamas K Lengyel
2014-09-12  9:01     ` Tamas K Lengyel
2014-09-10 13:51 ` [PATCH v5 00/17] Mem_event and mem_access for ARM Jan Beulich
2014-09-10 14:01   ` Tamas K Lengyel
2014-09-15 22:26     ` Ian Campbell
2014-09-16  8:00       ` Jan Beulich

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=541211F3.4050103@linaro.org \
    --to=julien.grall@linaro.org \
    --cc=andres@lagarcavilla.org \
    --cc=dgdegra@tycho.nsa.gov \
    --cc=ian.campbell@citrix.com \
    --cc=ian.jackson@eu.citrix.com \
    --cc=jbeulich@suse.com \
    --cc=stefano.stabellini@citrix.com \
    --cc=tim@xen.org \
    --cc=tklengyel@sec.in.tum.de \
    --cc=xen-devel@lists.xen.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.