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 RFC v2 09/12] xen/arm: Data abort exception (R/W) mem_events.
Date: Fri, 29 Aug 2014 17:41:15 -0400 [thread overview]
Message-ID: <5400F37B.9030006@linaro.org> (raw)
In-Reply-To: <1409148400-14810-10-git-send-email-tklengyel@sec.in.tum.de>
Hello Tamas,
I've not yet finished to reviewed entirely this patch but I'm at least
send thoses comments.
On 27/08/14 10:06, Tamas K Lengyel wrote:
> /*
> * Lookup the MFN corresponding to a domain's PFN.
> *
> * There are no processor functions to do a stage 2 only lookup therefore we
> * do a a software walk.
> + *
> + * [IN]: d Domain
> + * [IN]: paddr IPA
> + * [IN]: a (Optional) Update PTE access permission
It's very confusing to update the access permission in p2m_lookup. Why
didn't you add a new function?
Hence, you only update the PTE here and not the radix tree.
[..]
> {
> ASSERT(pte.p2m.type != p2m_invalid);
> maddr = (pte.bits & PADDR_MASK & mask) | (paddr & ~mask);
> + ASSERT(mfn_valid(maddr>>PAGE_SHIFT));
> +
> + if ( a )
> + {
> + p2m_set_permission(&pte, pte.p2m.type, *a);
> +
> + /* Only write the PTE if the access permissions changed */
Does this happen often? I'm wondering if we could always write the pte
no matter if the permission as changed or not.
If it happen often, maybe just checking the access type has changed
would be a good solution?
> + if(pte.p2m.read != pte_loc->p2m.read
Coding style
if ( ... )
> + || pte.p2m.write != pte_loc->p2m.write
> + || pte.p2m.xn != pte_loc->p2m.xn)
> + {
> + p2m_write_pte(pte_loc, pte, 1);
> + }
> + }
> +
> *t = pte.p2m.type;
> }
>
> @@ -208,8 +308,6 @@ done:
> if (first) unmap_domain_page(first);
>
> err:
> - spin_unlock(&p2m->lock);
> -
> return maddr;
> }
>
> @@ -228,7 +326,7 @@ int p2m_pod_decrease_reservation(struct domain *d,
> }
>
> static lpae_t mfn_to_p2m_entry(unsigned long mfn, unsigned int mattr,
> - p2m_type_t t)
> + p2m_type_t t, p2m_access_t a)
> {
> paddr_t pa = ((paddr_t) mfn) << PAGE_SHIFT;
> /* sh, xn and write bit will be defined in the following switches
> @@ -258,37 +356,7 @@ static lpae_t mfn_to_p2m_entry(unsigned long mfn, unsigned int mattr,
> break;
> }
>
> - switch (t)
> - {
> - case p2m_ram_rw:
> - e.p2m.xn = 0;
> - e.p2m.write = 1;
> - break;
> -
> - case p2m_ram_ro:
> - e.p2m.xn = 0;
> - e.p2m.write = 0;
> - break;
> -
> - case p2m_iommu_map_rw:
> - case p2m_map_foreign:
> - case p2m_grant_map_rw:
> - case p2m_mmio_direct:
> - e.p2m.xn = 1;
> - e.p2m.write = 1;
> - break;
> -
> - case p2m_iommu_map_ro:
> - case p2m_grant_map_ro:
> - case p2m_invalid:
> - e.p2m.xn = 1;
> - e.p2m.write = 0;
> - break;
> -
> - case p2m_max_real_type:
> - BUG();
> - break;
> - }
> + p2m_set_permission(&e, t, a);
>
> ASSERT(!(pa & ~PAGE_MASK));
> ASSERT(!(pa & ~PADDR_MASK));
> @@ -298,13 +366,6 @@ static lpae_t mfn_to_p2m_entry(unsigned long mfn, unsigned int mattr,
> return e;
> }
>
> -static inline void p2m_write_pte(lpae_t *p, lpae_t pte, bool_t flush_cache)
> -{
> - write_pte(p, pte);
> - if ( flush_cache )
> - clean_xen_dcache(*p);
> -}
> -
> /*
> * Allocate a new page table page and hook it in via the given entry.
> * apply_one_level relies on this returning 0 on success
> @@ -346,7 +407,7 @@ static int p2m_create_table(struct domain *d, lpae_t *entry,
> for ( i=0 ; i < LPAE_ENTRIES; i++ )
> {
> pte = mfn_to_p2m_entry(base_pfn + (i<<(level_shift-LPAE_SHIFT)),
> - MATTR_MEM, t);
> + MATTR_MEM, t, p2m->default_access);
>
> /*
> * First and second level super pages set p2m.table = 0, but
> @@ -366,7 +427,7 @@ static int p2m_create_table(struct domain *d, lpae_t *entry,
>
> unmap_domain_page(p);
>
> - pte = mfn_to_p2m_entry(page_to_mfn(page), MATTR_MEM, p2m_invalid);
> + pte = mfn_to_p2m_entry(page_to_mfn(page), MATTR_MEM, p2m_invalid, p2m->default_access);
>
> p2m_write_pte(entry, pte, flush_cache);
>
> @@ -498,7 +559,7 @@ static int apply_one_level(struct domain *d,
> page = alloc_domheap_pages(d, level_shift - PAGE_SHIFT, 0);
> if ( page )
> {
> - pte = mfn_to_p2m_entry(page_to_mfn(page), mattr, t);
> + pte = mfn_to_p2m_entry(page_to_mfn(page), mattr, t, a);
> if ( level < 3 )
> pte.p2m.table = 0;
> p2m_write_pte(entry, pte, flush_cache);
> @@ -533,7 +594,7 @@ static int apply_one_level(struct domain *d,
> (level == 3 || !p2m_table(orig_pte)) )
> {
> /* New mapping is superpage aligned, make it */
> - pte = mfn_to_p2m_entry(*maddr >> PAGE_SHIFT, mattr, t);
> + pte = mfn_to_p2m_entry(*maddr >> PAGE_SHIFT, mattr, t, a);
> if ( level < 3 )
> pte.p2m.table = 0; /* Superpage entry */
>
> @@ -640,6 +701,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;
>
> @@ -1048,7 +1110,10 @@ int p2m_cache_flush(struct domain *d, xen_pfn_t start_mfn, xen_pfn_t end_mfn)
>
> unsigned long gmfn_to_mfn(struct domain *d, unsigned long gpfn)
> {
> - paddr_t p = p2m_lookup(d, pfn_to_paddr(gpfn), NULL);
> + paddr_t p;
Missing blank line after the declaration block.
> + spin_lock(&d->arch.p2m.lock);
> + p = p2m_lookup(d, pfn_to_paddr(gpfn), NULL, NULL);
> + spin_unlock(&d->arch.p2m.lock);
> return p >> PAGE_SHIFT;
> }
>
> @@ -1080,6 +1145,241 @@ err:
> return page;
> }
>
> +int p2m_mem_access_check(paddr_t gpa, vaddr_t gla,
> + bool_t access_r, bool_t access_w, bool_t access_x,
> + bool_t ptw)
The 2 arguments lines should be aligned to p. IOW, you need to remove
one space on the both lines.
Also, as the function return always 0 or 1 I would use a bool_t for the
return value.
> +{
> + struct vcpu *v = current;
> + mem_event_request_t *req = NULL;
> + xenmem_access_t xma;
> + bool_t violation;
> + int rc;
> +
> + /* If we have no listener, nothing to do */
> + if( !mem_event_check_ring( &v->domain->mem_event->access ) )
The spaces in the inner () are not necessary.
Also, don't you miss to check p2m->access_required?
> + {
> + return 1;
> + }
> +
> + rc = p2m_get_mem_access(v->domain, paddr_to_pfn(gpa), &xma);
> + if ( rc )
> + return rc;
> +
> + switch (xma)
switch ( ... )
> + {
> + default:
It looks like all the possible case of the enum has been defined below.
Why do you define default as XENMEM_access_n?
> + case XENMEM_access_n:
The "case" is usually aligned to "{". Such as
{
case ...:
> + violation = access_r || access_w || access_x;
Silly question, where doess access_* comes from? I can't find any
definition with CTAGS.
[..]
> + if (!violation)
if ( ... )
> + return 1;
> +
> + req = xzalloc(mem_event_request_t);
> + if ( req )
> + {
> + req->reason = MEM_EVENT_REASON_VIOLATION;
> + req->flags |= MEM_EVENT_FLAG_VCPU_PAUSED;
> + req->gfn = gpa >> PAGE_SHIFT;
> + req->offset = gpa & ((1 << PAGE_SHIFT) - 1);
> + req->gla = gla;
> + req->gla_valid = 1;
> + req->access_r = access_r;
> + req->access_w = access_w;
> + req->access_x = access_x;
> + req->vcpu_id = v->vcpu_id;
> +
> + mem_event_vcpu_pause(v);
> + mem_access_send_req(v->domain, req);
> +
> + xfree(req);
> +
> + return 0;
> + }
Ignoring the access when Xen fails to allocate req sounds strange.
Shouldn't you at least print a warning?
> +
> + return 1;
> +}
[..]
> +int p2m_get_mem_access(struct domain *d, unsigned long gpfn,
> + xenmem_access_t *access)
> +{
[..]
> + if ( (unsigned) index >= ARRAY_SIZE(memaccess) )
> + return -ERANGE;
> +
> + *access = memaccess[ (unsigned) index];
Spurious space at after [ ?
Regards,
--
Julien Grall
next prev parent reply other threads:[~2014-08-29 21:41 UTC|newest]
Thread overview: 48+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-08-27 14:06 [PATCH RFC v2 00/12] Mem_event and mem_access for ARM Tamas K Lengyel
2014-08-27 14:06 ` [PATCH RFC v2 01/12] xen: Relocate mem_access and mem_event into common Tamas K Lengyel
2014-08-27 14:17 ` Julien Grall
2014-08-27 14:57 ` Tamas K Lengyel
2014-08-28 10:22 ` Tim Deegan
2014-08-27 14:06 ` [PATCH RFC v2 02/12] xen/mem_event: Clean out superflous white-spaces Tamas K Lengyel
2014-08-28 10:22 ` Tim Deegan
2014-08-27 14:06 ` [PATCH RFC v2 03/12] xen/mem_event: Relax error condition on debug builds Tamas K Lengyel
2014-08-27 16:39 ` Julien Grall
2014-08-27 17:00 ` Tamas K Lengyel
2014-08-27 17:02 ` Andres Lagar Cavilla
2014-08-27 21:26 ` Tamas K Lengyel
2014-08-28 6:36 ` Jan Beulich
2014-08-29 4:20 ` Andres Lagar Cavilla
2014-08-27 14:06 ` [PATCH RFC v2 04/12] xen/mem_event: Abstract architecture specific sanity checks Tamas K Lengyel
2014-08-27 15:19 ` Jan Beulich
2014-08-27 17:17 ` Tamas K Lengyel
2014-08-27 21:54 ` Tamas K Lengyel
2014-08-28 6:38 ` Jan Beulich
2014-08-28 8:40 ` Tamas K Lengyel
2014-08-28 8:46 ` Jan Beulich
2014-08-28 8:52 ` Tamas K Lengyel
2014-08-27 14:06 ` [PATCH RFC v2 05/12] xen/mem_access: Abstract architecture specific sanity check Tamas K Lengyel
2014-08-27 14:06 ` [PATCH RFC v2 06/12] tools/libxc: Allocate magic page for mem access on ARM Tamas K Lengyel
2014-08-29 20:43 ` Julien Grall
2014-09-04 0:12 ` Stefano Stabellini
2014-08-27 14:06 ` [PATCH RFC v2 07/12] xen/arm: p2m type definitions and changes Tamas K Lengyel
2014-08-27 14:06 ` [PATCH RFC v2 08/12] xen/arm: Add mem_event domctl and mem_access memop Tamas K Lengyel
2014-08-29 20:57 ` Julien Grall
2014-08-30 8:19 ` Tamas K Lengyel
2014-08-27 14:06 ` [PATCH RFC v2 09/12] xen/arm: Data abort exception (R/W) mem_events Tamas K Lengyel
2014-08-27 17:01 ` Julien Grall
2014-08-27 17:22 ` Tamas K Lengyel
2014-08-29 21:41 ` Julien Grall [this message]
2014-08-30 8:16 ` Tamas K Lengyel
2014-08-27 14:06 ` [PATCH RFC v2 10/12] xen/arm: Instruction prefetch abort (X) mem_event handling Tamas K Lengyel
2014-08-27 14:06 ` [PATCH RFC v2 11/12] xen/arm: Enable the compilation of mem_access and mem_event on ARM Tamas K Lengyel
2014-08-27 15:24 ` Jan Beulich
2014-08-27 17:12 ` Tamas K Lengyel
2014-08-28 6:39 ` Jan Beulich
2014-08-28 8:42 ` Tamas K Lengyel
2014-08-28 8:54 ` Jan Beulich
2014-08-28 9:00 ` Tamas K Lengyel
2014-08-27 17:05 ` Daniel De Graaf
2014-08-27 17:13 ` Tamas K Lengyel
2014-08-27 14:06 ` [PATCH RFC v2 12/12] tools/tests: Enable xen-access " Tamas K Lengyel
2014-08-27 15:46 ` [PATCH RFC v2 00/12] Mem_event and mem_access for ARM Andrii Tseglytskyi
2014-08-27 17:05 ` Tamas K Lengyel
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=5400F37B.9030006@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).